1

我正在尝试在桌面屏幕截图中检测某些彩色图像,其中我有形状相同但颜色不同的模板(这些模板在使用正常的 matchTemplate 方法时并没有区别,因为它是用灰度图像完成的)这是主要的代码检测:

     template = cv2.imread(template_path,1)
    #template_hsv = cv2.cvtColor(template, cv2.COLOR_RGB2HSV)
    #template_B, template_G, template_R = cv2.split(template)
    #scr_B, scr_G, scr_R = cv2.split(screenshot)
    scr_B = screenshot[:, :, 0]
    scr_G = screenshot[:, :, 1]
    scr_R = screenshot[:, :, 2]
    template_B = template[:, :, 0]
    template_G = template[:, :, 1]
    template_R = template[:, :, 2]
    #cv2.imwrite('./sc4.png', scr_R)
    #cv2.imwrite('./template.png', template)

    resB = cv2.matchTemplate(scr_B, template_B, cv2.TM_CCOEFF_NORMED)
    resG = cv2.matchTemplate(scr_G, template_G, cv2.TM_CCOEFF_NORMED)
    resR = cv2.matchTemplate(scr_R, template_R, cv2.TM_CCOEFF_NORMED)

    res = resB + resG + resR

    #res = cv2.matchTemplate(screenshot, template_G, cv2.TM_CCOEFF_NORMED)
    matches = np.where(res >= 3*threshold)
    print(matches)
    return matches

如您所见,我尝试拆分 rgb 屏幕截图图像的通道,然后与同样拆分的模板图像进行比较。正如您在注释代码中看到的那样,我还尝试使用 HSV 通道执行此操作。然而这并没有奏效,尽管看到在单通道图像中存在颜色的视觉差异,但程序没有区分它们(我还尝试与模板和屏幕截图的每个单独通道进行比较)。

欢迎所有建议,甚至尝试使用其他任何方法来实现我的目标。先感谢您。

4

1 回答 1

2

我用TM_CCOEFF_NORMED方法尝试过,但没有用......不知何故,它把所有东西都给了 1.0(所有最大值)......但是用这个TM_SQDIFF_NORMED方法实际上给出了一些合理的东西。

让我们从创建一个示例图像开始,我这样做如下:

import numpy as np
import cv2

randVal = lambda : np.random.randint(0,high=255, dtype=np.uint8)
randomColor = lambda : (randVal(), randVal(), randVal())
targetColor = randomColor()

width = 500
height = 500
x = 20
y = 20
img = np.zeros((height, width,3), dtype=np.uint8)
target = np.full((100, 100,3), targetColor, dtype=np.uint8)
while y < height-100:
  x  = 20
  while x < width-100:
    img[y:y+100, x:x+100] = randomColor()
    x += 120
  y += 120

img[20:120, 20:120] = targetColor

这将创建 2 个图像,img它们target都是随机的,在我的测试中它给出了如下内容:

图像:

在此处输入图像描述

目标:

在此处输入图像描述

现在,我按原样使用模板匹配,因为在文档中说它可能需要 1 或 3 个通道并且它会正确执行,但使用另一种方法

res = cv2.matchTemplate(img[:,:,0], target[:,:,0], cv2.TM_SQDIFF_NORMED )
threshold = 0.00001
loc = np.where( res <= threshold )
img_rgb = img.copy()
for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + 100, pt[1] + 100), (0,0,255), 2)

这给了我以下结果:

在此处输入图像描述

我希望这会有所帮助...我需要测试您在另一个版本中使用的方法,看看它是否是我的版本中的问题或者是这组图像的特定问题...

于 2019-04-24T12:51:23.660 回答