如何提升OpenCV模板匹配性能并解决ROI匹配后坐标偏移问题
解决方案
1. 匹配坐标偏移修复
问题原因
你在tmcheck子区域内执行模板匹配,得到的x/y坐标是相对于tmcheck区域左上角的相对坐标,直接绘制到完整窗口的img上时,没有叠加两个区域的相对偏移量,所以位置错位。
修复步骤
首先提前计算tmcheck相对于完整捕获区域mon的偏移值,绘制矩形前把偏移量加上即可,同时你还可以优化截屏逻辑,避免重复两次调用屏幕捕获,提升FPS:
import time import cv2 import mss import numpy as np from templates import death_img, defeat_img, exit_img, start_img, zero_img, death_h, death_w, defeat_h, defeat_w, exit_h, exit_w, start_w, start_h, zero_w, zero_h with mss.mss() as sct: # 捕获区域配置 tmcheck = {"top": 100, "left": 37, "width": 409, "height": 76} mon = {"top": 35, "left": 2, "width": 480, "height": 270} # 提前计算固定偏移量,不用每次循环重复计算 x_offset = tmcheck["left"] - mon["left"] y_offset = tmcheck["top"] - mon["top"] while "Screen capturing": last_time = time.time() # 只捕获一次完整窗口 img = np.array(sct.grab(mon)) # 直接从完整截图中切出匹配子区域,省去一次屏幕捕获 tm = img[y_offset:y_offset+tmcheck["height"], x_offset:x_offset+tmcheck["width"]] threshold = .60 result = cv2.matchTemplate(tm, zero_img, cv2.TM_CCOEFF_NORMED) yloc, xloc = np.where(result >= threshold) rectangles = [] for (x, y) in zip(xloc, yloc): rectangles.append([int(x), int(y), int(zero_w), int(zero_h)]) rectangles.append([int(x), int(y), int(zero_w), int(zero_h)]) rectangles, weights = cv2.groupRectangles(rectangles, 1, 0.2) for (x, y, zero_w, zero_h) in rectangles: # 叠加偏移量得到完整窗口中的真实坐标 real_x = x + x_offset real_y = y + y_offset img = cv2.rectangle(img, (real_x, real_y), (real_x + zero_w, real_y + zero_h), (0,255,255), 2) print(rectangles) # 展示画面 cv2.imshow("AI Eyes", img) print("fps: {}".format(1 / (time.time() - last_time))) # 按q退出 if cv2.waitKey(25) & 0xFF == ord("q"): cv2.destroyAllWindows() break
2. 模板导入优化方案
你可以把templates.py改造为统一的字典结构管理所有模板,无需逐个导出导入:
第一步:改造templates.py
# templates.py 示例代码 import cv2 # 封装模板加载逻辑,自动读取宽高 def load_template(file_path): tpl_img = cv2.imread(file_path, cv2.IMREAD_UNCHANGED) h, w = tpl_img.shape[:2] return { "img": tpl_img, "w": w, "h": h } # 所有模板统一放在字典里管理 TEMPLATES = { "death": load_template("death模板的文件路径.png"), "defeat": load_template("defeat模板的文件路径.png"), "exit": load_template("exit模板的文件路径.png"), "start": load_template("start模板的文件路径.png"), "zero": load_template("zero模板的文件路径.png"), }
第二步:简化主代码导入
原来的多行导入可以直接简化为1行:
from templates import TEMPLATES
使用时直接从字典中取对应模板即可,比如调用zero模板:
zero_tpl = TEMPLATES["zero"] # 模板图:zero_tpl["img"] # 模板宽:zero_tpl["w"] # 模板高:zero_tpl["h"]
后续新增模板只需要在TEMPLATES字典中添加条目即可,不需要修改导入语句,维护成本更低。
内容的提问来源于stack exchange,提问作者Nilaier
相关产品推荐
相关产品推荐

