OpenCV匹配轮廓图像

17
我希望了解比较一组轮廓的最佳策略,实际上是从两张图片中得到的Canny边缘检测结果,以便知道哪对更相似。
我有这张图片:

http://i55.tinypic.com/10fe1y8.jpg

我想知道如何计算哪一个最适合它:

http://i56.tinypic.com/zmxd13.jpg

(应该是右边的那个)

有没有办法将轮廓整体进行比较? 我可以很容易地旋转图像,但我不知道要使用哪些函数才能计算出右侧参考图像的最佳匹配。

这是我已经尝试过的opencv:

matchShapes函数 - 我尝试使用两个灰度图像进行此函数,并且在每次比较图像时都会得到相同的结果,而且该值似乎是错误的,因为它是0.0002。

因此,我意识到matchShapes的问题,但我不确定这是否是正确的假设,即该函数与轮廓对而不是完整图像一起工作。现在这是一个问题,因为虽然我有要比较的图像的轮廓,但它们有数百个,我不知道哪些应该“配对”。

所以我也尝试使用for迭代将第一个图像的所有轮廓与另外两个进行比较,但我可能正在比较例如5的轮廓与两个参考图像的圆形轮廓而不是2的轮廓。

还尝试了简单的cv :: compare函数和matchTemplate,但都没有成功。

1个回答

21

针对这个问题,你有几个选项,取决于你需要多么稳健的方法。

简单解决方案(带有假设):

对于这些方法,我假设你使用的是您提供的图像(即对象已经分割并且大致相同比例)。此外,你需要对旋转进行矫正(至少粗略地)。你可以像迭代旋转比较图像每10、30、60或90度,或者你觉得可以逃脱的任何粗略程度。

例如,

for(degrees = 10; degrees < 360; degrees += 10)
    coinRot = rotate(compareCoin, degrees)
    // you could also try Cosine Similarity, or even matchedTemplate here.
    metric = SAD(coinRot, targetCoin) 
    if(metric > bestMetric)
        bestMetric = metric
        coinRotation = degrees

  • 绝对差值和 (SAD):在确定近似旋转角度后,这将允许您快速比较图像。
  • 余弦相似性:通过将图像视为1D向量,并计算两个向量之间的高维角度来进行操作。匹配越好,角度越小。

复杂的解决方案(可能更加稳健):

这些解决方案将更加复杂,但可能会产生更加可靠的分类结果。


  • 豪斯多夫距离: 这个回答将向您介绍使用此方法的方法。该解决方案可能还需要旋转校正才能正常工作。
  • Fourier-Mellin变换:此方法是相位相关的扩展,可以提取两个图像之间的旋转,缩放和平移(RST)变换。
  • 特征检测和提取:此方法涉及在图像中检测“稳健”(即缩放和/或旋转不变)的特征,并使用RANSAC、LMedS或简单的最小二乘法将它们与一组目标特征进行比较。OpenCV有几个使用此技术的示例,在matcher_simple.cppmatching_to_many_images.cpp中。 注意:使用此方法时,您可能不希望对图像进行二值化,因此可用的可检测特征更多。

1
非常感谢提供的指南...我会立即开始学习...非常感谢..当我更好地分析推荐步骤后,我会给出一些反馈。 - out_sid3r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接