pcl计算点云法向量

最近因为项目,需要计算点云的法向量,所以在网上看了一些资料,然后知道pcl库里面有这些功能,pcl的法向量计算的原理:
pcl里面计算点云(自己的理解
根据顶点采样最近的局部点云(k个),根据自己的点云拟合出一个局部平面,然后计算平面的法向量。就是顶点的向量。
计算可以通过PCA那种,可以计算顶点的三个方向的主成分,然后得到最次的主成分对应的法向量,就是平面法向量。
以下是自己使用PCL计算法向量的过程,因为引用都是PCL库,所以只需要理解这个库的使用就可以了。

#include<pcl\point_types.h>
#include<pcl\kdtree\kdtree_flann.h>
#include<pcl\features\normal_3d.h>
#include<pcl\point_cloud.h>

	bool CaculateNormals()
	{
		if (HasNormal() && vertices_normals_.size() == vertices_.size())
			return true;
		std::cout << "start compute normal..." << std::endl;

		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
		for (int i = 0; i < vertices_.size(); ++i)	//这是一个类里面的函数,需要自己提供点云
		{
			pcl::PointXYZ p(vertices_[i](0), vertices_[i](1), vertices_[i](2));
			cloud->points.emplace_back(p);
		}
		pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> cloud_normals;
		pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
		//在flann中找到kdtree搜索机制
		pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
		//为kdtree增加搜索的点云
		tree->setInputCloud(cloud);
		cloud_normals.setInputCloud(cloud);
		cloud_normals.setSearchMethod(tree);
		cloud_normals.setKSearch(20);

		std::clock_t start_read = std::clock();

		cloud_normals.compute(*normals);

		std::clock_t end_read = std::clock();

		const float parsing_time = static_cast<float>(double(end_read - start_read)) / 1000.f;
		std::cout << "\t compute normal time parsing " << parsing_time << " seconds " << std::endl;

		std::cout << "normal num is: " << normals->size() << std::endl;
		std::cout << "end compute the cloud normals." << std::endl;

		//清空
		vertices_normals_.swap(std::vector<Eigen::Vector3f>());
		for (int i = 0; i < normals->size(); ++i)
		{
			Eigen::Vector3f tmp(normals->points[i].normal_x, 
				normals->points[i].normal_y, normals->points[i].normal_z);
			vertices_normals_.emplace_back(tmp);
		}

		return true;
	}

这样就得到点云中的法向量。

上一篇:Three.js Example 注解 —— webgl_morphtargets.html


下一篇:1142 Maximal Clique (25 分) 图论