Используйте matchTemplate с цветными изображениями OpenCV - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь обнаружить определенные ЦВЕТНЫЕ изображения на скриншоте рабочего стола, где у меня есть шаблоны одинаковой формы, но разного цвета (они не отличаются друг от друга при обычном методе 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, как вы можете видеть в закомментированном коде.Однако это не сработало, и, несмотря на то, что в одноканальных изображениях было визуальное различие в цвете, программа не различала их (я также попытался провести сравнение с каждым отдельным каналом шаблона и снимка экрана).

Любые предложения приветствуются, даже если я пытаюсь достичь своей цели, используя что-то еще.Заранее спасибо.

1 Ответ

1 голос
/ 24 апреля 2019

Я попробовал это с методом 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, которые являются случайными и в моем тестеэто дает что-то вроде этого:

img:

enter image description here

цель:

enter image description here

Теперь я использовал сопоставление шаблона как есть, поскольку в документации сказано, что он может занять 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)

Это дает мне следующий результат:

enter image description here

Надеюсь, это поможет ... Мне нужно проверить метод, который вы используете в другой версии, чтобы увидетьесли это проблема в моей версии или что-то конкретное с этим набором изображений ...

...