#python #python-3.x #opencv #image-processing #opencv-python
Вопрос:
Я использую 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/r7B7G6B https://ibb.co/r0r9w5T https://ibb.co/KXP3wWc
Комментарии:
1. Вам нужно сделать маску красной области в вашем шаблоне, а затем использовать маску в matchTemplate(). См. Документацию по использованию изображения маски. Прочитайте изображение шаблона, чтобы оно сохранило ваш альфа-канал. Затем извлеките альфа-канал в виде маски и извлеките изображение BGR под альфа-каналом. Затем используйте изображение BGR в качестве шаблона и маски, как в matchTemplate().
2. Я просто попробовал и сделал маску шаблона, добавил ее в шаблон и использовал, но все равно получил те же результаты, или я мог ошибиться, так как я относительно новичок в OpenCV
3. Покажите свой новый код и то, как вы прочитали шаблон и извлекли маску, а также свой код соответствия.
4. Попробуйте TM_SQDIFF и min_loc
5. Имейте в виду, что соответствие шаблону не является ни масштабируемым, ни вращающимся инвариантом. Мне кажется, что угол красных фигур немного отличается на обоих изображениях.
Ответ №1:
Вот пример сопоставления замаскированных шаблонов в Python/OpenCV с использованием двух ваших изображений и шаблона с альфа-каналом.
Изображение 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)
Комментарии:
1. Ты понял, что я сделал?
2. Обратите внимание, что ваш шаблон не такого размера, как красный на больших изображениях, но в этих случаях достаточно близок. Шаблон немного больше. Если у вас есть изменения большего масштаба, вам, возможно, придется выполнить сопоставление шаблонов с несколькими масштабами.
3. Вы понимаете, как я прочитал в шаблоне, чтобы в нем был альфа-канал, а затем разделил их? Затем есть опция для маски в matchTemplate(). В этом и заключается разница в сопоставлении замаскированных шаблонов.
4. В качестве небольшого пояснения, ваш шаблон не очень хорошо подходит, если не используется маскировка, так как изображение под прозрачной частью черное. Таким образом, шаблон пытается подобрать много черного и немного красного к вашему изображению. Как правило, этого не существует, так как изображение имеет текстуру вокруг красной области. Таким образом, добавление маски в matchTemplate позволяет ей игнорировать те области изображения, которые соответствуют черному цвету в маске, извлеченной из альфа-канала.
5. Это делается с помощью нарезки Numpy. Я читаю на изображении с прозрачностью. Затем я копирую только каналы BGR 0,1,2. Затем я копирую альфа-канал на изображение с канала 3.