pcl 的 IterativeClosestPoint 没有给出预期的结果
IterativeClosestPoint with pcl does not give expected results
我得到了两个点云。为了匹配他们,我尝试使用 ICP 进行注册。点云不是非常相似,但我至少想让它们非常接近。
当使用 pcl 库中的 IterativeClosestPoint
时,当我使用我的点云 A
作为源并使用点云 B
作为目标时,这会起作用。但是当我使用 B
作为源和 A
作为目标时它不起作用。在后一种情况下,它甚至增加了我两朵云之间的距离。
有谁知道我做错了什么?为什么更改 source/target 时性能会有所不同?
这是我的代码:
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(A);
icp.setInputTarget(B);
icp.setMaximumIterations(50);
icp.setTransformationEpsilon(1e-8);
icp.setEuclideanFitnessEpsilon(1);
icp.setMaxCorrespondenceDistance(0.5); // 50cm
icp.setRANSACOutlierRejectionThreshold(0.03);
icp.align(aligned_model_cloud);
我很高兴收到任何想法和意见。
更新:
我使用 Cloud A
作为源并使用 Cloud A
* 作为目标尝试了我的代码。其中 Cloud A
* 是 Cloud A
的副本,仅在 x 轴上进行了翻译。我用 Cloud B
做了同样的实验,两者都能够在 icp 中成功收敛。
但是一旦我使用 Cloud B
作为源和 Cloud A
作为目标,它就不再起作用并且在移动云一点点(即使是错误的方向)后收敛。我检查了convergecriteria,发现它是CONVERGENCE_CRITERIA_REL_MSE
(当transfromationEpslion几乎为零时)。我试着减少相对 MSE
icp.getConvergeCriteria()->setRelativeMSE(1e-15)
但这没有成功。在收敛后检查 relativeMSE 的值时,我得到这样的结果:-124034642
这对我来说根本没有任何意义。
Update2: 我先在没有 ICP 的情况下将云移得很近。执行此 ICP 时效果很好。
Update3: 我正在做 FPFH 以进行初步估计,然后进行 ICP。这样做也行。
这个问题很老了,OP 已经找到了解决方案,但我只是解释一下,以防 OP 和有人觉得它有用。
首先,ICP 的工作原理是迭代估计两个云之间的对应关系,然后最小化它们之间的总体距离。 ICP 使用最近点数据关联估计对应关系(因此得名迭代最近点)。
如您所知,最近邻图是有向的。也就是说,如果 A 点有 B 作为它的最近邻居,那么 B 点可能没有 A 作为它的最近邻居,因为 C 比 A 更接近 B!
现在 ICP 使用最近点数据关联来估计两个云之间的对应关系,指定 A 作为源将得到与指定 B 不同的对应集。这解释了您观察到的差异。
通常差异很小,ICP后您可能不会注意到。但在你的情况下,我发现你提供的两朵云太不一样了(一个特别大,另一个小),关系变得太不对称了。
如果你想确保结果是对称的,你可以只更改数据关联步骤(PCL 可能会提供这样做的选项)以使最近点对应来自两个云(这是只是经典ICP的一个变体。更多信息你可以看我的other answer).
我得到了两个点云。为了匹配他们,我尝试使用 ICP 进行注册。点云不是非常相似,但我至少想让它们非常接近。
当使用 pcl 库中的 IterativeClosestPoint
时,当我使用我的点云 A
作为源并使用点云 B
作为目标时,这会起作用。但是当我使用 B
作为源和 A
作为目标时它不起作用。在后一种情况下,它甚至增加了我两朵云之间的距离。
有谁知道我做错了什么?为什么更改 source/target 时性能会有所不同?
这是我的代码:
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(A);
icp.setInputTarget(B);
icp.setMaximumIterations(50);
icp.setTransformationEpsilon(1e-8);
icp.setEuclideanFitnessEpsilon(1);
icp.setMaxCorrespondenceDistance(0.5); // 50cm
icp.setRANSACOutlierRejectionThreshold(0.03);
icp.align(aligned_model_cloud);
我很高兴收到任何想法和意见。
更新:
我使用 Cloud A
作为源并使用 Cloud A
* 作为目标尝试了我的代码。其中 Cloud A
* 是 Cloud A
的副本,仅在 x 轴上进行了翻译。我用 Cloud B
做了同样的实验,两者都能够在 icp 中成功收敛。
但是一旦我使用 Cloud B
作为源和 Cloud A
作为目标,它就不再起作用并且在移动云一点点(即使是错误的方向)后收敛。我检查了convergecriteria,发现它是CONVERGENCE_CRITERIA_REL_MSE
(当transfromationEpslion几乎为零时)。我试着减少相对 MSE
icp.getConvergeCriteria()->setRelativeMSE(1e-15)
但这没有成功。在收敛后检查 relativeMSE 的值时,我得到这样的结果:-124034642
这对我来说根本没有任何意义。
Update2: 我先在没有 ICP 的情况下将云移得很近。执行此 ICP 时效果很好。
Update3: 我正在做 FPFH 以进行初步估计,然后进行 ICP。这样做也行。
这个问题很老了,OP 已经找到了解决方案,但我只是解释一下,以防 OP 和有人觉得它有用。
首先,ICP 的工作原理是迭代估计两个云之间的对应关系,然后最小化它们之间的总体距离。 ICP 使用最近点数据关联估计对应关系(因此得名迭代最近点)。
如您所知,最近邻图是有向的。也就是说,如果 A 点有 B 作为它的最近邻居,那么 B 点可能没有 A 作为它的最近邻居,因为 C 比 A 更接近 B!
现在 ICP 使用最近点数据关联来估计两个云之间的对应关系,指定 A 作为源将得到与指定 B 不同的对应集。这解释了您观察到的差异。
通常差异很小,ICP后您可能不会注意到。但在你的情况下,我发现你提供的两朵云太不一样了(一个特别大,另一个小),关系变得太不对称了。
如果你想确保结果是对称的,你可以只更改数据关联步骤(PCL 可能会提供这样做的选项)以使最近点对应来自两个云(这是只是经典ICP的一个变体。更多信息你可以看我的other answer).