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;
}
これにより,点雲における法ベクトルが得られる.