《PCL点云库学习&VS2010(X64)》Part 12 PCL1.72(VTK6.2.0)三角网格化(1)

Part 12 PCL1.72(VTK6.2.0)三角网格化(1)


1、GreedyProjectionTriangulation

cpp:

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/math/special_functions/round.hpp>
int
main(int argc, char** argv)
{
	// Load input file into a PointCloud<T> with an appropriate type
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCLPointCloud2 cloud_blob;
	pcl::io::loadPCDFile("Bunny.pcd", cloud_blob);
	pcl::fromPCLPointCloud2(cloud_blob, *cloud);
	//* the data should be available in cloud

	// Normal estimation*
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
	tree->setInputCloud(cloud);
	n.setInputCloud(cloud);
	n.setSearchMethod(tree);
	n.setKSearch(30);
	n.compute(*normals);
	//* normals should not contain the point normals + surface curvatures

	// Concatenate the XYZ and normal fields*
	pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
	pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
	//* cloud_with_normals = cloud + normals

	// Create search tree*
	pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
	tree2->setInputCloud(cloud_with_normals);

	// Initialize objects
	pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
	pcl::PolygonMesh triangles;

	// Set the maximum distance between connected points (maximum edge length)
	gp3.setSearchRadius(0.05);

	// Set typical values for the parameters
	gp3.setMu(2.5);
	gp3.setMaximumNearestNeighbors(300);
	gp3.setMaximumSurfaceAngle(M_PI / 2); // 45 degrees
	gp3.setMinimumAngle(M_PI / 36); // 10 degrees
	gp3.setMaximumAngle(5 * M_PI / 6); // 120 degrees
	gp3.setNormalConsistency(false);

	// Get result
	gp3.setInputCloud(cloud_with_normals);
	gp3.setSearchMethod(tree2);
	gp3.reconstruct(triangles);

	// Additional vertex information
	std::vector<int> parts = gp3.getPartIDs();
	std::vector<int> states = gp3.getPointStates();

	// Viewer
	pcl::visualization::PCLVisualizer viewer("viewer");
	viewer.addPolygonMesh(triangles);
	viewer.spin();

	// Finish
	return (0);
}


运行后的网格还算比较精细,主要和设置的参数有关,特别是搜索的领域个数、半径以及最小最大角等有重大关系,生成的网格越精细,时间越长。但是还是有孔洞,有待优化。


注:pcl网格模型有三种可选的显示模式,分别是面片模式(Surface)显示,线框图模式(Wireframe)显示,点模式(Points)显示(貌似还有其他的形式,具体使用过依次,函数可以查相关的手册)。默认为面片模式进行显示。设置函数依次为:

void pcl::visualization::PCLVisualizer::setRepresentationToSurfaceForAllActors ( ) 
void pcl::visualization::PCLVisualizer::setRepresentationToWireframeForAllActors ( ) 
void pcl::visualization::PCLVisualizer::setRepresentationToPointsForAllActors ( )

使用时,只需在可视话的时候,添加如下:

 //设置网格模型显示模式

        viewer->setRepresentationToSurfaceForAllActors(); //网格模型以面片形式显示  
        //viewer->setRepresentationToPointsForAllActors(); //网格模型以点形式显示  
        //viewer->setRepresentationToWireframeForAllActors();  //网格模型以线框图模式显示

2、Grid Projection


cpp:

//#include "stdafx.h"
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/grid_projection.h>
#include <iostream>
#include <string.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <time.h>


// convenient typedefs
typedef pcl::PointXYZ PointT; // pcl Point coordinate in 3-D 
typedef pcl::PointCloud<PointT> PointCloud;	// pcl Point cloud structure

int main(int argc, char**argv)
{
// Load input file into a PointCloud<T> with an appropriate type
// load the original data
//PointCloud::Ptr cloud (new PointCloud);	// original point cloud data
//if(readPCDFiles(cloud)==false) {
//	return -1;
//}
PointCloud::Ptr cloud(new PointCloud);
pcl::io::loadPCDFile("rabbit.pcd", *cloud);
std::cout << "Loaded " << cloud->width * cloud->height << " data points from " << "pcd files!" << std::endl;

// Create a timer
clock_t start, end;

// Normal estimation*
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud (cloud);
ne.setInputCloud (cloud);
ne.setSearchMethod (tree);
ne.setKSearch (20);
ne.compute (*normals);
//* normals should not contain the point normals + surface curvatures

// Concatenate the XYZ and normal fields*
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
//* cloud_with_normals = cloud + normals

std::cout << "normals computed!" << std::endl;

// Create search tree*
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::search::KdTree<pcl::PointNormal>);
tree2->setInputCloud (cloud_with_normals);

// Initialize objects
pcl::GridProjection<pcl::PointNormal> gp;
pcl::PolygonMesh mesh;
std::cout << "Computation began!" << std::endl;
gp.setInputCloud(cloud_with_normals);
gp.setSearchMethod(tree2);
gp.setResolution(0.005);// 输入立方体的边长,这个长度和输入
//点云密度有关,其值应与点与点之间的平均距离接近
//setNearestNeighborNum(2) k临近点搜索代替上述的Padding,一般2和3就可以了。
gp.setPaddingSize(3);//与setPaddingSize()函数二选一使用,不过该函数比较稳定
gp.setMaxBinarySearchLevel(11);//二分法搜索投影位置,输入为最大搜索深度
start = clock();
gp.reconstruct(mesh);
end = clock();
std::cout << "Computation ended!" << std::endl;
std::cout << (end-start)/CLOCKS_PER_SEC << "s used!" << std::endl;

// Viewer
pcl::visualization::PCLVisualizer viewer("viewer");
viewer.addPolygonMesh(mesh);
viewer.spin();

// Finish
return 0;
}



运行,发现模型精细程度并不高(其实是可调节的,将立方体的体积减小,可以得到比较好的模型):



3、Moving Least Square


cpp:


#include <iostream>
#include <string.h>
#include <pcl/io/pcd_io.h>	// pcl IO
#include <pcl/point_types.h>	// pcl PointT Structures
#include <pcl/visualization/pcl_visualizer.h>	// pcl Display using VTK library
#include <pcl/Polygonmesh.h>
#include <pcl/kdtree/kdtree_flann.h>
//#include <pcl/surface/mls_omp.h>
#include <pcl/surface/mls.h>
#include <time.h> 

// convenient typedefs
typedef pcl::PointXYZ PointT; 
typedef pcl::PointCloud<PointT> PointCloud;	

int main(int argc,char** argv)
{
PointCloud::Ptr inputCloud (new PointCloud);	// original point cloud data
PointCloud::Ptr outputCloud (new PointCloud);
pcl::visualization::PCLVisualizer viewer("demo");	// visualizer	

// load the original data
pcl::io::loadPCDFile("can.pcd", *inputCloud);
std::cout << "Loaded " << inputCloud->width * inputCloud->height << " data points from " << "pcd files!" << std::endl;

// Create a timer 
clock_t start, end;

// MLS filter
pcl::MovingLeastSquaresOMP<PointT, PointT> mls(10);
//pcl::MovingLeastSquares<PointT, PointT> mls(10);
//<PointInT, PointOutT> mls,if output with normals,and mls.setComputeNormals(true),PointOutT must be normals

// search method
pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);

mls.setInputCloud(inputCloud);
mls.setSearchMethod (tree);
mls.setPolynomialFit (true);
mls.setPolynomialOrder(4);
mls.setComputeNormals(false);
mls.setSearchRadius(8);
mls.setUpsamplingMethod(mls.SAMPLE_LOCAL_PLANE); 
mls.setUpsamplingRadius(10);
mls.setUpsamplingStepSize(4.5);
start = clock();
mls.process(*outputCloud);
end = clock();
std::cout << "Computation ended!" << std::endl<< outputCloud->size() << "Points after MLS!"<<std::endl;
std::cout << (end - start) / CLOCKS_PER_SEC << "s used!" << std::endl;

pcl::io::savePCDFileASCII<PointT>("can_mls.pcd",*outputCloud);

viewer.setBackgroundColor (0.0, 0.0, 0.0);
pcl::visualization::PointCloudColorHandlerCustom<PointT> handler(outputCloud, 255, 0, 0);
viewer.addPointCloud<PointT> (outputCloud, handler, "sample cloud");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
viewer.initCameraParameters ();

viewer.spin();

return 0;
}



运行后没有生成网格,不过点云变得密集均匀了。


相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页