摘要

项目的战斗记录 App(Battle Notes)最初要靠玩家在对局中按截图键,把想分析的画面交给视觉理解模块(Perception)读取,再由状态估计(SE,把读到的观察累积起来推断对局状态和对手构筑)给出对方信息。用户的目标是:战斗中不按截图键,程序自动挑出值得读的画面(关键帧)去分析;选秀阶段的画面低延迟丢弃;离线回放用虚拟时间;生产精度测试和有界队列测试分开。

本实验交付了三件事:

  1. 流式关键帧选择 + 阶段门:边播边选关键帧,选秀 / 菜单阶段的关键帧直接跳过。
  2. 行动条兵种识别提速:在“生产读数完全不变”的前提下,4 个测试局 51 张截图的识别总耗时从约 265 秒降到 103 秒。
  3. 手动与自动的对比:两局测试中,各种自动方式认出敌方英雄都比手动截图早约 1.5–3 分钟,而且自动模式在一局里多找到了 2 次真实的敌方施法;代价是有界队列会丢帧。

要回答的问题

不依赖截图键、完全自动地选帧和读取,能否得到不少于手动截图的对手信息?读取速度跟不上画面时会发生什么?

数据与来源

  • 测试录像:10 月 5 日两局(21:20 和 22:02 开始的录像),属于测试用途;另一段 10 分钟录像用于阶段门统计。
  • 真值:只来自这两局的“截图包”(玩家当时手动截的 15 张和 10 张图)及其标注。截图包没覆盖的画面,没有真值。
  • 用户第一次实战(10 月 9 日)的自动读取记录,用于检查重复关键帧。

方法

流式关键帧选择。 把原来的批处理关键帧选择器改成流式版本:逐帧输入、内存有界,单元测试确认与批处理逐帧结果相等。

阶段门。 选秀和菜单阶段的关键帧直接跳过,开战前的最终确认页保留,标签不可靠的帧照常分析。

选帧服务。 一个常驻服务接收 640×360 的 JPEG 帧,输出关键帧和每帧进度;App 端有背压控制:服务落后 8 帧就暂停送帧。

行动条兵种识别提速。 战斗画面上有一条“行动条”,按行动顺序列出各个兵堆的小卡片。原来每张卡片都要和全部兵种模板做精确匹配(每张约 0.2 秒)。尝试了几种提速,启用条件都是“4 个测试局 51 张截图的战场读数逐字段不变”:

  • 近乎相同的卡片复用上次结果(相似度 NCC ≥0.985,只在常驻服务里);
  • 由粗到细:先用便宜的粗匹配排出前 K 名,再只对这 K 名做精确匹配。K 根据数据定:在 289 张卡片、两种模板上,全量匹配的第 1/2/3 名在粗排中最差排在第 1/14/17 名,所以保留 24 名可以全覆盖。最后把粗排改写成矩阵运算,粗排每卡 4.5 毫秒(原约 90 毫秒),名次分布与原粗排逐项相同。

重复关键帧判定(实战后补充)。 160×90 灰度缩略图分成 16×9 格,与同场景上一张已读帧比较:变化超过 8 个灰度级的格子少于 10% 就跳过。

设置

对比实验在 CPU 限 8 核的条件下运行。两局的“全部关键帧”分别有 466 和 553 张,超过 SE 单次 256 帧的上限,所以等间隔去掉多余的战场 / 布阵帧,其余场景全部保留。行动条提速是在机器满载时测的,绝对时间偏高。

结果

阶段门(10 分钟录像):149 个选秀 / 菜单关键帧被丢弃,162 个送去分析;决定延迟中位数 0.2 秒。

真实 App 视频模式(一段 5 分钟测试录像,3,001 帧):

版本 用时 自动识别次数 结果
全量行动条匹配 278 秒 13 敌方英雄蕾亚正确,取到我方基准;所有学派法术费用 −1,并据此给出来源推断(报告记为“消耗 / 召魂戒指”)
发布候选(由粗到细 + 复用) 173 秒 13 同上;退出无报错

此前一个发布候选在退出时有顺序问题(Qt 已删除的进程对象仍触发错误回调),已修复。

行动条提速(51 张截图):

方法 读数一致 总耗时(全量 → 新)
近似相同卡片复用 51/51 253 → 206 秒
由粗到细,保留 12 51/51 282 → 103 秒(第 2/3 名个别不同,未启用)
由粗到细,保留 24 51/51 271 → 129 秒
由粗到细,矩阵粗排,保留 24(采用) 51/51 265 → 103 秒

手动与自动对比:

局 方式 读取张数 识别用时 敌方英雄(最早认出) 敌方法术 我方基准
10-05 21:20 手动截图 15 98 秒 对(514 秒) 无(真值也无) 有
10-05 21:20 全部关键帧 466 3,169 秒 对(419 秒) 无 有
10-05 21:20 有界队列(App 实时) 159 922 秒 对(424 秒) 无 有
10-05 21:20 自动 + 手动 167 1,012 秒 对(418 秒) 无 有
10-05 22:02 手动截图 10 26 秒 对(606 秒) 无(真值也无) 有
10-05 22:02 全部关键帧 553 3,499 秒 对(417 秒) 召唤原始残骸、暗影军队 有
10-05 22:02 有界队列(App 实时) 141 642 秒 对(417 秒) 召唤原始残骸、暗影军队 有
10-05 22:02 自动 + 手动 142 642 秒 对(442 秒) 无 有

第二局“多出来”的两个法术是真的:在录像第 1,178 秒的日志帧上按像素核对过两行,敌方英雄咕噜先后施放了“召唤原始残骸”和“暗影军队”。截图包的 10 张截图没覆盖这段日志,所以截图包真值里没有。也就是说,自动模式比手动截图多找到了 2 次对方施法。

重复关键帧:用户第一次实战那局自动读取了 23 次,其中有同一生物面板的重复读取。新规则下,同一面板的变化格占 5–6%,不同面板、日志、战场至少 17%;跳过了第 6、14、15、23 张,其余保留。会话里的原始截图不删除。

失败与负结果

  • 有界队列会丢帧。 两局分别丢了 307 和 412 张关键帧,这是读取速度慢于画面的代价。
  • “自动 + 手动”反而丢了那张关键日志帧:截图键帧占了队列名额,把这张关键帧挤掉了。
  • 第一次对比运行(全量匹配、机器过载)在第二局读到 164/563 帧时为释放负载而停止,缓存的读取结果保留。
  • 由粗到细只保留 12 名时,第 2/3 名个别结果不同,未启用。
  • 重复帧判定第一版用“每格平均差 <3 灰度级才算重复”,结果一张都判不出来:战场和头像有待机动画,最大格差在 12–80 之间。

局限

  • 只有两局测试录像;真值只来自截图包,“法术”列不能直接当作对真值的漏报或误报。
  • 全部关键帧方式的识别用时(约 3,000 秒以上)远不能实时。
  • 行动条提速是在机器满载时测的;不是延迟验收。

结论与下一步

不按截图键的自动分析在这两局里认敌方英雄更早,也能发现手动截图漏掉的施法。主要问题是读取跟不上画面导致有界队列丢帧,而且手动截图会和自动关键帧争抢队列名额。后续工作集中在实时模式下怎样把更多帧送进选帧服务、以及缩短每次读取的耗时。