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

如何提升OpenCV对Chrome恐龙游戏屏幕多目标检测的性能

优化Chrome恐龙游戏自动化的帧率问题

我正在实现Chrome恐龙游戏的自动化,通过裁剪昼夜两种状态下的障碍物(小仙人掌、大仙人掌、翼龙)图像,用OpenCV的matchTemplate遍历目标字典来定位物体。程序核心逻辑:

  1. 捕获恐龙前方的屏幕区域
  2. 遍历待检测目标,使用cv2.matchTemplate进行检测
  3. 当检测到的物体X坐标处于距离阈值内时,触发恐龙跳跃

当前帧率仅能达到15 FPS,即使游戏初期速度较慢,恐龙也无法在物体进入阈值时立即跳跃,躲避效果不佳。

主脚本代码

def main_script():

    # Local variables
    loop_time = 0.00001
    fps_list = []
    action_threshold = 280
    dodge_objects = {
        'big_cacti_day': GameObject(find_img('big_cacti_day.png')),
        'big_cacti_night': GameObject(find_img('big_cacti_night.png')),
        'bird_day': GameObject(find_img('bird_day.png')),
        'bird_night': GameObject(find_img('bird_night.png')),
        'small_cacti_day': GameObject(find_img('small_cacti_day.png')),
        'small_cacti_night': GameObject(find_img('small_cacti_night.png')),
    }
    # Start the game
    jump(actions)
    
    # Game loop
    with mss.mss() as sct:
        monitor = {"top": 600, "left": 250, "width": 550, "height": 150}
        while 1:
            # FPS print for testing
            print_fps(fps_list, loop_time)
            loop_time = time.time()

            # Update game screen
            img = numpy.array(sct.grab(monitor))
            game_screen = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

            for key in dodge_objects:
                dodge_object = dodge_objects[key]
                if dodge_object.match(game_screen):
                    dodge_object_left_x = dodge_object.location[0][0]
                    cv2.rectangle(game_screen, dodge_object.location[0], dodge_object.location[1], (0,0,255), 2)

                    # Action
                    if dodge_object_left_x < action_threshold:
                        print(key, 'x:', dodge_object_left_x, 'y:', dodge_object_left_y)
                        jump(actions)

            # Show recorded region
            cv2.imshow('screen', game_screen)
            if cv2.waitKey(1) == ord('q'):
                break

GameObject类代码

import cv2

class GameObject:

    location = None
    
    def __init__(self, path):
        img = cv2.imread(path, 0)
        self.img = img
        self.width = img.shape[1]
        self.height = img.shape[0]


    def match(self, screen):
        res = cv2.matchTemplate(screen, self.img, cv2.TM_CCOEFF_NORMED)
        minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res)
        startLoc = maxLoc
        endLoc = (startLoc[0] + self.width, startLoc[1] + self.height)

        if maxVal > 0.8:
            self.location = (startLoc, endLoc)
            return True
        else:
            self.location = None
            return False

已尝试的优化措施

  • 测试dxcam、win32api、pyautogui、PIL等屏幕捕获库,mss库性能最优
  • 通过mss裁剪恐龙前方550x150的感兴趣区域,性能有所提升但仍不足
  • 将待检测物体的图像裁剪至最小尺寸

性能分析显示,Python循环和cv2.matchTemplate是主要瓶颈——注释循环部分后帧率可达约27 FPS,mss._grab_impl和matchTemplate函数占用了大部分运行时间,现寻求更多可实施的代码性能优化技巧。


优化建议

1. 合并昼夜模板,减少检测次数

恐龙游戏的昼夜切换是全局色调反转,无需分开检测昼夜模板:

  • 提前将夜间模板做灰度反转,与白天模板共用检测逻辑
  • 或通过屏幕平均亮度判断当前昼夜状态,仅检测对应状态的3个模板,直接减少一半matchTemplate调用次数

2. 优化matchTemplate的计算效率

  • 更换更快的匹配算法:cv2.TM_SQDIFF_NORMED或cv2.TM_CCORR_NORMED的计算速度优于TM_CCOEFF_NORMED,可测试精度是否满足需求
  • 对模板和屏幕帧做降采样(比如缩小至原尺寸的50%),匹配后再还原坐标,大幅减少计算量
  • 提前预计算模板的归一化参数,避免每次匹配重复计算

3. 降低Python循环开销

  • 将dodge_objects从字典改为列表,遍历列表的速度比字典更快
  • 提前缓存所有模板的尺寸等属性,避免在循环中重复读取
  • 把匹配逻辑中的固定计算(如startLoc[0] + self.width)移至__init__方法中完成

4. 优化屏幕捕获与处理

  • 让mss直接返回灰度图:使用format="gray"参数,省去cv2.cvtColor的转换耗时
  • 进一步缩小捕获区域:如果恐龙前方的有效预警区域可压缩至更小范围(比如前300px宽度),减少处理的像素量
  • 移除调试开销:注释print_fps、print调试输出,关闭不必要的cv2.imshow预览,IO操作会显著拖慢帧率

5. 批量处理模板

将同状态的模板合并为一个大数组,利用OpenCV的批量匹配能力(部分版本支持),一次调用检测多个模板,减少Python与C层的交互开销

6. 多线程重叠耗时操作

将屏幕捕获与模板检测放在不同线程:mss捕获当前帧的同时,处理上一帧的模板检测,重叠耗时操作,提升整体帧率(注意cv2.imshow需放在主线程避免冲突)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:47:27