深度图像(Depth Images)也被称为距离图像(Range Image)
,是指将从图像采集器到场景中各点的距离值作为像素值的图像,它直接反应了景物可见表面的几何形状,利用它可以很方便的解决3D目标描述中的许多问题,深度图像经过点云变换可以计算为点云数据,点云数据可以反算为深度图像数据
。
不同视角获得深度图像的过程如下:
创建深度图像的语句为:
//xy的角分辨率一致
template <typename PointCloudType> void
RangeImage::createFromPointCloud (const PointCloudType& point_cloud, float angular_resolution,
float max_angle_width, float max_angle_height,
const Eigen::Affine3f& sensor_pose, RangeImage::CoordinateFrame coordinate_frame,
float noise_level, float min_range, int border_size)
{
createFromPointCloud (point_cloud, angular_resolution, angular_resolution, max_angle_width, max_angle_height,
sensor_pose, coordinate_frame, noise_level, min_range, border_size);
}
//xy的角分辨率不一致
template <typename PointCloudType> void
RangeImage::createFromPointCloud (const PointCloudType& point_cloud,
float angular_resolution_x, float angular_resolution_y,
float max_angle_width, float max_angle_height,
const Eigen::Affine3f& sensor_pose, RangeImage::CoordinateFrame coordinate_frame,
float noise_level, float min_range, int border_size)
函数说明如下:
- pointCloud:被检测点云
- angular_resolution_x:x角度的分辨率
- angular_resolution_y:y角度的分辨率
- angularResolution=1:邻近的像素点所对应的每个光束之间相差 1°,如果设置这个,说明水平和垂直的角度分辨率是一样的。
- maxAngleWidth=360:
水平视角
- maxAngleHeight=180:
垂直视角
- sensorPose: 定义了模拟深度图像获取传感器的6DOF(6自由度)位置,其原始值为横滚角roll、俯仰角 pitch、偏航角 yaw 都为 0
- coordinate_frame: 设置为
CAMERA_FRAM
E说明系统的X轴是向右的、Y轴是向下的、Z轴是向前的。如果参数值是LASER_FRAME
,其X轴向前、Y轴向左、Z轴向上。- noiseLevel=0: 是指使用一个归一化的 Z缓存区来创建深度图像,如果想让邻近点集都落在同一个像素单元,可以设置一个较高的值,例如 noiseLevel = 0.05 可以理解为深度距离值是通过查询点半径为 5cm 的圆内包含的点用来平均计算而得到的 。
- minRange=0:如果设置>0则所有模拟器所在位置半径 minRange 内的邻近点都将被忽略,即为盲区。
- borderSize=1:如果设置>0 ,在裁剪图像时,将在图像周围留下当前视点不可见点的边界 。
#include
#include
#include
#include
int main(int argc, char **argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ> &pointCloud = *pointCloudPtr;
pcl::PCDReader reader;
//reader.read("../../pcd/table_scene_lms400.pcd", *pointCloudPtr); //读取pcd点云
reader.read<pcl::PointXYZ>("../../pcd/rabbit.pcd", *pointCloudPtr); //读取pcd点云
// We now want to create a range image from the above point cloud, with a 1deg angular resolution
//创建深度图像
float angularResolution = (float)(1.0f * (M_PI / 180.0f)); // 1.0 degree in radians
float maxAngleWidth = (float)(180.0f * (M_PI / 180.0f)); //水平视角
float maxAngleHeight = (float)(60.0f * (M_PI / 180.0f)); //垂直视角
Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
float noiseLevel = 0.00;
float minRange = 0.0f;
int borderSize = 1;
boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
pcl::RangeImage &rangeImage = *range_image_ptr;
rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
std::cout << rangeImage << std::endl;
//可视化深度图像
pcl::visualization::PCLVisualizer viewer("range image viewer"); //创建一个3D可视化界面
viewer.setBackgroundColor(1, 1, 1); //设置视窗背景颜色rgb111
// 添加深度图点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 0, 0, 0);
viewer.addPointCloud(range_image_ptr, range_image_color_handler, "range image");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "range image");
// 添加原始点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> org_image_color_handler(pointCloudPtr, 255, 100, 0);
viewer.addPointCloud(pointCloudPtr, org_image_color_handler, "orginal image");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "orginal image");
viewer.initCameraParameters();
viewer.addCoordinateSystem(1.0);
while (!viewer.wasStopped())
{
viewer.spinOnce();
pcl_sleep(0.01);
}
return 0;
}
输出结果如下,可以看到height已经不为1了,说明它是一个有序的图像点云。
header:
seq: 0 stamp: 0 frame_id:
points[]: 17738
width: 362
height: 49
sensor_origin_: 0 0 0
sensor_orientation_: 0 0 0 1
is_dense: 0
angular resolution: 1deg/pixel in x and 1deg/pixel in y.
可视化结果如下图所示,正如设定的参数一样,水平视角范围为180度,垂直视角为60度。
参考:
https://pcl.readthedocs.io/projects/tutorials/en/latest/range_image_creation.html#range-image-creation
https://pcl.readthedocs.io/projects/tutorials/en/latest/range_image_visualization.html#range-image-visualization
https://pointclouds.org/documentation/classpcl_1_1_range_image.html