本文主要是介绍PCL——点云到深度图的变换与曲面重建,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
点云到深度图的变换与曲面重建
点云数据需要通过k-d tree等索引来对数据进行检索;
深度图和图像类似,可以通过上下左右等近邻来直接进行索引。
所以有必要将点云数据转换为深度图像,进而使用PCL内部只适用于深度图像的算法来进行曲面重建等。
代码实现:
#include <pcl/range_image/range_image.h>
#include <pcl/range_image/range_image_planar.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/console/print.h>
#include <pcl/surface/organized_fast_mesh.h>
#include <pcl/console/time.h>
#include <Eigen/StdVector>
#include <Eigen/Geometry>
#include <iostream>
#include <pcl/surface/impl/organized_fast_mesh.hpp>
#include <boost/thread/thread.hpp>#include <pcl/common/common_headers.h>#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
using namespace pcl::console;
int main (int argc, char** argv) {// Generate the dataif (argc<2){print_error ("Syntax is: %s input.pcd -w 640 -h 480 -cx 320 -cy 240 -fx 525 -fy 525 -type 0 -size 2\n", argv[0]);print_info (" where options are:\n");print_info (" -w X = width of detph iamge ");return -1;}std::string filename = argv[1];//深度图像的宽度、高度、光轴在深度图像上的坐标点、成像的焦距int width=640,height=480,size=2,type=0;float fx=525,fy=525,cx=320,cy=240;parse_argument (argc, argv, "-w", width);//深度图像的宽度parse_argument (argc, argv, "-h", height);//深度图像的高度parse_argument (argc, argv, "-cx", cx);//光轴在深度图像上的x坐标parse_argument (argc, argv, "-cy", cy);//光轴在深度图像上的y坐标parse_argument (argc, argv, "-fx", fx);//水平方向的焦距parse_argument (argc, argv, "-fy", fy);//垂直方向的焦距parse_argument (argc, argv, "-type", type);//曲面重建时三角化的方式parse_argument (argc, argv, "-size", size);//曲面重建时的面片的大小//convert unorignized point cloud to orginized point cloud beginpcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);pcl::io::loadPCDFile (filename, *cloud);print_info ("Read pcd file successfully\n");Eigen::Affine3f sensorPose;//相机的位姿sensorPose.setIdentity(); pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;//成像时遵循的坐标系统float noiseLevel=0.00;float minRange = 0.0f;//创建了RangeImagePlanar对象,利用该对象的函数createFromPointCloudWithFixedSize()进行深度图像的生成pcl::RangeImagePlanar::Ptr rangeImage(new pcl::RangeImagePlanar);rangeImage->createFromPointCloudWithFixedSize(*cloud,width,height,cx,cy,fx,fy,sensorPose,coordinate_frame);std::cout << rangeImage << "\n";//convert unorignized point cloud to orginized point cloud end//viusalization of range imagepcl::visualization::RangeImageVisualizer range_image_widget ("点云库PCL从入门到精通1");range_image_widget.showRangeImage (*rangeImage);range_image_widget.setWindowTitle("点云库PCL从入门到精通2");//triangulation based on range imagepcl::OrganizedFastMesh<pcl::PointWithRange>::Ptr tri(new pcl::OrganizedFastMesh<pcl::PointWithRange>);pcl::search::KdTree<pcl::PointWithRange>::Ptr tree (new pcl::search::KdTree<pcl::PointWithRange>);tree->setInputCloud(rangeImage);pcl::PolygonMesh triangles;tri->setTrianglePixelSize(size);//参数size控制重建曲面的精细程度tri->setInputCloud(rangeImage);tri->setSearchMethod(tree);tri->setTriangulationType((pcl::OrganizedFastMesh<pcl::PointWithRange>::TriangulationType)type);//设置的三角化的类型,是个枚举类型,包含三角形、四边形等tri->reconstruct(triangles);boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("点云库PCL从入门到精通3"));viewer->setBackgroundColor(0.5,0.5,0.5);viewer->addPolygonMesh(triangles,"tin");viewer->addCoordinateSystem();while (!range_image_widget.wasStopped ()&&!viewer->wasStopped()){range_image_widget.spinOnce ();pcl_sleep (0.01);viewer->spinOnce ();}
}
命令行执行语句:
…>greedy_projection.exe …/1.pcd -size 5
运行结果:
深度图可视化结果
曲面重建结果
命令行执行语句:
…>greedy_projection.exe …/1.pcd -size 20
运行结果:
深度图可视化结果
曲面重建结果
说明:命令行参数中,第一个为输入点云,第二个用于控制重建曲面的精细程度,由以上两个不同的精细程度的参数的设置,可以看到重建的结果的精细程度有所改变。
这篇关于PCL——点云到深度图的变换与曲面重建的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!