OpenCV:比较简单图像与小差异

时间:2012-06-02 21:42:32

标签: opencv

我有一堆“简单”的图像,我想比较它们是否相似。我使用模板匹配(cv::matchTemplate)将它们相互比较,结果非常好。

现在我想微调我的程序,我遇到了问题。例如,我有两个看起来非常相似的图像。只有它们之间的区别在于另一个具有较粗的线条并且项目的数字前端不同。当两个图像都很小时,线条厚度的一个像素差异在进行模板匹配时会产生很大的结果差异。当线条厚度相同且前面的数字只有差异时,我会在匹配成功时获得模板匹配结果,如0.98CV_TM_CCORR_NORMED。当线条厚度不同时,匹配结果类似于0.95。

我无法将阈值降低到0.98以下,因为其他一些类似的图像具有相同的线条粗细。

以下是示例图片:

enter image description here enter image description here

那么我有什么选择?

我试过了:

  • 扩展原始和模板
  • 同时侵蚀
  • physicsEx both
  • 计算关键点并进行比较
  • 寻找角落

但尚无大的成功。那些图像太简单了,检测“好的功能”很难吗?

任何帮助都非常好。

谢谢!

修改

以下是其他一些示例图片。我的程序认为类似的东西放在相同的zip文件夹中。 ZIP

3 个答案:

答案 0 :(得分:3)

一种可能的方法可能是使两个图像变薄,这样每条线都有一个像素宽度,因为不同的厚度会导致相似的主要问题。

程序将首先对图像进行二值化/阈值处理,然后对两个图像应用细化操作,因此两者现在具有相同的1 px厚度。然后使用您之前使用的常用模板匹配,并获得良好的结果。

如果您想了解有关二进制图像细化/骨架化的更多详细信息,请参阅各种论坛和OpenCV小组​​发布的一些OpenCV实现:

  1. OpenCV code for thinning(郭和霍尔算法,与CvMat输入一起工作)
  2. The JR Parker implementation使用OpenCV
  3. 可能更有效的代码here(使用OpenCV优化的访问方法很多,但是大部分页面都是日语!)
  4. 最后是brief overview of thinning以防你感兴趣。

答案 1 :(得分:2)

你需要一些更基本的东西,没有太多理由去寻找花哨的方法。你的数字已经是二元数字,它们的形状总体上非常相似。

一个初步想法:考虑某个图像中的上部点和底部点,形成一个上部船体和一个底部船体(简单地是一个船体,而不是一个凸包或其他任何东西)。如果给定列i,则该点被称为高点(respec。底点),它是从图像顶部(底部)开始的第一个点,而不是{{i中的背景点。 1}}。此外,您的图像大多是一个连接的组件(在某些情况下,垂直条分开,但这很好),因此您可以轻松地丢弃小组件。这一步对您的情况非常重要,因为我看到有些图形具有与图像其余部分无关的某种形式的噪声。考虑到小于100点的连通组件很小,这些是您在问题中包含的相应图像所获得的船体:

enter image description here

enter image description here

蓝线表示上部船体,绿线表示底部船体。如果不明显,当我们考虑这些船体的区域最大值和区域最小值时,我们在两者中获得相同的量。此外,它们都非常接近,除了y轴上的一些位移。如果我们考虑极值的平均x位置并将两个图像的线条绘制在一起,我们得到下图。在这种情况下,蓝色和绿色的线条用于第二个图像,而线条用红色和青色用于第一个图像。红点位于某些区域最小值的平均x坐标中,蓝点相同但区域最大值(这些是我们感兴趣的点)。 (已调整以下图像的大小以获得更好的可视化效果)

enter image description here

正如你所看到的,你没有做任何事情就会得到许多几乎重叠的点。如果我们做得更少,即使不关心这种重叠,并继续以琐碎的方式对图像进行分类:如果图像a和另一图像b具有相同数量的区域最大值上部船体,上部船体中相同数量的区域最小值,底部船体中相同数量的区域最大值,以及底部船体中相同数量的区域最小值,然后ab属于到同一个班级。对所有图像执行此操作后,除以下情况外,所有图像都会正确分组:

enter image description here

enter image description here

在这种情况下,我们在第一张图像中只有3个最大值和3个最小值用于上部船体,而第二个图像中有4个最大值和4个最小值。下面你看到了船体和兴趣点的图:

enter image description here enter image description here

你可以注意到,在第二个上部船体中有两个非常接近的极值。平滑此曲线消除了两个极值,使图像与平凡的方法匹配。另外,请注意,如果在图像周围绘制一个矩形,则此方法将告诉它们全部相等。在这种情况下,您需要比较多个船体,丢弃当前船体中的点并构建其他船体。尽管如此,这种方法能够正确地对所有图像进行分组,因为它们非常简单且大部分都是无噪声的。

答案 2 :(得分:1)

从我能得到的,难度是形状相同,只是尺寸不同。一个简单的黑客方法可能是: - 减去图像,然后腐蚀。如果形状相同但稍大一些,减去将仅留下边缘,这将是一个消失的薄的消失。

更正式的是采取轮廓然后是近似多边形并进行不变量比较(Hu Moments等。)