我使用OpenCV的cv::findHomography
API来计算两个平面图像的单应矩阵。
匹配的关键点由SIFT提取并由BFMatcher匹配。据我所知,cv:findHomography
使用RANSAC迭代找出最佳的四个对应点来获得单应矩阵。
因此,我使用对象边缘的同一矩阵绘制所选择的四对点和计算出的轮廓。
结果如链接:
https://postimg.cc/image/5igwvfrx9/
正如我们所看到的,RANSAC选择的匹配点是正确的,但轮廓显示单应性不准确。
但是这些测试表明,所选择的匹配点和单应性都是正确的:
https://postimg.cc/image/dvjnvtm53/
我的猜测是,如果选定的匹配点太近,像素位置的小误差将导致单应矩阵的显着误差。如果四个点位于图像的角落,那么匹配点的移位4-6个像素仍然具有良好的单应矩阵。 (根据同质坐标,我认为这是合理的,因为近平面的小误差会在很远的地方被放大)
我的问题是:
1.我猜对了吗? 2.由于RANSAC迭代生成了四个匹配点,因此所有关键点的总误差最小。但是如何获得稳定的单应性,至少使轮廓的映射是正确的?理论证明,如果找到平面上的四个对应点,应该计算单应矩阵,但是工程师的工作是否有任何技巧?
答案 0 :(得分:8)
我认为你是对的,4点的接近度无助于结果的准确性。您观察到的可能是由数字问题引起的:对于这4个点,结果可能局部正确,但在进一步发展时会变得更糟。
然而,RANSAC在这里不会帮助你。原因很简单:RANSAC是一个强大的估计程序,旨在找到许多对应关系中的最佳点对(包括一些错误的对应关系)。然后,在RANSAC的内环中,执行标准的单应性估计。
您可以看到 RANSAC 作为拒绝错误点对应的方式,这会导致错误的结果。
回到你的问题:
你真正需要的是获得更多积分。在您的示例中,您仅使用4点对应关系,这足以估计单应性。 您将通过在目标图片上提供更多匹配来改善结果。然后问题变得过于确定,但OpenCV仍然可以找到最小二乘解决方案。此外,在点对应过程或某些点定位中存在一些错误,RANSAC将能够选择最佳的并且仍然给您可靠的结果。
如果RANSAC导致过度拟合4个点(在您的示例中似乎就是这种情况),请尝试通过增加ransacReprojThreshold
参数来放宽约束。
或者,你可以:
CV_LMEDS
是一个不错的选择)答案 1 :(得分:5)
只是为了扩展@sansuiso的回答,我同意:
如果您向RANSAC提供大约100个通信,那么您可能会从cvFindHomography
获得超过4个内容。检查status
输出参数。
为了获得良好的单应性,你应该有超过4个对应关系(注意4个对应关系总是给你一个单应性),它们很好地分布在图像周围并且不是线性的。实际上,您可以使用最少数量的内点来确定获得的单应性是否足够好。
请注意,RANSAC找到一组一致的点,但是它必须说该集合是最好的(重投影错误)有点受限。有一种类似RANSAC的方法,称为MSAC,它使用稍微不同的误差测量,检查出来。
根据我的经验,坏消息是大多数时候几乎不可能获得100%的精确单应性。如果你有几个相似的框架,你可能会发现它们之间的单应性变化很小。
有一些技巧可以改善这一点。例如,在使用RANSAC获得单应性后,您可以使用它将模型投影到图像中,并查找新的对应关系,这样您就可以找到另一个应该更准确的单应性。
答案 2 :(得分:1)
你的目标有很多对称和相似的元素。正如其他人提到的(你后来澄清),点间距和点数可能是个问题。另一个问题是SIFT并非旨在处理您的案例中存在的重大透视扭曲。尝试通过较小的旋转跟踪您的对象,如前所述,使用最新的单应性重新投影它,使其看起来尽可能接近原始。这也将允许您跳过处理繁重的SIFT并使用像FAST一样轻量级的东西,并使用图像补丁的互相关进行匹配。
你也可能最终明白使用积分是不够的。你必须使用你所拥有的一切,这意味着线条或圆锥曲线。如果单应性变换点Pb = H * Pa,则很容易验证在齐次坐标线Lb = Henv.transposed * La。这直接来自等式La'.Pa = 0 = La'* Hinv * H * Pa = La'* Hinv * Pb = Lb'.Pb 可能的分钟。配置是1行和3点或3行和1点。两条线和两条点不起作用。您也可以使用四行或四个点。当然这意味着您不能再使用openCV功能,必须编写自己的DLT然后进行非线性优化。