我用的是OpenCV cv::findHomography
API用于计算两个平面图像的单应矩阵。
匹配的关键点由SIFT提取并由BFMatcher匹配。我所知, cv:findHomography
使用RANSAC迭代找出最佳的四个对应点以获得单应矩阵。
因此,我使用对象边缘的同一矩阵绘制所选择的四对点和计算出的轮廓。
结果如链接:
https://postimg.cc/image/5igwvfrx9/
我们可以看到,RANSAC选择的匹配点是正确的,但轮廓显示单应性不准确。
但是这些测试表明,所选择的匹配点和单应性都是正确的:
https://postimg.cc/image/dvjnvtm53/
我的猜测是,如果选定的匹配点太近,像素位置的小误差将导致单应矩阵的显着误差。如果四个点位于图像的角落,那么匹配点的移位4-6个像素仍然具有良好的单应矩阵。
(根据同质坐标,我认为这是合理的,因为近平面的小误差会在很远的地方被放大)
我的问题是:
我猜对了吗?
2.由于RANSAC迭代生成了四个匹配点,因此所有关键点的总误差最小。但是如何获得稳定的单应性,至少使轮廓的映射是正确的?该理论证明,如果找到平面中的四个对应点,则应计算单应矩阵,但工程师工作中是否有任何技巧?
我认为你是对的,而且 接近4点 无助于结果的准确性。你观察到的可能是由数字问题引起的:结果可能是 在当地正确 对于这4点,但进一步走得更糟。
但是,RANSAC在这里不会帮助你。原因很简单:RANSAC是一个强大的估算程序,旨在找到许多对应关系中的最佳点对(包括一些错误的对应关系)。然后,在RANSAC的内环中,执行标准单应性估计。
你可以看到 RANSAC 作为一个 拒绝错误点对应的方法 这会引起不好的结果。
回到你的问题:
你真正需要的是获得更多积分。在您的示例中,您仅使用4点对应关系,这足以估计单应性。
您将通过提供来改善您的结果 更多比赛 遍布目标图像。然后问题变得过于确定,但OpenCV仍然可以找到最小二乘解决方案。此外,在点对应过程或某些点定位中存在一些错误,RANSAC将能够选择最佳的并且仍然给您可靠的结果。
如果RANSAC导致过度拟合在4个点上(在您的示例中似乎就是这种情况),请尝试通过增加 ransacReprojThreshold
参数。
或者,你可以:
- 使用不同的估计量(稳健的中位数
CV_LMEDS
如果匹配错误很少,这是一个很好的选择)
- 或者在第一步中使用RANSAC以获得大的重投影误差(以获得粗略估计)以便检测伪匹配,然后在正确的匹配上使用LMEDS。
只是为了扩展@sansuiso的答案,我同意:
如果你向RANSAC提供大约100个通信,那么你可能会得到超过4个内容 cvFindHomography
。检查 status
输出参数。
为了获得良好的单应性,你应该有超过4个对应关系(注意4个对应关系总是给你一个单应性),它们很好地分布在图像周围并且不是线性的。您实际上可以使用最少数量的内点来确定获得的单应性是否足够好。
请注意,RANSAC找到一组一致的点,但它必须说该集合是最好的(重投影错误)有点受限。有一种类似RANSAC的方法,称为MSAC,它使用稍微不同的错误测量,检查出来。
根据我的经验,坏消息是大多数时候几乎不可能获得100%精确的单应性。如果你有几个类似的框架,你可能会发现它们之间的单应性变化很小。
有一些技巧可以改善这一点。例如,在使用RANSAC获得单应性后,您可以使用它将模型投影到图像中,并查找新的对应关系,这样您就可以找到另一个应该更准确的单应性。
你的目标有很多对称和相似的元素。正如其他人提到的(你后来澄清),点间距和点数可能是个问题。另一个问题是,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然后进行非线性优化。