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]