py-autogui/utils/cv2.py
2023-09-17 16:37:43 +08:00

78 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import imutils
import numpy as np
from PIL.Image import Image
import utils.matplotlib
def match_resize(src: Image, tmpl: str, similarity=0.9, step=10, fast=False):
src = cv2.cvtColor(np.asarray(src), cv2.COLOR_RGB2BGR)
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
tmpl = cv2.imread(tmpl)
tmpl_gray = cv2.cvtColor(tmpl, cv2.COLOR_BGR2GRAY)
found = None
tmp_r = 0
for scale in np.linspace(0.2, 2, step)[::-1]:
# 根据scale比例缩放图像并保持其宽高比
resized = imutils.resize(src_gray, width=int(src_gray.shape[1] * scale))
r = src_gray.shape[1] / float(resized.shape[1])
result = cv2.matchTemplate(resized, tmpl_gray, cv2.TM_CCOEFF_NORMED)
found_location = convert_location(result, tmpl_gray, similarity, r)
# 快速匹配, 如果缩放比例越大 相似度越低就直接退出循环 返回当前最佳结果
if fast:
if found is not None and found_location is not None:
print(found[2], found_location[2])
if tmp_r < r and found[2] > found_location[2] and found[2] >= similarity:
break
tmp_r = r
# 如果我们找到了一个新的最大校正值,更新簿记变量值
if found is None or (found_location is not None and found_location[2] > found[2]):
found = found_location
if found is not None and found[2] >= similarity:
break
if found is None:
return None
x, y, _ = found
print("x,y (%s, %s)" % (x, y))
return found[0], found[1]
def match(src: Image, tmpl: str, similarity=0.9):
# cv::TM_CCOEFF_NORMED = 5 标准相关匹配
method = cv2.TM_CCOEFF_NORMED
src = cv2.cvtColor(np.asarray(src), cv2.COLOR_RGB2BGR)
# 灰度图提高精度
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
tmpl = cv2.imread(tmpl)
tmpl_gray = cv2.cvtColor(tmpl, cv2.COLOR_BGR2GRAY)
# print('imagetempl.shape:', tmpl_gray.shape)
result = cv2.matchTemplate(src_gray, tmpl_gray, method)
print(result)
loc = convert_location(result, tmpl_gray, similarity)
if loc is None:
return
x, y, _ = loc
print("x,y (%s, %s)" % (x, y))
return x, y
def convert_location(result, tmpl, similarity, resize=1):
method = 5
min_max = cv2.minMaxLoc(result)
if method == 0 or method == 1: # 根据不同的模式最佳匹配位置取值方法不同
match_loc = min_max[2]
else:
match_loc = min_max[3]
right_bottom = (match_loc[0] + tmpl.shape[1], match_loc[1] + tmpl.shape[0])
# print('result.min_max:', min_max, 'method=', method)
# print('match_loc:', match_loc, type(match_loc))
# print('right_bottom', right_bottom, type(right_bottom))
x = int(match_loc[0] * resize) + int((right_bottom[0] - match_loc[0]) / 2 * resize)
y = int(match_loc[1] * resize) + int((right_bottom[1] - match_loc[1]) / 2 * resize)
print("(%s, %s) 缩放比例: %s, 相似度: %s" % (x, y, resize, min_max[1]))
if min_max[1] < similarity:
return None
return x, y, min_max[1]