模式匹配 - 在第二个图像中查找参考对象[OpenCV?]

时间:2012-11-29 10:14:41

标签: c++ opencv pattern-matching

我有一个参考黑白图像,其中包含一个参考对象(例如硬币)。该对象由用户标记,即感兴趣的区域。

现在我想分析其他图像并找到该对象或类似对象的位置和旋转。物体任意放置在相机下方,但从不缩放,视角始终为90度。

我已经评估了一个完全符合我要求的商业图书馆:Euresys EasyFind

您可以在下面找到手头任务的示例图像。当前的实现使用OpenCV的特征检测,并且无法正常工作。

模板:

enter image description here

找到同一枚硬币的匹配:

enter image description here

对于略有不同的硬币,比赛失败了:

enter image description here

特征检测似乎是错误的方法。我需要以某种方式简单地对象。但是,如果我这样做(Blur,Canny,CornerHarris)特征检测根本不起作用。

非常感谢任何有关坚实方法的建议。一个替代的图书馆建议也会很棒。

5 个答案:

答案 0 :(得分:9)

由于你已经尝试了很多可能的技术,我会要求你通过以下链接(可能你可能已经完成了!!!)

  1. comparision of all feature detectors and descriptors
  2. combination of surf,FREAK and brisk
  3. 你失败的第3张图像是低对比度,与其余两张完美匹配并不是很棘手...所以我进行了对比度调整,我得到了以下与Orb特征探测器和Orb Descriptor Extractor的匹配。在特征检测之前对所有图像应用对比度调整。

    图片1与图片3

    enter image description here

    图片2与图片3

    enter image description here

    带图像2的图像1(此组合适用于所有检测器/提取器对)

    enter image description here

    为了匹配,我使用了BruteForceMatcher<Hamming> matcher 虽然点是局部定位可以很好地猜测。需要使用多于一种技术并首先进行一些圆检测以将特征检测限制为尽可能小的ROI。加上检测点相对于圆心的方向可以轻松获得新的方向信息。参考第一个链接和第二个链接,您可以注意到SURF和BRIEF非常能抵抗光线强度和模糊的变化。因此,您可以尝试使用SURF和BRIEF的组合。

答案 1 :(得分:4)

在输入中应用关键点检测器而不执行任何类型的预处理是找到相关有趣匹配点的一种非常差的方法。

鉴于您的图像,数学形态学提供了预处理它们的好工具,并希望在以后的步骤中获得更好的匹配。其中一种工具称为形态重建,其概括称为Levelings,它将基于标记图像合并和扩展平坦区域。正如你所看到的,你的图像是非常有噪音的,因为到处都有山谷(那些黑点),所以你想抑制其中的大部分。实现Levelings并不难,但是因为我不知道免费提供的工具(实际上有一个大型框架在法国开发,我相信它包含它,但我不记得名字),让我们坚持下去更标准的形态重建。我们也没有标记图像,但这很容易构建:用一些结构元素侵蚀你的图像并应用形态重建,这被一些作者称为测地开放。这将抑制你的一些嘈杂的山谷。

此时您的图像可能适合与某些关键点检测器一起使用,但我建议将其二值化,因为您想要匹配的内容与灰度色调无关。 Otsu给出了典型的自动方法,但还有其他像Kapur的方法,它用于直方图熵最小化。我没有使用Otsu只是因为它很常见,对于一些Stackoverflow-新奇我去了另一种方法:P(是的,非常糟糕的原因)。最后,在二值化之后,您可以继续处理图像。这里单个形态学闭合可能就足够了,因为你想要删除一些剩余的噪声点(它们不一定与组件断开连接,因此现在删除组件可能是一个糟糕的选择)。

为了简短起见,这里是第一张图片的测地线打开和最终预处理(使用上述几点):

enter image description here enter image description here

以下是您的其他两张图片的最终结果(应用完全相同的过程,不需要不断修改或其他任何内容):

enter image description here enter image description here

如果我现在使用典型的SURF方法继续进行匹配,我会得到大部分完美的匹配,使得另一个问题(相对于另一个问题的方向)非常容易解决。我没有包括我得到的匹配结果(除非有人想比较结果),因为我相信你现在应该使用OpenCV或任何其他正确的实现获得相同的结果。

如果重要,这里是Mathematica中用于实现上述预处理的单行:

g = Closing[Binarize[GeodesicOpening[f, DiskMatrix[5]], Method -> "Entropy"], 1]

其中f是灰度输入图像,g是生成的二进制图像。

答案 2 :(得分:3)

问题非常广泛,取决于您想要达到的目标,有很多方法。您可以使用霍夫变换来检测硬币,因为它是圆的,但它可能会检测到许多圆形元素(因此它取决于您是否在视图中有其他类似的东西)。

更一般地说,您需要使用特征检测器(SURF,ORB,FAST,Shi-Tomassi),在具有硬币的参考框架和您正在寻找它的框架之间进行提取和匹配。然后,你可以使用Homography变换来确保你找到的点是相同的,因此你找到了你的硬币。

看一下这个例子:

Features2D + Homography to find a known object

答案 3 :(得分:3)

通常,您有以下步骤,这些更改可能会影响系统性能:

  1. 检测器及其配置
  2. 描述符及其配置
  3. 匹配器及其配置
  4. RANSAC参数(或您正在使用的任何参数)
  5. 您可以尝试MSER (maximally stable extremal region)作为探测器。众所周知,这种探测器找不到与SIFT / SURF等其他探测器一样多的关键点。但它们非常稳定和独特。但我会尝试不同的描述符进行匹配。也许是FREAK (Fast Retina Keypoint)

    使用RANSAC算法进行过滤应该可以,但您可以通过设置您喜欢的距离来调整。如果RANSAC不能正常工作,请尝试切换默认阈值,直到它看起来效果更好。

    你可以改变的另一件事是匹配器。 FLANN非常好,但只能近似结果,并且在高维空间中搜索时表现出色。但如果表现与你没关系,那么试试一下欧几里德或马哈拉诺比斯距离的BruteForceMatcher。

    [EDIT-1]: * 现在我想给你额外的帮助 - 你的建议=)* Kampel等人。在他们的文章“古代硬币的基于图像的检索和识别”中描述了一些额外的方法,为古钱币提供形状描述符,以增强项目的描述特征。

    另一个问题可能是RANSAC,这是一种消除异常值的非常严格的方法。 方法Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray() )具有其他参数(click this link)。您可以使用所有点,RANSAC或Least-Median稳健方法。

    或者您尝试进行稳健的计算,距离可能是检索良好匹配的良好阈值。标准教程使用最小找到距离的两倍,这是一个开始但不是非常强大,因为它取决于当前匹配的距离。

    标准OpenCV中不包含其他几种描述符/检测器。 Lindbjerg在他的论文“寻找最佳特征检测器 - 描述符组合”中描述了MSER使用DAISY-Descriptor进行的工作。或者您可以尝试AGASTBRISK。一个真正的大缺点是它们都不包含在标准的OpenCV发行版中。有一些实现,但你必须集成它们,这可能意味着很多工作。

答案 4 :(得分:1)

我相信最适合你的是某种版本的暴力搜索,类似于cvMatchTemplate所有基于特征提取的搜索都非常敏感;除非您有一些先验的理由知道某些类型的特征在所有感兴趣的图像中都会突出(例如:硬币的轮廓圆/椭圆),然后特征提取不太可能给您带来良好的性能。蛮力匹配的问题在于它对比例和旋转敏感。也许您可以查看文献中的无标度匹配,和/或蛮力可能的比例和旋转。对于您给出的示例图像,如果旋转几度并缩放几个百分点,它实际上会很好地匹配自己;你“只”需要几百个电话cvMatchTemplate才能找到一个旋转的缩放版本。