Ahmed Elsisi
Ahmed Elsisi

Reputation: 88

OpenCV2 matchTemplate does not work on different pictures with same template

I am using OpenCV2 to work on an auto-block function for a game, so simply: If the red indicator that shows up in a specific region has a max_val higher than threshold, press the key specified to block that attack.

There is a template of the indicator with a transparent background, it works on few screenshots but not most of the others, however.

Here is the data I'm using:

Template:

Left Block

Screenshot where it successfully detects: enter image description here

Screenshot where it fails to detect: enter image description here

Code to detect:

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()

So, in conclusion, I have tried multiple other methods but all have shown less successful outcomes. Are there any filters, any processing that I can add in order to fix this? Thank you.

Images uploaded are in 8-bit, however images used are 32-bit, but couldn't upload due to size, 32-bit images used are uploaded here: https://ibb.co/r7B7G6B https://ibb.co/r0r9w5T https://ibb.co/KXP3wWc

Upvotes: 0

Views: 1104

Answers (1)

fmw42
fmw42

Reputation: 53089

Here is an example of masked template matching in Python/OpenCV using your two images and template with alpha channel.

Image 1:

enter image description here

Image 2:

enter image description here

Template:

enter image description here

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()

Match for Image 1:

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

enter image description here

Match for Image 2:

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

enter image description here

Upvotes: 2

Related Questions