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

如何在有快速移动投射物的屏幕上识别手游骰子棋盘信息?

手游棋盘骰子识别优化方案

一、解决检测速度慢的问题

pyautogui的模板匹配效率极低,尤其是多模板场景,以下是针对性优化:

  • 锁定ROI区域,避免全图搜索:提前计算棋盘上5×3个骰子的精确坐标(比如每个骰子格子是80×80像素),直接裁剪每个格子的ROI,而非在整屏搜索所有模板。
  • 替换为OpenCV高效匹配:放弃pyautogui的locateOnScreen,改用OpenCV的cv2.matchTemplate,提前将所有模板和ROI转为灰度图,选择更快的匹配算法(如cv2.TM_SQDIFF_NORMED)。
  • 预处理模板批量缓存:将5种类型×7等级的所有模板,提前resize到与骰子格子一致的尺寸并转灰度,存储为列表,避免每次匹配时重复处理。
  • 并行处理多格子:15个骰子格子的匹配是独立任务,用concurrent.futures.ThreadPoolExecutor并行处理,可将速度提升3-5倍。

示例代码片段:

import cv2
import numpy as np
from concurrent.futures import ThreadPoolExecutor

# 提前加载并预处理模板(假设模板路径为templates/typeX_levelY.png)
templates = {}
for dice_type in range(1,6):
    for level in range(1,8):
        path = f"templates/type{dice_type}_level{level}.png"
        template = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
        templates[(dice_type, level)] = cv2.resize(template, (80,80))  # 假设骰子格子80×80

# 定义单个格子的匹配函数
def match_dice(roi_gray):
    best_score = float('inf')
    best_match = None
    for (dtype, lvl), temp in templates.items():
        res = cv2.matchTemplate(roi_gray, temp, cv2.TM_SQDIFF_NORMED)
        min_val = np.min(res)
        if min_val < best_score:
            best_score = min_val
            best_match = (dtype, lvl)
    return best_match if best_score < 0.1 else None  # 置信度阈值设为0.1

# 裁剪所有ROI并并行匹配
def recognize_board(screen_gray):
    roi_coords = [(x*80, y*80, 80,80) for y in range(3) for x in range(5)]  # 5×3格子
    rois = [screen_gray[y:y+h, x:x+w] for x,y,w,h in roi_coords]
    with ThreadPoolExecutor(max_workers=5) as executor:
        results = list(executor.map(match_dice, rois))
    # 整理为5×3数组
    return np.array(results).reshape(3,5).T

二、解决投射物干扰的问题

1. 帧平均法(可行且易实现)

连续捕获20-30帧快速截图(用mss替代pyautogui的screenshot,速度快10倍以上),对所有帧的对应像素取平均值,动态的投射物会因位置变化被模糊消除,留下清晰的静态骰子。
示例代码片段:

import mss
import numpy as np
import cv2

def get_avg_frame(num_frames=20):
    with mss.mss() as sct:
        monitor = sct.monitors[1]  # 主显示器
        frames = []
        for _ in range(num_frames):
            frame = np.array(sct.grab(monitor))
            frames.append(cv2.cvtColor(frame, cv2.COLOR_BGRA2GRAY))
        # 取平均并转为uint8格式
        avg_frame = np.mean(frames, axis=0).astype(np.uint8)
        return avg_frame

注意:需确保捕获帧的间隔足够短(mss的截图间隔约1ms),避免骰子本身位置变化。

2. 特征聚焦识别

放弃整骰子模板,聚焦骰子的核心特征:

  • 颜色分割:5种类型的骰子主色调不同,用HSV颜色空间分割出每个骰子的区域,过滤掉投射物的异色区域。
  • 等级数字单独匹配:只截取骰子上等级数字的小区域(比如骰子顶部10×20的区域),用数字模板匹配或轻量OCR(如Tesseract训练小数字模型)识别等级,避免投射物干扰。

3. 多模板鲁棒匹配

针对每个等级的骰子,收集3-5张带有不同投射物干扰的模板,匹配时取所有模板的最高置信度结果,无需降低置信度即可避免等级混淆。

三、可选技术栈优化

如果Python的性能仍不满足需求:

  • 改用C++结合OpenCV,速度比Python快5-10倍。
  • 训练轻量CNN模型(如MobileNetV2、TensorFlow Lite模型),将每个骰子ROI输入模型直接输出类型和等级,抗干扰能力强,推理速度可达每秒数百帧。训练数据可自行截图生成,加入投射物干扰的样本并做数据增强(旋转、模糊、亮度调整)。

内容的提问来源于stack exchange,提问作者Loïc Pottier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:53:10