摘要
战场截图上常常同时有两样东西:战场上站着的一群群生物(游戏里称“兵堆”或“部队”,一堆同种生物共享一个数量),以及屏幕边上某个生物的属性面板(生物面板,显示攻击、防御、数量等)。要把面板读到的数值记到正确的兵堆上,程序得先回答:“面板说的是战场上哪一个?”本实验(编号 B028)是这件事的第一步:只把已有的检测器和身份分类器接起来,在 8 张截图上生成“这里有一个某物种的单位”的候选,不做绑定。
结果:8 张图共 71 个阈值以上的身份候选。随后人工逐张看图,只核对与面板相关的 13 个目标:参考中的 9 个场上单位都有候选且物种第一名正确;另有 3 个框其实是面板上的立绘,不是战场单位;9 个数量牌(显示兵堆数量的小牌子)的中心全部落在身体检测框之外。核心结论是“同物种不等于同一部队”,绑定还没解决。
要回答的问题
能否在同一帧里,为生物面板找到它对应的战场兵堆?这需要几件事分别做好:
- 战场上每个单位在哪(检测);
- 它是什么物种(身份分类);
- 它的数量牌在哪、是多少;
- 面板、当前高亮单位、选中单位、鼠标悬停目标不是同一个概念,要分开;
- 同物种的兵堆可能不止一个(双方各有,或一方多队),名字相同不能直接认定是同一个。
本轮只回答第一层:现成模型能给出什么样的候选。
数据与来源
- 8 张战场截图(原生分辨率 2560×1440),每张都有一个生物面板。这些是以前看过的开发材料,不是独立测试集。
- 另有一份手工参考(标出相关单位的大致位置),但运行器从不读取它,只在之后核对时使用。
- 没有训练、没有解码新视频、没有新 OCR、没有写数据库。
方法
- 检测器:一个先前实验选定的 FCOS 战场单位检测器,阈值固定 0.55,读整张原图。
- 身份分类器:一个先前实验选定的 ConvNeXt-Tiny 分类器(141 个物种类别),只读检测框裁出的小图(裁图底部去掉 10%,缩放到 224×224)。
- 加载模型前先检查原图、清单、OCR 记录是否一致,避免用到过期缓存。OCR 文本不进入模型。
- 输出每个框的位置、检测分数、裁图框和身份前 5 名。身份分数是未校准的 softmax,只代表“物种”猜测,不是部队实例编号;“已接受身份、阵营、队色、兵堆跟踪号”等字段全部留空。所有输出都标为模型候选。
已知风险(本步没有自动屏蔽):面板立绘、界面头像和被遮挡的战场都可能被检测为单位。
设置
保留所有分数 ≥ 0.001、最多 100 个原始检测,再对 0.55 以上的框做分类;没有界面区域过滤。单次开发运行计时不是常驻速度测试。
结果
| 项目 | 数字 |
|---|---|
| 截图 | 8 |
| 低阈值原始检测 | 800 |
| 阈值以上身份候选 | 71(逐图 11/11/13/5/7/5/5/14) |
| 从懒导入到 8 图写完 | 10.629 秒(首图解码+推理 1.184 秒) |
人工同帧核对(独立助手逐张看原图和候选框,只核对 13 个相关目标):
| 核对内容 | 结果 |
|---|---|
| 参考中的场上单位 | 9 个都有候选,物种 Top-1 全部匹配 |
| 额外的框 | 3 个是面板立绘(物种也认对了,但不是战场单位) |
| 面板边缘的一个实际场上单位 | 身份保留未知,不能因为框与面板相交就排除 |
| 8 个面板的对应关系 | 5 个能找到可见对应;1 个对应清楚但面板质量阻断;2 个因数量矛盾拒绝绑定 |
| 数量牌 | 9 个数量牌中心全部位于身体检测框之外 |
作为背景,两个模型在各自原实验中的成绩:检测器测试集 AP50:95 = 70.67%,阈值 0.55 下精确率/召回率 95.39%/93.91%(只衡量框,不含身份);分类器在参考裁图上 Top-1 = 59.28%、Top-5 = 82.63%。这些不能转述为本次组合的成绩。
失败与负结果
- 3 个面板立绘被当作战场单位检测出来——这只是明确检查到的例子,不是全部错误数。
- 2 个面板因为数量与候选兵堆矛盾,无法绑定。
- 数量牌都在身体框外,说明不能指望用身体框“顺便”拿到数量,需要单独定位数量牌再关联。
局限
- 只核对了 71 个候选中的 13 个,不能算作全部候选的准确率,更不是自动绑定成绩。
- 8 张图是已曝光开发材料,不代表完整战场覆盖。
- 分类器没有可靠的“未知类别”拒识能力。
- 面板是否是当前时刻的、属于我方还是敌方、跨帧跟踪,都没有解决;这些结果不能用来更新游戏状态。
结论与下一步
现成模型能为面板对应的场上单位给出不错的物种候选,但“同物种”远不等于“同一部队”。下一步:按原图审核可见单位与面板负例(把面板立绘排除出战场),关联全图 OCR 读到的数量牌坐标,再研究队色与实例对应。后续设计还规定:归属(我方/敌方)的证据链单独验证;跨帧锚点由专门的时序模块处理,单帧代码不偷偷读历史。
Comments