# 上分帝(Climperor) Dota 2 **天梯选将识别**:从选人 / 决策时间截图中识别双方 10 个英雄。 本地、离线、秒级;模板来自 Steam CDN 官方头像。GSI 只负责触发时机,阵容靠视觉读顶栏。 设计背景见 [DESIGN.md](DESIGN.md);协作约定见 [AGENTS.md](AGENTS.md);变更记录见 [CHANGELOG.md](CHANGELOG.md)。 ## 原理 ``` 决策时间截图(PNG) → 按相对坐标裁出 10 个头像格(分辨率无关) → 缩放到统一尺寸;天梯局自动屏蔽段位条/勋章遮挡区 → 与 CDN 模板做归一化相关匹配(TM_CCOEFF_NORMED) → Top-1 分数 + Top1−Top2 分差双阈值 → hero_key 或 null ``` 皮肤差异靠会话策略处理(选人阶段多帧确认,决策阶段禁止改判),不堆皮肤模板。 ## 安装 ```powershell pip install -r requirements.txt python fetch_cdn_templates.py # 一次性:heroes.json + templates/cdn/ ``` ## 快速开始(GSI 自动跟踪) ```powershell python gsi_setup.py # 写入 Dota GSI 配置 # Steam → Dota 2 → 属性 → 启动项加上 -gamestateintegration,重启游戏 python gsi_watch.py ``` 进入英雄选择后自动跟踪;凑齐 10 人或超时后写出 `results/draft_<时间戳>.json`(该目录已 gitignore)。 会话截图按对局落在 `samples/raw//`。 > 主菜单收不到 GSI 是正常的:客户端**第一次载入对局后**才开始推送。看到 `[gsi] connected` 才算链路通。 ## 手动流程 ### 截图 ```powershell python capture.py # 单张 → samples/raw/ python capture.py --loop 300 3 # 每 3 秒一张,持续 300 秒 ``` GSI 跟踪时自动写入 `samples/raw//draft_*.png`(含 milestone / best)。 需无边框窗口或窗口模式(独占全屏可能黑帧)。 ### 标定 ROI(一次性) ```powershell python autocalibrate.py samples/raw//<某帧>.png # 失败时退路:python calibrate.py samples/raw//<某帧>.png ``` ### 识别 / 评测 ```powershell python recognize.py samples/raw//<帧>.png python recognize.py samples/raw//<帧>.png --sheet python recognize.py samples/raw//<帧>.png --truth hero1,...,hero10 python evaluate.py # 按 samples/labels.json 批量评测 ``` 辅助脚本:`roles.py`(位置字)、`grid.py`(禁用名单)、`modes.py`(模式字)。 ## 截图要求 - PNG、原始分辨率(勿经聊天工具压缩) - 顶栏 10 个英雄完整可见 - 优先选人阶段默认脸帧(全员选完后顶栏才会换皮肤;GSI 无「皮肤已加载」信号) ## 已知限制 - 宽高比差异大(如 21:9)时可能需重标定 - 客户端改网格排序后 `grid.py` 会 `ok=False`,不会瞎报禁用名单 - 新英雄上线后重跑 `fetch_cdn_templates.py` - 位置文字模板取自简体中文客户端 - 决策界面 3D 模型挡住顶栏时单帧会很弱,依赖会话多帧回填 - 普通玩家 GSI 只有自己的英雄 id,不能代替读顶栏 ## 相关项目 成熟后可移植到 [dota2-hex](../dota2-hex) 或独立发布。合规边界:只使用屏幕可见信息,不读内存、不注入。