PCL 估计某些部分的法线方向错误

PCL estimates wrong normal direction in some parts

我正在使用 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;

也许我应该调整一些其他参数?或者改用更好的方法?感谢您的关注!

您的视点位于对象的中间,而不是检测到的点所在的位置。所有法线都朝向(或远离)视点,其想法是该点后面有一个实体对象。在你的情况下,情况并非如此。

您可以将视点设置为实际检测到点的位置,并根据该点定位它们。

如果这不是您的选择,您可以尝试这样做。

  1. 选择邻居搜索的半径

  2. 随机选择一个点开始,检查法线是否正常 您想要的方式并将其标记为完成(也许从 云或点指数)。

  3. 然后select它的邻居并检查 如果法线相同(点积为正)。如果没有,翻转它们并标记它们完成。

  4. 找到这些点的邻居并重复所有点。

这应该可以解决问题。玩转半径,这样你就做对了。您不想 select 来自 "fingers".

相对两侧的点

AFAIK PCL 没有真正可靠的方法来确定组合 "complete" 扫描的法线方向。