|
|
@@ -93,9 +93,10 @@ def _numpy_bgr_to_torch_rgb(img_bgr):
|
|
|
return torch.from_numpy(t).float().div(255.0)
|
|
|
|
|
|
|
|
|
-def match_by_lightglue(screenshot, template, min_matches=8, device='cpu'):
|
|
|
+def match_by_lightglue(screenshot, template, min_matches=6, device='cpu'):
|
|
|
"""
|
|
|
使用 LightGlue + SuperPoint 做特征匹配,在截图中找模板位置。
|
|
|
+ 参数已调优以提高难图(如缩略图)匹配率:更多特征点、关闭裁剪/早停、放宽匹配与 RANSAC。
|
|
|
返回 (x, y, w, h, center_x, center_y) 或 None。
|
|
|
"""
|
|
|
if not HAS_LIGHTGLUE:
|
|
|
@@ -104,8 +105,13 @@ def match_by_lightglue(screenshot, template, min_matches=8, device='cpu'):
|
|
|
try:
|
|
|
img0 = _numpy_bgr_to_torch_rgb(screenshot)
|
|
|
img1 = _numpy_bgr_to_torch_rgb(template)
|
|
|
- extractor = SuperPoint(max_num_keypoints=2048).eval().to(device)
|
|
|
- matcher = LightGlue(features='superpoint').eval().to(device)
|
|
|
+ extractor = SuperPoint(max_num_keypoints=4096).eval().to(device)
|
|
|
+ matcher = LightGlue(
|
|
|
+ features='superpoint',
|
|
|
+ depth_confidence=-1,
|
|
|
+ width_confidence=-1,
|
|
|
+ filter_threshold=0.05,
|
|
|
+ ).eval().to(device)
|
|
|
feats0, feats1, matches01 = match_pair(extractor, matcher, img0, img1, device=device)
|
|
|
matches = matches01.get('matches')
|
|
|
if matches is None or matches.shape[0] < min_matches:
|
|
|
@@ -116,7 +122,7 @@ def match_by_lightglue(screenshot, template, min_matches=8, device='cpu'):
|
|
|
idx1 = matches[:, 1]
|
|
|
pts_screen = kp0[idx0].cpu().numpy().astype(np.float32)
|
|
|
pts_template = kp1[idx1].cpu().numpy().astype(np.float32)
|
|
|
- H, mask = cv2.findHomography(pts_template, pts_screen, cv2.RANSAC, 5.0)
|
|
|
+ H, mask = cv2.findHomography(pts_template, pts_screen, cv2.RANSAC, 8.0)
|
|
|
if H is None:
|
|
|
return None
|
|
|
corners = np.float32([[0, 0], [t_w, 0], [t_w, t_h], [0, t_h]]).reshape(-1, 1, 2)
|
|
|
@@ -180,9 +186,10 @@ def match_by_features(screenshot, template, min_good_matches=8):
|
|
|
return (x, y, w, h, center_x, center_y)
|
|
|
|
|
|
|
|
|
-def multi_scale_template_match(screenshot, template, threshold=0.65):
|
|
|
+def multi_scale_template_match(screenshot, template, threshold=0.65, scale_min=0.4, scale_max=1.65):
|
|
|
"""
|
|
|
多尺度模板匹配:对模板做多种缩放后在截图中匹配,适配不同分辨率(如简单图标、轮廓)。
|
|
|
+ scale_min, scale_max: 缩放比范围,如 0.2~1.6 可匹配缩略图。
|
|
|
返回 (x, y, w, h, center_x, center_y) 或 None。
|
|
|
"""
|
|
|
gray_screen = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
|
|
|
@@ -191,8 +198,8 @@ def multi_scale_template_match(screenshot, template, threshold=0.65):
|
|
|
t_h, t_w = template.shape[:2]
|
|
|
best = None
|
|
|
best_val = threshold
|
|
|
- # 从 0.4 到 1.6 倍缩放,步长约 0.15,保证缩放后不超出截图
|
|
|
- for scale in np.arange(0.4, 1.65, 0.12):
|
|
|
+ step = max(0.05, (scale_max - scale_min) / 12.0)
|
|
|
+ for scale in np.arange(scale_min, scale_max + step * 0.5, step):
|
|
|
w = max(8, int(round(t_w * scale)))
|
|
|
h = max(8, int(round(t_h * scale)))
|
|
|
if h > sh or w > sw:
|
|
|
@@ -216,9 +223,10 @@ def main():
|
|
|
method = 'feature' # feature=特征点匹配(跨分辨率), template=像素模板匹配
|
|
|
adb_path = None
|
|
|
device = None
|
|
|
+ scale_min, scale_max = 0.4, 1.65
|
|
|
|
|
|
if len(sys.argv) >= 2 and sys.argv[1] == '--adb':
|
|
|
- # 用法2:--adb --device --screenshot --template
|
|
|
+ # 用法2:--adb --device --screenshot --template [--scale-min 0.2] [--scale-max 1.6]
|
|
|
i = 1
|
|
|
while i < len(sys.argv):
|
|
|
if sys.argv[i] == '--adb' and i + 1 < len(sys.argv):
|
|
|
@@ -241,6 +249,12 @@ def main():
|
|
|
if method not in ('template', 'feature'):
|
|
|
method = 'feature'
|
|
|
i += 2
|
|
|
+ elif sys.argv[i] == '--scale-min' and i + 1 < len(sys.argv):
|
|
|
+ scale_min = float(sys.argv[i + 1])
|
|
|
+ i += 2
|
|
|
+ elif sys.argv[i] == '--scale-max' and i + 1 < len(sys.argv):
|
|
|
+ scale_max = float(sys.argv[i + 1])
|
|
|
+ i += 2
|
|
|
else:
|
|
|
i += 1
|
|
|
if adb_path and device and screenshot_path and template_path:
|
|
|
@@ -320,7 +334,7 @@ def main():
|
|
|
sys.exit(0)
|
|
|
# 3) 回退:多尺度模板匹配,适合简单图标/轮廓(如心形、纯色图标),跨分辨率
|
|
|
fallback_threshold = min(threshold, 0.65)
|
|
|
- scale_result = multi_scale_template_match(screenshot, template, threshold=fallback_threshold)
|
|
|
+ scale_result = multi_scale_template_match(screenshot, template, threshold=fallback_threshold, scale_min=scale_min, scale_max=scale_max)
|
|
|
if scale_result is not None:
|
|
|
x, y, w, h, center_x, center_y = scale_result
|
|
|
output = {
|