pcl計算点群法ベクトル

13011 ワード

最近プロジェクトのため、点群の法ベクトルを計算する必要があるので、ネット上でいくつかの資料を見て、それからpclライブラリの中にこれらの機能があることを知っていて、pclの法ベクトルの計算の原理:pclの中で点群(自分の理解)を計算して頂点によって最も近い局部点群(k個)をサンプリングして、自分の点群によって1つの局部平面をフィッティングして、それから平面の法ベクトルを計算します.頂点のベクトルです.計算はPCAのように、頂点の3方向の主成分を計算して、最も次の主成分に対応する法ベクトル、すなわち平面法ベクトルを得ることができる.以下は,PCL計算法ベクトルを自分で使用する過程であり,参照はすべてPCLライブラリであるため,このライブラリの使用を理解するだけでよい.
#include
#include
#include
#include

	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;
	}

これにより,点雲における法ベクトルが得られる.