P63 · 固定战斗 UI · 实验记录与相关篇目
已补头像与属性图标匹配:战斗初段 56 个 HUD 中,45 组可把数字关联到字段名,另有 1 组 OCR 冲突。逐截止点的真实前缀检查通过;尚未完成敌方技能推断。
《英雄无敌:上古纪元》的战斗界面有很多固定区域:两侧的英雄信息区(HUD)显示数值和时间,顶部一排卡片显示行动顺序。我们希望程序先找出这些元素,让人直接检查结果,不必逐帧从头看。
这一轮先把行动条上的卡片框出来,再分别判断生物种类和红蓝底色。认不出种类也保留位置,人仍能在原图上补标。151 张开发图得到了 1,618 个去重后的卡片框,其中 370 个身份未知;数据来源与逐项检查见前半篇。后半篇单独讲英雄数字和计时,不把两批成绩混在一起。
9 月 20 日又向前走了一步:让 HUD 读取器按录像时间工作。目标不只是读准数字,还要保证在第十分钟显示的分析没有偷看第二十分钟的画面。新增试验放在第 6 节,前面的行动条结果保留为原有实验。
flowchart LR
K[Available source frame] --> R[Known UI regions]
R --> H[HUD and clock reading]
R --> D[Turn card boxes]
D --> C[Identity and color]
H --> V[Reviewable observations]
C --> V
图 1:固定区域缩小搜索范围。框、身份、颜色和数字是不同读数,不需要全部成功才保留一个元素。
1. 行动条竖直位置固定,身份判断可以晚一步
行动条里,生物卡片的上下边界基本不动;卡片数量、回合分隔符和横向位置会变化。因此不必在整张战场上搜索。当前输入限定为原生 2560×1440,先裁出顶部 [448, 0, 2144, 160],检测器只找一种目标:“生物卡片”。回合分隔符和英雄头像不是这个类别。
拿到框后,再分别回答“是什么生物”和“底色是红还是蓝”。颜色只读两侧边缘,避免让生物本身的红蓝外观投票;身份不够确定,就把字段留为 UNKNOWN,框和已经读出的颜色仍然保留。这比“身份没认出就连框一起丢掉”更适合辅助标注。
很多检测网络本来就有框回归与分类分支,但这不等于原生支持可靠的未知类。例如 Faster R-CNN 对候选区域分类,YOLO Detect 分别预测框与类别。工程上把卡片定位与具体生物分类拆开,可以降低定位对已知物种的依赖;仍不能保证所有陌生外观都能被框出。项目的战场本体运行器其实已是单类 FCOS 检测加独立分类,这一轮没有替换它,也没有改它的默认输出。

图 2:这张图原始模型给了 14 个框,实际有 13 张卡片。最终输出固定 y=0…127,保留左右边界;横向重叠比例过高的框只留高分者。不同位置出现相同头像仍是不同槽位,不会按物种去重。这里的网络仍是二维检测器,固定高度是后处理,不是已经训练好的一维网络。
2. 少量框训练定位,更多原图用于核对身份
模型采用已有的官方 COCO 预训练 YOLO26n 权重,微调为单类卡片检测。训练长边 1024、矩形输入、batch 4、AdamW,不做会拼出多排行动条的 mosaic。最多训练 80 epoch,验证指标停止改善后在第 65 epoch 结束,保留第 50 epoch 的 checkpoint。
| 数据 | 图 / 卡片框 | 实际用途 |
|---|---|---|
| 原有 3 个视频组 | 12 / 110 | 训练;含 3 张无卡片图 |
| 原有另外 2 个视频组 | 8 / 74 | 选择模型和身份门限;含 2 张无卡片图 |
| 新增 20 个视频 | 36 / 448 | 模型辅助目视核对;含 1 张无卡片图 |
| 另选菜单、选兵等画面 | 12 / 0 | 固定设置下的无卡片检查 |
| 额外未审核图片 | 115 / — | 仅生成自动候选 |
训练与验证按视频分开。新增 36 图避开这五个视频,从已有战场标注中挑选更丰富的生物组合;战场上的标签只用来选图,不能直接充当行动条答案。逐图查看原始顶部、规范图标对照,再写身份、底色和数量。这批参考含 130 个目录身份,其中有化身等非 Arena 条目;与原有参考合并后,Arena 覆盖是 129/141,不是 130/141。
新增参考没有参与本轮训练,但也不是盲测:身份建议辅助了标注,固定高度和去重是在看到重复框后加入的。同一画面中未来回合重复的头像、两对近似相同的行动条也带来相关性。以下数字是开发检查,不能当作新录像的准确率。
3. 框已经够用,未知身份仍不能完全靠门限解决
先只检查“框得对不对”。交并比(IoU)是两个框的重叠面积除以它们合起来占据的面积;本轮以 IoU ≥ 0.5 判为匹配。在 36 张新增图上得到:
| 定位方法 | 匹配框 | 漏框 | 多余框 |
|---|---|---|---|
| 原有边框扫描 | 448 | 0 | 0 |
| 小模型原始输出 | 448 | 0 | 4 |
| 小模型+固定高度+横向去重 | 448 | 0 | 0 |
这批数据没有证明学习式检测比原有规则更好。参考框也采用目视核对过的固定布局,所以不拿规则框与参考框重合得更好作为优势。额外 12 张顶部无卡片图中没有误报;它们来自 3 个视频,覆盖菜单、选英雄、选宝物、选兵、选法术和战斗准备的选图标签,仍缺少完整的过渡、遮挡和缩放测试。
身份读取把卡片头像与游戏知识库(Game Knowledge)的 148 个规范图标比较。只比较头像头部,不看数字区;在 100/108/116 像素三种尺度、两个朝向下,计算有效像素区域的相似程度,即带掩膜的归一化相关匹配。程序保存前三名。旧验证集选定的接受条件是:第一名至少 0.80,且比第二名高至少 0.03;这个相似分数不是正确概率。

图 3:这是本地结果中的真实拒识。界面可以显示第一名建议供人审核,但代码中的身份仍为空,不偷偷把建议写成已确认类别。
36 图的 448 张卡片中,349 个身份通过门限,99 个拒识;通过的身份都与这批目视参考一致。颜色是 412 个一致、36 个未知。核对过程中曾发现 4 处参考底色抄错,重新放大原图后修正;没有把模型输出直接当真值覆盖。
为了试探未知类问题,还做了一个简单诊断:从每个 crop 的前三名里移除真实类别,再看系统会不会错误接受别的名字。旧验证集 74 个都拒识,但新增参考中仍有 4/448 错误接受。它只模拟匹配库缺少真实类别,不是真正陌生生物的完整测试,因此目前不能承诺可靠的开放集识别。
最终批量处理 151 图得到 1,637 个原始框,横向去重移除 19 个,留下 1,618 个。身份未知 370 个、颜色未知 138 个,两项可能重叠。当时 115 张额外图片尚未逐项核对;其中 12 张现已进入下述第二轮参考,另外 103 张仍为自动候选。算法输出保留原样,与人工参考分层。数量已逐项转录,但没有重新评估自动数量 OCR。
第二轮:把审核时间用在稀缺类别上
程序根据缓存预测中的类别建议,优先找参考少的生物,每段视频最多选两图、两图至少相隔 90 秒。本轮实际查看 10 段录像的 12 张原图及规范资产对照,新增 156 张卡片参考:89 个目录身份、72 红、84 蓝。这是新标注,不是新录像,也不是重新推理后的成绩。
新增覆盖了虫巢女王、农民和阳矛骑兵三个 Arena 身份。和旧 20 图、第一轮 36 图合并,现有 68 图、788 卡片、135 个目录身份,其中 132/141 个 Arena 身份。仍缺屠龙者、半身人、小角猫、荣耀守望者、洞龙、吸血鬼领主、噬蠕、邪教徒、誓信徒;已经覆盖也不表示样本量足够。
阳矛骑兵的本地身份分数约 0.62,低于接受门槛,仍输出 UNKNOWN;人对照原图与规范图标后才加入参考。没有为了消灭未知而降低门槛。另发现一张裁图里修女院长的蓝衣服容易被当成蓝方,放大原图确认红底后修正参考。
两张农民来源共享同一阵容、数量有变化,只增加可见数据,不当成两份独立身份泛化证据。模型与门槛没有变化;下一步继续补缺类与不同视频,并为新视频保留真正未曝光的验收集。
4. 前一批 HUD 实验:稳定帧让固定区域 OCR 变得便宜
这一历史 HUD 实验的 68 张原图,与前面的 68 张行动条参考是不同批次。它们来自 2 个视频、6 个 30 秒区间:40 张来自 9 月 4 日视频,28 张来自 9 月 5 日视频。每张 2560×1440 原图固定裁出四块:左右完整 HUD 各 333×547,左右计时各 154×202。

图 4:完整 HUD crop 保留头像、三项数值和资源 current/maximum。裁图可用不代表字段含义已经识别。

图 5:计时 crop 同时包含上、下两行显示,OCR 必须成对返回,不能从上一帧硬补缺失字符。
抽查 4 张候选中的 10 个 crop,头像、三项面板数字、生命/资源显示和两行计时都没有被裁掉。这只验证区域范围,不是 OCR 真值评估。
5. 两路图像处理互相校验计时
PP-OCRv6 medium 分别读取原始 crop 和 3× CLAHE 增强 crop。CLAHE 是局部对比度增强,用来让细小数字更清楚。125 个 crop 在两路中都得到相同的两个 MM:SS;另 11 个只有增强路得到完整成对读数,集中在原图漏末位数字的 03:47 与 02:27。
这 11 个被标成 OBSERVED_WITH_INCOMPLETE_PASS,保留另一条不完整尝试,不伪装成两路一致。人工抽查 9 个计时 crop,显示原文与解析结果 9/9 一致。GPU 常驻批次处理 136 个 crop 用时 4.63 秒;这个时间不含完整冷启动。
6. 英雄 HUD 宁可拒识,也不拼接冲突数字
英雄 HUD 读取器只输出 attribute_slot_1/2/3 和 resource_current/resource_maximum。136 个 crop 中:
| 结果 | 数量 | 含义 |
|---|---|---|
| 两路完整一致 | 102 | 接受 |
| 只有一路完整 | 22 | 接受,但保留不完整尝试 |
| 两路完整但冲突 | 9 | 拒识 |
| 两路都不完整 | 3 | 拒识 |
| 总接受 | 124/136,91.18% | 开发集可用率,不是准确率 |
人工查看 10 个 HUD:6 个接受样例的四项读数都与画面一致;1 个冲突和 3 个不完整样例都没有被错误输出。一个典型冲突是增强路把 12 12 6 连成 12 126 6,拒识是正确选择。三个肉眼可读但 OCR 漏中间属性的样例说明召回仍不完整。
打开魔法书的同一张图,也检查英雄数字与时钟
9月12日,我们在核对魔法书数字时,同时逐张读取了10张原图的两侧HUD。每侧记录3项属性、1个资源分数和2个时钟,共80项英雄字段、40项时钟。它们都与已冻结的视频流水线输出一致;参考是看原图另写的,没有从预测复制,也没有修改预测补分。
这里用的是视频原有的全图多配方OCR和严格字段解析,不是前面专门HUD裁图实验的成绩,也没有额外调用VL重读HUD。10张图来自同一段开发录像,重复内容多,不能由120/120推出所有战斗场景都准确。属性槽和资源的游戏含义仍未知,左/右也只表示屏幕位置。
同帧HUD审核入口把参考与本地结果分开显示,左右切帧时能看到实际时钟变化。这批参考待作者确认;底栏生命、行动条和其他UI没有因此被算作全部标完。下一批更应覆盖不同视频、嵌入式时钟和遮挡,而不是继续增加相似帧。
按录像时间读取:后面出现的画面不能改写前面
如果以后要在录像上方显示敌方技能分析,选帧就不能再从整段视频里寻找最清楚的一张。我们先固定十个检查时刻,每到一个时刻,只取此前已经出现的最后一帧,再裁出左右 HUD。保留视频里的原始时间戳,而不是用帧序号除以平均帧率估算时间;这份录屏的帧间隔并不完全相同。
沿用原图与三倍增强两路 OCR,没有重新训练或调整门限。20 个区域中,14 个得到完整读数,其中 9 个两路完整、5 个只有一路完整;另外 6 个不输出属性组。看原图后发现,这 6 个位置显示的是非数字 HUD 画面,包括部署阶段的两个计时。它们不能硬套成英雄属性。

图 6:上排来自原片约 70 分钟,下排约 100 分钟。左侧第三个属性从 19 变为 27,当前资源从 292 变为 130;右侧第三属性仍为 14。程序先记录这些变化,不把它们直接解释为某项技能成长或某次施法消耗。
逐图转录后,14 组里的 70 个数字与参考一致;6 个无数字 HUD 区域没有误接受。这是同一开发录像、看过模型输出后的非盲核对,参考仍待作者确认,不是新视频准确率测试。三个属性槽也不等于读齐了英雄的四种主属性,缺少的字段要从其他可见界面补充,不能从资源上限反算后冒充读数。
数字读到了,但它属于谁、代表什么?
只读到 4、6、14,还不能直接写成“敌方英雄的攻击、防御、法强”。现在增加两条独立的图像比较:肖像区域与知识库的 77 个英雄参考图比较;数字上方的小图标与 11 个属性参考图比较。数字本身不参与英雄身份选择,也不靠“第一个位置通常是什么”来补图标答案。
肖像比较寻找图中相似的局部纹理点,使用 SIFT 特征,再检查这些点能否用一致的缩放、旋转和平移对齐。至少八个分散的匹配点通过检查,且明显优于另一位英雄,才给出身份候选。属性图标较小、位置固定,直接在几个大小下比较有效像素的颜色变化。这两种方法都保留拒识,相似分数不当成概率。

图 7:右侧肖像匹配到修女凯莉,三个图标对应攻击、防御、法强,读数为 4、6、14。左侧则是希尔的 3、3、18。兔子头像另提供左红为我方的候选依据;这些外观结果仍不是游戏内部状态的确认。
补采按原片时间分成两组:部署附近每两秒取一张,共 36 张、72 个 HUD,数字读取全部保留为不完整;战斗开始附近每十秒一张,共 28 张、56 个 HUD,其中 45 组有完整数字和图标对应,10 组不完整、1 组冲突。这是同一已曝光录像的输出统计,不是逐张人审后的准确率,也没有覆盖全部 77 位英雄。
冲突出现在 4180 秒右侧:原图路读到 4、6、14,增强路却读成 6、1、14。目视原图能确认原图路更接近实际显示,但程序没有因此选边,更没有从前后帧抄答案;该时刻暂不输出属性组。局部增强有时能补救小字,也会制造新错误。
为了检查是否偷看未来,我们从原片物化两秒真实画面,对片段的 500 ms 和 999 ms 分别制作截断版本和未来纯色版本。每个截止点各启动三个独立 OCR 进程,只给它本时刻的两个裁图;实际像素、来源时间、肖像候选、图标匹配及解析读数都一致。另检查截止点之后的画面确实发生了替换,避免做了一个没有变化的对照。
制作对照必须保留编码时间基:只说“保持帧率”仍可能让可变帧率的时间戳被重新取整。这里验证的是局部读取链路;技能推断、历史账本和整片导出还要单独做前缀检查。
7. 读到像素,不等于确认了游戏角色
B029 保存这一帧计时的位置、原文和解析值。计时是否减少,需要比较不同时间的观测;减少的一侧是否属于我方,还需要本局的身份对应关系。这三层结论不能互相替代。上下计时仍命名为 upper_clock 和 lower_clock,左/右仍是屏幕位置。新增的英雄与属性名称来自独立图像匹配;没显示的知识值、尚未关联的资源含义和行动方仍不能顺手补齐。
当前结果也不是独立 OCR 准确率:68 张帧来自开发视频,人工只抽查了一小部分。它证明的是稳定选帧可以快速批量生成可读固定区域,而且保守拒识没有阻断后续工作。
8. 下一步:先把同一帧的英雄、卡片和数字读齐
截至9月24日,隐藏技能与装备推断已经暂停。当前先补开战瞬间和英雄面板的缺失字段,再核对行动卡的身份、颜色与数量。上文“剩余9个Arena身份”是当时快照,不是今天重数的缺口;恢复采集前应重新生成覆盖表。
行动卡数量后来已接入可选流程:四张有参考图的49个数量中47个相符、2个未知,见P80。它不证明卡片物种或行动方都正确。英雄数字、玩家身份和底栏高亮仍需同帧关联;不能把屏幕左侧直接叫我方,也不能把第一次读到的数值自动叫开局值。最终仍以完整关键帧审阅为准。
Comments