opencv:具有CCOEFF_NORMED的matchTemplate的否定结果

时间:2018-06-19 17:24:22

标签: opencv python-3.6 opencv3.1

我得到了几个应用程序图标,并调整为36 * 36。我希望它们中的任何两个都相似。我已经使用opencv函数threshold使它们成为黑色和白色。我遵循其他问题的指导。我在两个图标上应用了matchTemplate和方法TM_CCOEFF_NORMED,但是得到了否定的结果,这让我感到困惑。 基于doc,结果数组中不应有任何负数。谁能向我解释为什么我得到一个负数,这个负数有意义吗?

enter image description here

即使我从编辑中删除了所有代码部分,也无法在一小时内尝试编辑带有代码缩进错误的帖子。太疯狂了。我尝试了灰度和黑白图标。当两个图标完全不同时,我将始终得到负面结果。

如果我使用尺寸为48 * 48的原始图标,一切将会顺利进行。我不知道这是否与我的调整大小步骤有关。

#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


样本:

enter image description here

enter image description here

enter image description here


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

1 个答案:

答案 0 :(得分:0)

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

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

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

enter image description here

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

enter image description here

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

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

  1. 最小值:与模板相比,图像中匹配最少的像素
  2. 最大值:与模板相比,图像中匹配度最高的像素
  3. 最小位置:最小值的出现位置
  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)

获得最大值和最小值及其位置。