| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """
- 测试 image-match:用模板图生成合成截图(模拟手机屏中缩略图),再跑匹配并校验中心点。
- 用法: python test_img_match.py <template_path> [screenshot_path]
- - 仅 template_path: 用模板生成合成截图再匹配(用于验证流程与 RoMa 参数)
- - template_path + screenshot_path: 用真实截图与模板匹配(用于实机调试)
- 输出: 打印 JSON 结果及期望中心点(合成时),成功时退出码 0。
- """
- import os
- import sys
- import json
- import tempfile
- import subprocess
- # 项目根目录
- SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
- PROJECT_ROOT = os.path.dirname(os.path.dirname(SCRIPT_DIR))
- IMAGE_MATCH = os.path.join(SCRIPT_DIR, "image-match.py")
- def load_image_cv(path):
- import cv2
- import numpy as np
- with open(path, "rb") as f:
- data = np.frombuffer(f.read(), dtype=np.uint8)
- img = cv2.imdecode(data, cv2.IMREAD_COLOR)
- if img is not None:
- return img
- return cv2.imread(path)
- def make_synthetic_screenshot(template_path, scale=0.45, offset_x=100, offset_y=350, screen_w=1080, screen_h=2340):
- """用模板图生成一张合成截图:黑色背景,模板缩放后贴在 (offset_x, offset_y)。"""
- import cv2
- import numpy as np
- tpl = load_image_cv(template_path)
- if tpl is None:
- raise FileNotFoundError(f"无法读取模板: {template_path}")
- h, w = tpl.shape[:2]
- new_w = int(round(w * scale))
- new_h = int(round(h * scale))
- small = cv2.resize(tpl, (new_w, new_h), interpolation=cv2.INTER_AREA)
- screen = np.zeros((screen_h, screen_w, 3), dtype=np.uint8)
- screen[:] = (30, 30, 30) # 深灰模拟界面
- x1, y1 = offset_x, offset_y
- x2, y2 = min(offset_x + new_w, screen_w), min(offset_y + new_h, screen_h)
- sx2 = x2 - x1
- sy2 = y2 - y1
- screen[y1:y1 + sy2, x1:x1 + sx2] = small[:sy2, :sx2]
- expect_cx = offset_x + new_w // 2
- expect_cy = offset_y + new_h // 2
- return screen, (expect_cx, expect_cy, offset_x, offset_y, new_w, new_h)
- def run_match(screenshot_path, template_path, method="feature"):
- py = os.environ.get("PYTHON", "python")
- cmd = [py, IMAGE_MATCH, screenshot_path, template_path, "0.8", method]
- r = subprocess.run(cmd, capture_output=True, text=True, timeout=60, cwd=PROJECT_ROOT)
- out = (r.stdout or "").strip()
- err = (r.stderr or "").strip()
- if r.returncode != 0 and out:
- try:
- return json.loads(out)
- except json.JSONDecodeError:
- pass
- if out:
- try:
- return json.loads(out)
- except json.JSONDecodeError:
- pass
- return {"success": False, "error": err or out or "unknown error", "returncode": r.returncode}
- def main():
- if len(sys.argv) < 2:
- print("用法: python test_img_match.py <template_path> [screenshot_path]")
- sys.exit(2)
- template_path = os.path.abspath(sys.argv[1])
- if not os.path.exists(template_path):
- print(json.dumps({"success": False, "error": f"模板不存在: {template_path}"}))
- sys.exit(1)
- screenshot_path = sys.argv[2] if len(sys.argv) > 2 else None
- expect_center = None
- if screenshot_path is None:
- # 合成截图
- screenshot_path = os.path.join(tempfile.gettempdir(), "ef_test_screenshot.png")
- screen, (expect_cx, expect_cy, ox, oy, nw, nh) = make_synthetic_screenshot(
- template_path, scale=0.45, offset_x=100, offset_y=350
- )
- import cv2
- cv2.imwrite(screenshot_path, screen)
- expect_center = (expect_cx, expect_cy)
- print("合成截图已生成:", screenshot_path, "期望中心:", expect_center, file=sys.stderr)
- result = run_match(screenshot_path, template_path)
- print(json.dumps(result, ensure_ascii=False, indent=2))
- if expect_center and result.get("success"):
- cx, cy = result.get("center_x"), result.get("center_y")
- ex, ey = expect_center
- tol = 25
- if abs(cx - ex) <= tol and abs(cy - ey) <= tol:
- print("中心点与期望一致 (容差 %d px)" % tol, file=sys.stderr)
- else:
- print("中心点与期望偏差: 得到 (%d,%d) 期望 (%d,%d)" % (cx, cy, ex, ey), file=sys.stderr)
- if not result.get("success"):
- sys.exit(1)
- sys.exit(0)
- if __name__ == "__main__":
- main()
|