【问题标题】:opencv: negative result of matchTemplate with CCOEFF_NORMEDopencv:带有 CCOEFF_NORMED 的 matchTemplate 的否定结果
【发布时间】:2019-03-05 18:08:19
【问题描述】:

我得到了几个应用程序图标并将大小调整为 36*36。我希望在他们中的任何两个之间获得相似性。我用 opencv 函数threshold 将它们变成了黑白的。我遵循其他问题的指示。我在两个图标上应用matchTemplateTM_CCOEFF_NORMED 方法但得到否定结果,这让我感到困惑。 基于doc,结果数组中不应有任何负数。谁能向我解释为什么我得到一个负数,这个负数有意义吗?

即使我从编辑中删除了所有代码部分,我也因尝试编辑帖子而出现代码缩进错误而失败了一小时。太疯狂了。我已经尝试过图标的灰度和黑白。当两个图标完全不同时,我总是会得到否定的结果。

如果我使用大小为 48*48 的原始图标,一切顺利。不知道是不是和我的resize step有关。

#read in pics
im1 = cv2.imread('./app_icon/pacrdt1.png')
im1g = cv2.resize(cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
im2 = cv2.imread('./app_icon/pacrdt2.png')
im2g = cv2.resize(cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
im3 = cv2.imread('./app_icon/mny.png')
im3g = cv2.resize(cv2.cvtColor(im3, cv2.COLOR_BGR2GRAY), (36, 36), cv2.INTER_CUBIC)
#black&white convert
(thresh1, bw1) = cv2.threshold(im1g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
(thresh3, bw3) = cv2.threshold(im3g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
(thresh2, bw2) = cv2.threshold(im2g, 128 , 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#match template
templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED)[0][0]
templ_diff = 1 - templ_match


示例:


edit2:我将具有不同背景颜色或字体颜色的图标定义为非常相似的图标(但查看者会知道它们与我的示例中的图像 1 和 2 完全相同)。这就是为什么我将图标图片输入为黑白的原因。希望这是有道理的。

【问题讨论】:

  • 能否请您发布您的代码和示例图片
  • 为什么要转换成黑白图像?尝试对灰度图像进行相同操作。
  • @JeruLuke 实际上我已经尝试过灰度和黑白。我仍然会得到否定的结果。
  • @G_cy 你能分享一些示例图片吗?
  • @JeruLuke 感谢您的帮助。我添加了一些示例。我能知道你是如何编辑帖子的吗?即使我可以得到正确的预览,我也会不断出错。谢谢

标签: opencv python-3.6 opencv3.1


【解决方案1】:

出现此问题是因为两个图像的大小相同。

我尝试了相同的方法,但使用了不同的图像尺寸。我以前经常关注图片:

图片 1:(125 x 108 像素)图片

图片 2:(48 x 48 像素)模板

当我为这些图像运行给定代码时,它返回一个包含值的数组,其中每个值对应于某个像素周围的(图像)区域与模板(模板)匹配的程度。

现在,当您执行 cv2.minMaxLoc(templ_match) 时,它会返回 4 个值:

  1. 最小值:与模板相比,图像中匹配最少的像素
  2. 最大值:与模板相比,图像中匹配最多的像素
  3. minimum_location:最小值出现的位置
  4. maximum_location:最大值出现的位置

这是我得到的:

Out[32]: (-0.15977318584918976, 1.0, (40, 12), (37, 32))
                    ^            ^       ^         ^
                    |            |       |         |
                min_val       max_val  min_loc   max_loc  

当图像和模板的大小不同时会观察到此结果。在您的情况下,您已将所有图像的大小调整为相同的大小,结果您只得到一个值,即templ_match 的第一个值。此外,你必须避免这样做templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED)[0][0]

而是执行templ_match = cv2.matchTemplate(im1g, im3g, cv2.TM_CCOEFF_NORMED),然后使用:cv2.minMaxLoc(templ_match) 获取最大值和最小值以及它们的位置

【讨论】:

  • 如果是小图标引起的问题,是否意味着我需要将我的图标调整为不同的大小。因为在真正的项目中,所有给出的图标都将是相同的大小。负 min_val 对你意味着什么?还有一个,我能知道为什么我们必须避免这样做吗?这实际上来自这个答案:stackoverflow.com/a/45485883/3330229
  • 当您对具有相同大小的图像执行此操作时,min_val 和 max_val 将与 (0.5552718639373779, 0.5552718639373779, (0, 0), (0, 0)) 相同。 min_val 表示与其他图像相比最不相似(或高度不同)的值。
  • 我可以认为问题不会总是发生在相同尺寸的图片上吗?在我尝试将图片大小调整为 32*32 之后,返回值似乎不是负数。
  • 您可以考虑相同大小的图像,但它们只会返回一个值。如果图像几乎相似/相同,它将接近 1。但如果图像不同,它们将接近 0。有点相似的图像将具有介于 0 和 1 之间的某个值。
  • 我一直认为这个函数的返回值应该在0到1之间,来自上面的doc链接。作为 cv 的新手,我对这个函数产生的负值感到非常困惑。我真诚地希望知道如何在这里解释或理解这种情况。它只是由两个输入图像的相同大小引起的吗?抱歉重复,感谢您的耐心。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 2012-11-04
  • 2015-12-20
  • 2016-06-09
  • 2016-08-20
  • 1970-01-01
  • 2015-10-12
相关资源
最近更新 更多