Document match-scoped sample paths and draft-session timing lessons.

Capture the prototype findings on top-bar skins, strategy_tail polling, and why CDN-only plus session policy is enough without a real template library.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-07-26 12:13:57 +08:00
co-authored by Cursor
parent a089660ca9
commit 2fb298ebf1
4 changed files with 65 additions and 17 deletions
+5 -4
View File
@@ -30,7 +30,7 @@ Windows 上的 Dota 2 **天梯选将识别**工具:用 GSI 感知选将阶段
运行时产物(**勿提交**,见 `.gitignore`):
- `samples/raw/` — 截图
- `samples/raw/<matchid>/` — GSI 会话截图;手动 `capture.py` 可写在 `raw/` 根下
- `preview/` — 标定 / sheet 预览
- `results/` — 每局 JSON
- `failures/``--truth` 调试用错识裁切
@@ -39,7 +39,7 @@ Windows 上的 Dota 2 **天梯选将识别**工具:用 GSI 感知选将阶段
```
Dota 2 GSI → gsi_watch.py (:3223)
→ DraftSession 轮询截屏
→ DraftSession 轮询截屏 → samples/raw/<matchid>/
→ recognize_image (CDN 模板 + 可选天梯遮罩)
→ roles / grid / modes(辅助)
→ results/draft_*.json + 终端时间线
@@ -48,8 +48,9 @@ Dota 2 GSI → gsi_watch.py (:3223)
## 技术约束(修改前必读)
- **合规**:仅 GSI + 屏幕截图;**禁止**读进程内存、注入、绕过 VAC。
- **GSI 范围**:普通玩家视角拿不到双方 pick;GSI 只作阶段触发`team_slot` 等自身信息
- **模板策略**:只维护 CDN 层。皮肤问题用会话策略(选人可改判、决策 `allow_revise=False`、best 帧偏 HERO_SELECTION),不要为皮肤加模板库。
- **GSI 范围**:普通玩家视角拿不到双方 pick;GSI 只作阶段触发`team_slot`、本人 `hero`
- **模板策略**:只维护 CDN 层。皮肤问题用会话策略(选人可改判、决策 `allow_revise=False`、best 帧偏 HERO_SELECTION),不要为皮肤加模板库,也不要复活 real 双层库
- **顶栏时机**:皮肤在**全员选完后**才上顶栏;本机进决策时别人可能还在选——须保持 `strategy_tail` 视觉,禁止「一进 STRATEGY 就永久停读」。
- **坐标**:一律相对坐标(相对屏幕高 / 相对中心),勿写死像素分辨率。
- **宁可不认,不可乱认**`min_score` + `min_margin` 双门控;不确定就 `null`
- **平台**:面向 Windows;截屏依赖无边框/窗口模式。
+5 -1
View File
@@ -10,8 +10,11 @@
- **放弃 real 实拍模板库**:删除 `build_library.py``templates/real/`;匹配仅使用 CDN 层。
- 移除 `match.cdn_penalty``evaluate.py --cdn-only`(双层库对比已无意义)。
- 模板加载 API 简化为 `(hero_key, image)`
- GSI 会话截图按对局写入 `samples/raw/<matchid>/`
- 运行产物纳入 `.gitignore``preview/``results/``failures/``samples/raw/`
- 文档拆分为 `README`(操作)、`DESIGN`(决策)、`AGENTS`(协作)、`CHANGELOG`(变更)。
- `DESIGN.md` / `AGENTS.md` 补录原型会话结论:顶栏皮肤时机、决策禁改判原因、
real 库审计结论、无法靠 GSI 卡「皮肤前」单帧等。
### Removed
@@ -21,7 +24,8 @@
### Fixed
- (继承自原型)CDN 头像按顶栏窗口裁切,而非中心正方形;CDN-only 即可高准确率。
- (继承自原型)天梯段位条 / 勋章遮罩匹配;选人多帧 + 决策禁改判规避皮肤
- (继承自原型)天梯段位条 / 勋章遮罩匹配;选人多帧 + 决策禁改判规避皮肤
best 帧优先选人阶段;本人英雄以 GSI 覆盖。
## [0.1.0] - 2026-07-25
+45 -6
View File
@@ -68,7 +68,13 @@ Valve 已明确关闭普通玩家视角的实时 draft
- 选人阶段:多帧确认、允许更高分改判(`revise_gain`
- 决策阶段:只补空槽、禁止改判(避免皮肤顶栏覆盖默认脸结论)
- best 帧优先选人阶段默认脸
- best 帧优先选人阶段默认脸`recognized` 相同时)
- 本人英雄以 GSI `hero` 覆盖视觉结果(只覆盖自己的槽)
**⑤ 截图按对局归档**
GSI 会话写入 `samples/raw/{matchid}/`;手动 `capture.py` 仍写 `samples/raw/` 根目录。
结果 JSON 仍为 `results/draft_<时间戳>.json`(内含 `match_id`)。
---
@@ -88,6 +94,15 @@ Valve 已明确关闭普通玩家视角的实时 draft
CDN-only 开箱即用后,「打几十局攒默认脸」不再是主路径。项目改为只维护 CDN。
后续审计(迁出前原型库)进一步确认:
- 标注集上大量 `score=1.000` 往往是「从同帧裁进 real 再评同帧」的自证,夸大了 real 贡献。
- 剩余 real 与 CDN(天梯遮罩)多数 ≥0.85,近乎 CDN 副本;明显偏离的极少(如军团指挥官一类边缘格)。
- **近期问题局**(宙斯缺槽、斯拉达 CDN 分低、敌法末位、皮肤帧风行者 0.415)主要靠
**多帧会话 + 决策禁改判 + GSI 补自己** 凑齐,不是靠 real。
- 皮肤变体极多,入库皮肤模板不合理;段位条/徽章每人不同,匹配时已用遮罩忽略,
也不该为不同段位重复存图。
### 发现三:自动标定靠玩家颜色条
10 条固定玩家色定位槽位;中心用中位数槽距拟合(剔除被身后头像污染的宽条);
@@ -109,6 +124,27 @@ GSI 不含可靠 lobby 类型时,用右下金色勋章检测(`has_ranked_ove
定位局位置字用二值 IoU(非 OCR)。「我」优先 GSI `team_slot`
否则姓名亮度相对差(最亮比次亮 ≥ 25)兜底。
### 发现七:客户端顶栏时机(会话策略前提)
这些是实战纠正后的事实,改 `DraftSession` 时不要违背:
| 现象 | 含义 |
|------|------|
| 顶栏默认脸 → 皮肤 | **全员选完后**才换皮肤立绘,不是一进决策就换 |
| 本机已进 `STRATEGY_TIME` | 别人可能还在选;**不能**一进决策就永久停视觉 |
| 空槽红旗倒计时 | 只出现在**未选**槽;揭晓后消失,不是挡脸主因 |
| GSI | **没有**「皮肤已加载」字段;无法精确卡「人选完、皮肤前」单帧 |
因此正确节奏是:选人 + 决策前期持续读,直到确认 10/10 或 `strategy_tail_polls` 用尽;
凑齐后停视觉,再短等 GSI 补本人英雄。单帧皮肤弱识别(如决策 3D 模型挡顶栏)属预期,
靠会话回填,不靠降阈值或堆皮肤模板。
### 发现八:揭晓淡入需要可改判
首帧揭晓常半透明 + 段位条,易误认(例:剑圣揭晓瞬间被认成幽鬼)。
`confirm_polls` 后若仍禁止改判会锁死错误。选人阶段允许
`score ≥ was_score + revise_gain` 的稳定新结果覆盖;决策阶段则关闭改判。
---
## 4. 代码结构
@@ -122,10 +158,10 @@ climperor/
├── autocalibrate.py / calibrate.py / capture.py
├── evaluate.py / roles.py / grid.py / modes.py
├── templates/cdn|roles|modes/
└── samples/labels.json # 评测真值;raw/ 见 .gitignore
└── samples/labels.json # 评测真值;raw/<matchid>/ 见 .gitignore
```
运行时目录 `preview/``results/``failures/``samples/raw/` 不入库。
运行时目录 `preview/``results/``failures/``samples/raw/`(含按对局子目录)不入库。
### 主要配置
@@ -135,8 +171,9 @@ climperor/
| `match.ranked_mask` | 天梯遮罩比例 | bottom 0.32, right 0.22 |
| `gsi.port` | 监听端口 | 3223 |
| `gsi.confirm_polls` | 连续同结果帧数 | 2 |
| `gsi.revise_gain` | 改判所需分数增益 | 0.15 |
| `gsi.revise_gain` | 选人阶段改判所需分数增益 | 0.15 |
| `gsi.strategy_tail_polls` | 决策阶段继续视觉轮询 | 8 |
| `gsi.strategy_gsi_wait` | 视觉结束后等待本人 GSI 英雄 | 3.0 |
---
@@ -149,10 +186,12 @@ Dota 2 (-gamestateintegration)
→ results/draft_*.json
```
要点:按 `matchid` 去重;识别在工作线程;未标定时降级为只截图。
要点:按 `matchid` 去重;截图进 `samples/raw/{matchid}/`识别在工作线程;
未标定时降级为只截图。
天梯 AP 选人按 2/2/1 成批揭晓,本轮结束前互不可见——因此必须在
**HERO_SELECTION** 跟踪,不能只在决策时间截一张终局图
**HERO_SELECTION** 跟踪,不能只在决策时间截一张终局图;决策前期仍读几帧
以吃到最后一人揭晓(见发现七)。
---
+10 -6
View File
@@ -34,6 +34,7 @@ python gsi_watch.py
```
进入英雄选择后自动跟踪;凑齐 10 人或超时后写出 `results/draft_<时间戳>.json`(该目录已 gitignore)。
会话截图按对局落在 `samples/raw/<matchid>/`
> 主菜单收不到 GSI 是正常的:客户端**第一次载入对局后**才开始推送。看到 `[gsi] connected` 才算链路通。
@@ -46,21 +47,22 @@ python capture.py # 单张 → samples/raw/
python capture.py --loop 300 3 # 每 3 秒一张,持续 300 秒
```
GSI 跟踪时自动写入 `samples/raw/<matchid>/draft_*.png`(含 milestone / best)。
需无边框窗口或窗口模式(独占全屏可能黑帧)。
### 标定 ROI(一次性)
```powershell
python autocalibrate.py samples/raw/<某帧>.png
# 失败时退路:python calibrate.py samples/raw/<某帧>.png
python autocalibrate.py samples/raw/<matchid>/<某帧>.png
# 失败时退路:python calibrate.py samples/raw/<matchid>/<某帧>.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 recognize.py samples/raw/<matchid>/<>.png
python recognize.py samples/raw/<matchid>/<>.png --sheet
python recognize.py samples/raw/<matchid>/<>.png --truth hero1,...,hero10
python evaluate.py # 按 samples/labels.json 批量评测
```
@@ -70,7 +72,7 @@ python evaluate.py # 按 samples/labels.json 批量评测
- PNG、原始分辨率(勿经聊天工具压缩)
- 顶栏 10 个英雄完整可见
- 优先选人阶段默认脸帧(皮肤尚未上顶栏
- 优先选人阶段默认脸帧(全员选完后顶栏才会换皮肤;GSI 无「皮肤已加载」信号
## 已知限制
@@ -78,6 +80,8 @@ python evaluate.py # 按 samples/labels.json 批量评测
- 客户端改网格排序后 `grid.py``ok=False`,不会瞎报禁用名单
- 新英雄上线后重跑 `fetch_cdn_templates.py`
- 位置文字模板取自简体中文客户端
- 决策界面 3D 模型挡住顶栏时单帧会很弱,依赖会话多帧回填
- 普通玩家 GSI 只有自己的英雄 id,不能代替读顶栏
## 相关项目