Opencv匹配轮廓图像

out*_*d3r 14 opencv contour

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

我有这个图像:

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

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

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

(它应该是右边的那个)

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

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

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

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

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

还试过简单的cv :: compare函数和matchTemplate,没有成功.

mev*_*ron 19

那么,为此你有几个选择,取决于你需要多么强大的方法.

简单解决方案(假设):

对于这些方法,我假设您提供的图像是您正在使用的图像(即,对象已经被分割并且大致相同的比例.此外,您将需要校正旋转(至少以粗略的方式)你可以做一些事情,比如每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
Run Code Online (Sandbox Code Playgroud)
  • 绝对差值之和(SAD):一旦确定了近似旋转角度,就可以快速比较图像.
  • 余弦相似度:通过将图像视为一维矢量,然后计算两个矢量之间的高维角度,这有点不同.匹配越好,角度越小.

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

这些解决方案实施起来会更复杂,但可能会产生更强大的分类.


  • Haussdorf距离:这个答案将为您介绍使用此方法.该解决方案可能还需要旋转校正才能正常工作.
  • 傅里叶 - 梅林变换:此方法是相位相关的扩展,可以提取两个图像之间的旋转,缩放和平移(RST)变换.
  • 特征检测和提取:该方法涉及检测图像中的"鲁棒"(即,尺度和/或旋转不变)特征,并将它们与具有RANSAC,LMedS或简单最小二乘的一组目标特征进行比较.OpenCV在matcher_simple.cppmatching_to_many_images.cpp中使用了这种技术的几个示例.注意:使用此方法您可能不希望对图像进行二值化,因此可以使用更多可检测的功能.