You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用Sikuli追踪旋转及被遮挡物体?求实现方法

关于用Sikuli追踪旋转/遮挡对象的解决方案

可行性说明

完全可行,但Sikuli原生的模板匹配对旋转、缩放的鲁棒性极差,直接用while exists+简单匹配会因为频繁匹配失败、CPU占用过高导致崩溃,需要调整匹配策略或结合外部工具解决。


方案一:优化Sikuli自身实现

核心是改用特征点匹配替代模板匹配,并优化追踪逻辑:

  1. 启用特征匹配模式
    SikuliX支持基于特征点的图像匹配,对旋转、轻微缩放的对象识别效果更好,通过以下设置开启:

    from sikuli import *
    # 切换到特征匹配模式
    Settings.MATCH_MODE = MATCH_MODE_FEATURE
    # 设置最低匹配相似度(根据对象特征调整,0.5-0.7比较合适)
    Settings.MinSimilarity = 0.6
    
  2. 优化追踪循环,添加异常处理
    避免死循环无间隔采样,增加休眠时间;捕获匹配失败异常,防止程序崩溃:

    import time
    
    ball_pattern = Pattern("ball_reference.png")  # 提前准备一张对象的参考图
    search_radius = 150  # 限定搜索范围,减少计算量
    
    while True:
        try:
            # 在上次找到的位置周边搜索,提升效率
            ball = find(ball_pattern.nearby(search_radius))
            mouse.move(ball)
            time.sleep(0.2)  # 控制追踪频率,降低CPU占用
        except FindFailed:
            # 未找到时扩大搜索范围或直接等待重试
            time.sleep(0.1)
            continue
    
  3. 适配遮挡场景
    如果对象被部分遮挡,可适当降低Settings.MinSimilarity阈值,同时确保参考图包含对象的核心特征(比如球的标志性图案),而非完整外观。


方案二:调用外部脚本(推荐)

如果Sikuli自身的匹配能力无法满足需求,可以调用外部工具(如OpenCV)实现更鲁棒的追踪,Sikuli支持直接执行外部脚本或程序:

  1. 用OpenCV实现目标追踪
    编写一个独立的Python脚本(如track_ball.py),使用OpenCV的CSRT/KCF等追踪算法,这类算法对旋转、遮挡的处理远优于Sikuli:

    # track_ball.py
    import cv2
    import numpy as np
    
    # 若追踪屏幕内容,需替换为屏幕捕获工具(如mss)
    cap = cv2.VideoCapture(0)
    # 初始框选对象(或用图像识别初始化)
    ret, frame = cap.read()
    bbox = cv2.selectROI("Select Ball", frame, False)
    tracker = cv2.TrackerCSRT_create()
    tracker.init(frame, bbox)
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        success, bbox = tracker.update(frame)
        if success:
            x, y, w, h = [int(v) for v in bbox]
            # 输出中心坐标到标准输出,供Sikuli读取
            print(f"{x+w//2},{y+h//2}", flush=True)
        cv2.waitKey(1)
    
  2. 在Sikuli中调用外部脚本
    使用subprocess模块启动外部脚本,读取其输出的坐标并控制鼠标:

    from sikuli import *
    import subprocess
    import time
    
    # 启动外部追踪脚本
    proc = subprocess.Popen(
        ["python", "track_ball.py"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )
    
    while True:
        line = proc.stdout.readline()
        if not line:
            break
        # 解析坐标
        try:
            x, y = map(int, line.strip().split(","))
            mouse.move(x, y)
        except ValueError:
            pass
        time.sleep(0.1)
    

原脚本崩溃原因分析

你之前的while exists脚本崩溃,主要是因为:

  • 原生模板匹配完全无法应对旋转对象,频繁触发FindFailed异常且未处理
  • 无间隔的循环持续占用100%CPU,导致程序资源耗尽

内容的提问来源于stack exchange,提问作者Gustavo Orth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:32:33