16

我想知道比较一组轮廓的最佳策略是什么,实际上是从两张图片中进行精明边缘检测的边缘,以便知道哪一对更相似。

我有这张图片:

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

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

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

(应该是右边那个)

无论如何要比较整个轮廓吗?我可以轻松地旋转图像,但我不知道使用什么函数来计算右侧的参考图像是最合适的。

这是我已经尝试过使用opencv的:

matchShapes 函数 - 我使用 2 个灰度图像尝试了此函数,并且在每个比较图像中我总是得到相同的结果,并且该值似乎是错误的,因为它是 0,0002。

所以我意识到matchShapes,但我不确定这是正确的假设,是该函数适用于成对的轮廓而不是完整的图像。现在这是一个问题,因为虽然我有我想要比较的图像的轮廓,但它们有数百个,我不知道哪些应该“配对”。

因此,我还尝试将第一个图像的所有轮廓与其他两个进行迭代进行比较,但我可能会比较,例如,5 的轮廓与两个参考图像的圆形轮廓而不是 2 轮廓。

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

4

1 回答 1

20

好吧,为此,您有几个选择,具体取决于您需要的方法有多健壮。

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

对于这些方法,我假设您提供的图像是您正在使用的图像(即,对象已经被分割并且大致相同的比例。此外,您将需要校正旋转(至少以粗略的方式) . 您可能会执行类似的操作,例如每 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):一旦确定了近似的旋转角度,这将允许您快速比较图像。
  • 余弦相似度:通过将图像视为一维向量,这有点不同,然后计算两个向量之间的高维角度。匹配越好,角度越小。

复杂的解决方案(可能更强大):

这些解决方案实施起来会更复杂,但可能会产生更稳健的分类。


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