从点云创建深度图并显示
函数原型
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)
参数说明:
- point_cloud:创建深度图像所需要的点云的引用
- angular_resolution:角分辨率,以弧度表示。它表示在水平和垂直方向上每个像素点之间的角度差。
- max_angle_width:进行模拟的距离传感器对周围的环境拥有一个完整的360°视角,无论任何数据集都推荐使用此设置,因为最终获取的深度图像将被裁剪到有空间物体存在的区域范围。
- max_angle_height:当传感器后面没有可以观测的点时,设置一个水平视角为180°的激光扫描仪即可,因为需要观察距离传感器前面就可以了。
- sensor_pose:定义了模拟深度图像获取传感器的6DOF(6自由度)位置,其原始值为横滚角roll、俯仰角 pitch、偏航角 yaw 都为 0
- coordinate_frame:设置为
CAMERA_FRAM
E说明系统的X轴是向右的、Y轴是向下的、Z轴是向前的。如果参数值是LASER_FRAME
,其X轴向前、Y轴向左、Z轴向上。 - noise_level:获取深度图像深度时,近邻点对查询点距离值的影响水平。例如 noiseLevel = 0.05 可以理解为深度距离值是通过查询点半径为 5cm 的圆内包含的点用来平均计算得到的 。
- min_range:设置最小的获取距离,小于最小获取距离的位置为传感器的盲区。
- border_size:获得深度图像的边缘的宽度 默认为0;如果设置>0 ,在裁剪图像时,将在图像周围留下当前视点不可见点的边界 。
创建 矩形点云
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/range_image_visualizer.h>
int main(int argc, char** argv) {
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>& pointCloud = *pointCloudPtr;
// 创建一个矩形形状的点云
// Generate the data
for (float y = -0.5f; y <= 0.5f; y += 0.01f) {
for (float z = -0.5f; z <= 0.5f; z += 0.01f) {
pcl::PointXYZ point;
point.x = 2.0f - y;
point.y = y;
point.z = z;
pointCloud.points.push_back(point);
}
}
pointCloud.width = (uint32_t)pointCloud.points.size();
pointCloud.height = 1;
// We now want to create a range image from the above point cloud, with a 1deg angular resolution
// 根据之前得到的点云图,通过1deg的分辨率生成深度图。
float angularResolution = (float)(1.0f * (M_PI / 180.0f));// 弧度1°
float maxAngleWidth = (float)(360.0f * (M_PI / 180.0f)); // 弧度360°
float maxAngleHeight = (float)(180.0f * (M_PI / 180.0f)); // 弧度180°
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;
pcl::RangeImage::Ptr rangeImage_ptr(new pcl::RangeImage);
pcl::RangeImage& rangeImage = *rangeImage_ptr;
rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
std::cout << rangeImage << "\n";
// 添加原始点云
pcl::visualization::PCLVisualizer viewer("3D Viewer");
viewer.setBackgroundColor(1, 1, 1);
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);
// 添加深度图点云
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("RangeImage Viewer"));
viewer1->setBackgroundColor(0, 0, 0); //设置背景颜色为黑色
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointWithRange> range_image_color_handler(rangeImage_ptr, "z");
viewer1->addPointCloud(rangeImage_ptr, range_image_color_handler, "range image");
viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "range image");
viewer1->initCameraParameters();
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return (0);
}
运行效果:
Explanation :
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>& pointCloud = *pointCloudPtr;
这段代码创建了一个指向pcl::PointCloudpcl::PointXYZ类型的指针pointCloudPtr,并通过关键字new实例化了一个新的PointCloud对象。然后,通过将指针解引用并赋值给pointCloud变量,将其引用指向了pointCloudPtr所指向的PointCloud对象。
pcl::RangeImage::Ptr rangeImage_ptr(new pcl::RangeImage);
pcl::RangeImage& rangeImage = *rangeImage_ptr;
这段代码创建了一个指向pcl::RangeImage类型的指针rangeImage_ptr,并通过关键字new实例化了一个新的RangeImage对象。然后,通过将指针解引用并赋值给rangeImage变量,将其引用指向了rangeImage_ptr所指向的RangeImage对象。
viewer.initCameraParameters();
通过调用viewer.initCameraParameters()方法,初始化了相机参数,即设置了默认相机姿态和投影参数,以便在可视化中正确显示点云或三维对象。
加载已有的点云数据
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/png_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/range_image/range_image.h>
#include <pcl/visualization/common/float_image_utils.h>//保存深度图像
#include <pcl/visualization/range_image_visualizer.h> //深度图像可视化
#include <pcl/visualization/pcl_visualizer.h>//点云可视化
int main(int argc, char** argv) {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 从PCD文件中加载点云数据
if (pcl::io::loadPCDFile<pcl::PointXYZ>("../data/DKdata2.pcd", *cloud) == -1) {
PCL_ERROR("无法读取 PCD 文件!\n");
return -1;
}
// 创建深度图参数
float angularResolution = (float)(1.0f * (M_PI / 180.0f)); // 1.0 degree in radians
float maxAngleWidth = (float)(360.0f * (M_PI / 180.0f)); // 360.0 degree in radians
float maxAngleHeight = (float)(180.0f * (M_PI / 180.0f)); // 180.0 degree in radians
Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(135.75f, -99.18f, 52.64f);
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
float noiseLevel = 0.00;
float minRange = 0.0f;
int borderSize = 1;
pcl::RangeImage::Ptr rangeImage_ptr(new pcl::RangeImage);
pcl::RangeImage& rangeImage = *rangeImage_ptr;
//pcl::RangeImage rangeImage;
rangeImage.createFromPointCloud(*cloud, angularResolution, maxAngleWidth, maxAngleHeight,
sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("RangeImage Viewer"));
viewer->setBackgroundColor(0, 0, 0); //设置背景颜色为黑色
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointWithRange> range_image_color_handler(rangeImage_ptr, "z");
viewer->addPointCloud(rangeImage_ptr, range_image_color_handler, "range image");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "range image");
viewer->initCameraParameters();
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
return 0;
}
运行效果:
参考:点云转深度图:转换,保存,可视化