如何在PyAutoGUI截图中匹配任意旋转缩放的PNG模板?
问题解决:带旋转/缩放的模板匹配及OpenCV深度不匹配修复
当前报错原因分析
你遇到的cv2.error: (-215:Assertion failed)错误,是因为截图和模板的图像类型/深度不匹配:
- 截图通过
COLOR_RGB2GRAY转成了单通道8位灰度图(CV_8U) - 模板处理过程中出现了类型混乱:先用
IMREAD_UNCHANGED读入带Alpha通道的4通道图,又转BGRA,再转灰度,但中间步骤可能导致类型异常,最终和截图的类型/深度不匹配。
修复当前深度不匹配的代码
先把基础的模板匹配代码修复,确保类型一致:
import cv2 import pyautogui import numpy as np # 读入模板:直接转灰度,忽略Alpha通道 objet_image = cv2.imread('traps/canon/Cannon1.png', cv2.IMREAD_GRAYSCALE) # 截取屏幕并转灰度 screenshot = pyautogui.screenshot() screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2GRAY) # 确保两者都是8位单通道灰度图 assert objet_image.dtype == np.uint8 and screenshot.dtype == np.uint8, "图像类型必须一致" assert len(objet_image.shape) == 2 and len(screenshot.shape) == 2, "必须是单通道灰度图" # 模板匹配 result = cv2.matchTemplate(screenshot, objet_image, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # 移动到匹配位置(注意:这里是模板左上角,如需中心要加模板尺寸的一半) template_h, template_w = objet_image.shape center_x = max_loc[0] + template_w // 2 center_y = max_loc[1] + template_h // 2 pyautogui.moveTo(center_x, center_y)
解决旋转/缩放的模板匹配问题
OpenCV的matchTemplate只支持同尺寸、无旋转的匹配,针对你需要的任意2D旋转+尺寸变化的场景,推荐用特征点匹配(比如ORB算法),代码示例:
import cv2 import pyautogui import numpy as np def detect_template_with_transform(screenshot_gray, template_gray, threshold=0.7): # 初始化ORB特征检测器 orb = cv2.ORB_create(500) kp1, des1 = orb.detectAndCompute(template_gray, None) kp2, des2 = orb.detectAndCompute(screenshot_gray, None) # 暴力匹配 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(des1, des2) matches = sorted(matches, key=lambda x: x.distance) # 筛选匹配点 good_matches = matches[:int(len(matches)*threshold)] if len(good_matches) < 4: return None # 匹配点太少,无法计算变换 # 获取匹配点坐标 src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1,1,2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1,1,2) # 计算透视变换矩阵 M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) h, w = template_gray.shape pts = np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts, M) # 返回模板在截图中的四个角坐标(可用来计算中心) return dst # 主流程 template_gray = cv2.imread('traps/canon/Cannon1.png', cv2.IMREAD_GRAYSCALE) screenshot = pyautogui.screenshot() screenshot_gray = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2GRAY) template_location = detect_template_with_transform(screenshot_gray, template_gray) if template_location is not None: # 计算中心坐标 center_x = np.mean(template_location[:,:,0]) center_y = np.mean(template_location[:,:,1]) pyautogui.moveTo(center_x, center_y) else: print("未检测到模板")
批量处理44张模板的建议
如果要批量检测44张模板,可以把模板提前加载成灰度图列表,循环调用上述特征匹配函数,一旦检测到匹配就停止或记录结果。
内容的提问来源于stack exchange,提问作者Yeesou
相关产品推荐
相关产品推荐

