1.原理介绍
深度图像也叫高度图像,距离图像,由传感器采集场景的距离作为图像像素值,是一种3D图像格式,有些情况下,需要把3D点云转成深度图来处理,转换原理本质上是坐标系的变换。
2.PCL实现
PCL中实现3D点云到深度图转换的代码如下:
#pragma warning(disable:4996)
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/common/common_headers.h>
#include <pcl/range_image/range_image.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/io/png_io.h>
#include <pcl/visualization/common/float_image_utils.h>
typedef pcl::PointXYZ PointType;
int main(int argc, char** argv)
{
pcl::PointCloud<PointType>::Ptr cloud(new pcl::PointCloud<PointType>);
Eigen::Affine3f scene_sensor_pose(Eigen::Affine3f::Identity());
pcl::io::loadPCDFile("Armadillo.pcd", *cloud);
float angularResolution = pcl::deg2rad(1.0f);
float maxAngleWidth = pcl::deg2rad(360.0f);
float maxAngleHeight = pcl::deg2rad(360.0f);
Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::LASER_FRAME;
float noiseLevel = 0.00;
float minRange = 0.0f;
int borderSize = 1;
pcl::RangeImage::Ptr range_image_ptr(new pcl::RangeImage);
pcl::RangeImage& range_image = *range_image_ptr;
range_image.createFromPointCloud(*cloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
float* ranges = range_image.getRangesArray();
unsigned char* rgb_image = pcl::visualization::FloatImageUtils::getVisualImage(ranges, range_image.width, range_image.height);
pcl::io::saveRgbPNGFile("RangeImage.png", rgb_image, range_image.width, range_image.height);
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("PointCloud Viewer"));
viewer1->setBackgroundColor(0, 0, 0);
viewer1->addPointCloud(cloud, "point cloud");
viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 1, "point cloud");
viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "point cloud");
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(range_image_ptr, "z");
viewer->addPointCloud(range_image_ptr, range_image_color_handler, "range image");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "range image");
viewer->initCameraParameters();
pcl::visualization::RangeImageVisualizer range_image_widget("Range image");
range_image_widget.setWindowTitle("RangeImage");
range_image_widget.showRangeImage(range_image);
range_image_widget.setSize(800, 600);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
system("pause");
return 0;
}
3.结果展示
生成的深度图有点小