我正在使用 PCL 计算点云的法线。用Meshlab,法线是对的,虽然所有的法线都是从外到内的,但是我把它们都反转后就是正确的。
但是当我使用 PCL 执行此操作时,如左图所示,一些法线的方向是错误的。
为了更有意义,下面是使用 meshlab 和 PCL 重建的表面,使用 PCL 估计的法线,我无法得到正确的结果。
我的代码如下,我的示例 .ply 数据是 here ,我的模型可以在这里找到,我尝试更改半径、邻居数和质心位置,但无法解决这个问题。
cout << "begin normal estimation" << endl;
NormalEstimationOMP<PointXYZ, Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setSearchMethod(tree);
ne.setNumberOfThreads(8);
ne.setInputCloud(filtered);
ne.setKSearch(15);
ne.setRadiusSearch(5);
Eigen::Vector4f centroid;
compute3DCentroid(*filtered, centroid);
ne.setViewPoint(centroid[0], centroid[1], centroid[2]);
PointCloud<Normal>::Ptr cloud_normals (new PointCloud<Normal>());
ne.compute(*cloud_normals);
cout << "normal estimation complete" << endl;
也许我应该调整一些其他参数?或者改用更好的方法?感谢您的关注!
最佳答案
您的视点位于对象的中间,而不是检测到的点所在的位置。所有法线都朝向(或远离)视点,其想法是该点后面有一个实体对象。在你的情况下,情况并非如此。
您可以将视点设置为实际检测到点的位置,并根据该点定位它们。
如果这不是您的选择,您可以尝试做这样的事情。
选择邻居搜索的半径
从哪里开始随机选择一个点,检查法线是否正常 您想要的方式并将其标记为完成(也许从 云或点指数)。
然后选择它的邻居并检查 如果法线相同(点积为正)。如果没有,翻转它们并将它们标记为完成。
找到这些点的邻居并重复所有点。
这应该可以解决问题。玩转半径,这样你就做对了。您不想从“手指”的相对侧选择点。
AFAIK PCL 没有真正可靠的方法来确定组合“完整”扫描的法线方向。
关于c++ - PCL估计某些部分的法线方向错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47428220/