裁剪模板区域后,如何换算matchTemplate返回的x/y坐标匹配实际屏幕位置?
问题根源
你对截图做裁剪后,Vision.find()返回的坐标是相对于裁剪后图片左上角的相对坐标,而非真实屏幕坐标,直接传给pyautogui自然会出现偏移。你之前修改border_pixels和titlebar_pixels参数不生效,是因为没有同步更新坐标偏移的计算逻辑。
解决方案1:直接修改调用逻辑(无需改动现有类)
只需要在拿到匹配点后,叠加裁剪对应的坐标偏移即可,修改后的调用代码如下:
import cv2 as cv import pyautogui as py from windowcapture import WindowCapture from vision import Vision # 初始化窗口捕获类,捕获全屏 haystack = WindowCapture() # 初始化模板匹配类 needle = Vision('needle.jpg') # 提前定义裁剪参数,避免硬编码 CROP_Y_START = 220 CROP_Y_END = 900 CROP_X_START = 270 CROP_X_END = 1590 while(True): # 获取全屏截图(注意修复原代码笔误,之前初始化的是haystack,调用写了template) screenshot = haystack.get_screenshot() # 裁剪目标区域 screenshotCropped = screenshot[CROP_Y_START:CROP_Y_END, CROP_X_START:CROP_X_END] # 模板匹配获取裁剪图内的相对坐标 points = needle.find(screenshotCropped, 0.85, 'points') if points: # 坐标转换:裁剪图相对坐标 + 裁剪偏移 + 窗口全局偏移 = 真实屏幕坐标 real_x = points[0][0] + CROP_X_START + haystack.offset_x real_y = points[0][1] + CROP_Y_START + haystack.offset_y py.moveTo(real_x, real_y)
解决方案2:内置裁剪到WindowCapture类(代码更整洁)
修改WindowCapture类的构造方法,增加裁剪参数,直接在捕获阶段完成裁剪,后续不需要额外做坐标转换:
第一步:修改WindowCapture类的__init__方法
def __init__(self, window_name=None, crop=None): # 原有逻辑保持不变,直到offset计算完成后,新增以下裁剪处理逻辑 self.offset_x = window_rect[0] + self.cropped_x self.offset_y = window_rect[1] + self.cropped_y # 新增裁剪逻辑 if crop is not None: # crop参数格式:(裁剪起始x, 裁剪起始y, 裁剪结束x, 裁剪结束y) crop_x_start, crop_y_start, crop_x_end, crop_y_end = crop # 调整宽高为裁剪后的尺寸 self.w = crop_x_end - crop_x_start self.h = crop_y_end - crop_y_start # 更新截图捕获的偏移,直接捕获裁剪区域 self.cropped_x += crop_x_start self.cropped_y += crop_y_start # 更新全局坐标偏移,后续匹配返回的坐标直接对应真实屏幕位置 self.offset_x += crop_x_start self.offset_y += crop_y_start
第二步:初始化时传入裁剪参数
# 传入你需要的裁剪范围即可,不需要再手动裁剪截图 haystack = WindowCapture(crop=(270, 220, 1590, 900)) needle = Vision('needle.jpg') while(True): screenshot = haystack.get_screenshot() points = needle.find(screenshot, 0.85, 'points') if points: # 不需要额外转换坐标,直接使用即可 py.moveTo(points[0])
内容的提问来源于stack exchange,提问作者Stevphen
相关产品推荐
相关产品推荐

