【问题标题】:OpenCV2 matchTemplate does not work on different pictures with same templateOpenCV2 matchTemplate 不适用于具有相同模板的不同图片
【发布时间】:2021-10-12 01:08:21
【问题描述】:

我正在使用 OpenCV2 来处理游戏的自动阻止功能,所以很简单: 如果特定区域中显示的红色指示器的 max_val 高于阈值,请按指定的键以阻止该攻击。

有一个带有透明背景的指标模板,它适用于少数屏幕截图,但不适用于大多数其他屏幕截图。

这是我正在使用的数据:

模板:

成功检测到的屏幕截图:

未能检测到的屏幕截图:

检测代码:

import time
import cv2
import pyautogui
import numpy as np


def block_left():
    # while True:
        # screenshot = pyautogui.screenshot(region=(960, 455, 300, 260))
        # region = cv2.imread(np.array(screenshot), cv2.IMREAD_UNCHANGED)
    region = cv2.imread('Screenshots/Left S 1.png', cv2.IMREAD_UNCHANGED)
    block = cv2.imread(r'Block Images/Left Block.png', cv2.IMREAD_UNCHANGED)
    matched = cv2.matchTemplate(region, block, cv2.TM_CCOEFF_NORMED)

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(matched)
    print(max_val)

    w = block.shape[1]
    h = block.shape[0]

    cv2.rectangle(region, max_loc, (max_loc[0] + w, max_loc[1] + h), (255, 0, 0), 2)

    cv2.imshow('Region', region)
    cv2.waitKey()


block_left()

因此,总而言之,我尝试了多种其他方法,但都显示出不太成功的结果。是否有任何过滤器,我可以添加任何处理来解决这个问题? 谢谢。

上传的图片是8位的,但是使用的图片是32位的,但是由于大小无法上传,使用的32位图片在这里上传:https://ibb.co/r7B7G6Bhttps://ibb.co/r0r9w5Thttps://ibb.co/KXP3wWc

【问题讨论】:

  • 您需要在模板中制作红色区域的遮罩,然后在 matchTemplate() 中使用遮罩。请参阅使用蒙版图像的文档。阅读模板图像,使其保留您的 Alpha 通道。然后提取alpha通道作为mask,提取alpha通道下的BGR图像。然后在 matchTemplate() 中使用 BGR 图像作为模板和掩码。
  • 我刚刚尝试制作了模板的掩码,将其添加到模板中并使用了它,但结果仍然相同,或者我可能犯了一个错误,因为我对 OpenCV 还比较陌生跨度>
  • 显示您的新代码以及您如何阅读模板并提取掩码和 matchTemplate 代码。
  • 试试 TM_SQDIFF 和 min_loc
  • 请注意,模板匹配既不是缩放不变的,也不是旋转不变的。对我来说,两张图片中红色形状的角度似乎略有不同。

标签: python python-3.x opencv image-processing opencv-python


【解决方案1】:

这是一个在 Python/OpenCV 中使用您的两个图像和带有 alpha 通道的模板进行蒙版模板匹配的示例。

图片1:

图 2:

模板:

import cv2
import numpy as np

# read  image
img = cv2.imread('game2.jpg')

# read template with alpha channel
template_with_alpha = cv2.imread('game_template.png', cv2.IMREAD_UNCHANGED)
hh, ww = template_with_alpha.shape[:2]

# extract base template image and alpha channel and make alpha 3 channels
template = template_with_alpha[:,:,0:3]
alpha = template_with_alpha[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])

# do masked template matching and save correlation image
correlation = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED, mask=alpha)

# get best match
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(correlation)
max_val_corr = '{:.6f}'.format(max_val)
print("correlation score: " + max_val_corr)
print("match location:", max_loc)

# draw match 
result = img.copy()
cv2.rectangle(result, (max_loc), ( max_loc[0]+ww,  max_loc[1]+hh), (0,0,255), 1)

# save results
cv2.imwrite('game2_matches.jpg', result)

cv2.imshow('template',template)
cv2.imshow('alpha',alpha)
cv2.imshow('result',result)
cv2.waitKey(0)
cv2.destroyAllWindows()

匹配图像 1:

correlation score: 0.983882
match location: (783, 512)

匹配图像 2:

correlation score: 0.938928
match location: (867, 504)

【讨论】:

  • 你明白我做了什么吗?
  • 请注意,您的模板与大图像中的红色大小不同,但在这些情况下足够接近。模板稍大。如果您有较大的比例变化,您可能需要进行多比例模板匹配。
  • 你明白我是如何在模板中阅读的,以便它具有 alpha 通道,然后将两者分开吗?然后在 matchTemplate() 中有一个掩码选项。这就是做掩码模板匹配的区别。
  • 作为一点解释,如果不使用遮罩,您的模板不会很好地匹配,因为透明部分下的图像是黑色的。因此,模板会尝试将大量黑色和少量红色与您的图像相匹配。这通常不存在,因为图像在红色区域周围有纹理。因此,将遮罩添加到 matchTemplate 允许它忽略图像中与您从 Alpha 通道中提取的遮罩中的黑色相对应的那些区域。
  • 使用 Numpy 切片完成。我用透明度读入图像。然后我只复制 BGR 通道 0、1、2。然后我将 alpha 通道从通道 3 复制到图像。
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 2019-02-02
  • 2016-12-12
  • 2020-04-13
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多