游戏里的单位即使没有行动,也会呼吸、振翅或冒火。反过来,一次重要变化可能只发生在很小的区域:鼠标指向一个技能,旁边多出几行文字,整张战场图却几乎没变。如果只按固定时间截图,就容易留下运动中间态,也容易漏掉值得读取的提示。

我们要从视频自动选出适合标注和识别的原图:同一内容持续稳定时,最多保留一个代表帧;内容改变后,再寻找新的代表帧。 短暂的文字提示也要保留。这里的输入是视频,输出是候选图片、来源时间及选择原因;识别生物、读取文字和解释伤害是后续任务。

这轮先标注96组五帧片段,比较全图帧差、局部特征逻辑回归和局部特征Extra Trees。选中的模型在按视频轮流留出的开发比较中判对89组;接收的49组里有47组确实稳定。长视频也跑通了,但抽查暴露了菜单动画被过度切段的问题。窗口分类和长段选帧,必须分开验收。

flowchart LR
 V[Source video] --> W[Five-frame stability model]
 W --> S[Merge runs and check content changes]
 S --> R[One native representative per candidate run]
 V --> D[Independent dense change scan]
 D --> C[Short-event candidates]
 R --> A[Scene and element annotation]
 C --> A

图1:两条供样路径共用原视频。稳定门决定何时适合重复使用一个代表帧,不负责宣判其他时间没有重要信息。

1. 稳定,指内容稳定

在这个回合制战斗游戏里,单位占据六边形格子。下面第一组中,单位姿态改变,但落点和数量牌锚点不变;第二组中,单位真正跨格移动。我们把前者标为STILL,后者标为CHANGED

五帧中的原地待机动画

图2:clip-63,雪地战场,3502.0秒开始。振翅不是移动。可查看第一帧原图第五帧原图

五帧中的跨格移动

图3:同一来源的clip-37,3528.8秒开始。身体和数量牌一起移位,是变化样本。第一帧原图第五帧原图。缩略拼图便于比较,原图保留2560×1440像素。

每组取5帧、5 fps,只标这五个采样点,不要求另看完整一秒。首尾相隔0.8秒,也不保证采样点之间没有更短事件。

数据批次 组数 稳定 变化 审核来源
前两批 64 24 40 用户已确认
新增批次 32 28 4 助手逐组目视审核
本轮训练合计 96 52 44 7段视频、480张原图

新增批次重点补待机动作,也含持续特效、已经打开且不再变化的提示/面板和真实变化对照。它不是32组全都没有面板的战场。原有用户标签保持不变;少数旧备注与最终标签不同,训练以最终标签为准。

STILL也不等于“所有内容都能读”。一个遮住生物的提示框可以一直不动:它对生物识别造成遮挡,对提示文字识别却正是目标。稳定性、场景类别和任务区域可读性是三个不同判断。

2. 从全图平均变化,到局部变化

第一种方法最直接:比较相邻图像的像素差,变化小就认为稳定。它运行便宜,但大面积背景和小块提示会争夺同一个分数。我们因此保留局部位置,尝试两种小模型,不在这一步使用OCR或预先提供scene标签。

方法 程序实际看到什么 怎样判断
全图帧差阈值 五张缩小后的完整截图 取相邻帧平均变化的最大值,低于阈值就接收
局部特征逻辑回归 同一输入,43个局部变化统计 学习各统计的权重,再给出稳定分数
局部特征Extra Trees 同样的43个统计 多棵随机化决策树组合不同区域的条件

三种方法都把2560×1440原图缩成320×180灰度图,做3×3平滑。只屏蔽左右上角很小的计时/头像区域,避免计时变化支配稳定判断;上方行动条和下方技能栏仍保留。完整计时读取属于另一个任务,不能因为这里屏蔽了计时,就在最终系统里丢掉它。

局部特征来自六个固定区域,包括战场内部、中央书页、左下日志、底部技能和行动条,再加8×6分块统计。既看相邻帧差,也看首尾差。例如,中央书页变化很大而底部不变,与整屏淡出产生的分布不同。这里的固定区域是宽泛的位置提示,没有使用人工文字框或生物框。

逻辑回归学习一个加权组合;Extra Trees可以表示“这个区域有变化,同时另一个区域保持不变”等组合条件。本轮后者使用200棵树、最大深度5、最小叶节点2;逻辑回归在训练折内标准化,正则参数C=0.2。两者都把变化样本的训练权重设为稳定样本的两倍。

3. 判对多少,错在什么方向?

采用按来源视频轮流留出:每轮用六段视频的样本训练,预测剩下一段。这样同一视频里的相邻窗口不会直接分到训练与留出两边。不过这七段来源都已经用于开发,模型和阈值也根据这些结果选择;尚未按独立对局和重复录像进一步隔离,因此以下不是最终独立测试成绩。

方法 判对/96 接受样本中的稳定比例 找回稳定样本的比例 动态误放行 稳定误拒绝
全图帧差阈值 86 44/46,95.65% 44/52,84.62% 2 8
局部逻辑回归,阈值0.5 88 50/56,89.29% 50/52,96.15% 6 2
局部Extra Trees,阈值0.5 89 47/49,95.92% 47/52,90.38% 2 5

“接受样本中的稳定比例”是稳定精确率;“找回稳定样本的比例”是稳定召回率。两种错误代价不同:错过一个稳定窗口,还可能等到下一帧;把变化窗口误当稳定,可能给下游错误的图标或数字。因此本轮用3×动态误放行+稳定误拒绝选模型。3∶1是一个明确的工程假设,尚未用实际下游损失校准。

我们同时比较阈值0.5和0.8。Extra Trees在0.8时只误放行1组,但会漏掉12组稳定样本;按上述代价,0.5仍较合适。这个分数也不是“该窗口有95%概率稳定”一类经过校准的概率。

行动和范围变化被模型误接收

图4:clip-74是一个真实失败。变化集中在回合提示和行动范围,模型仍把它接收为稳定。另一个误放行是英雄卡片刚出现hover高亮。错误不能只用全屏看起来相似来解释掉。

原64组上,两种学习模型都判对62组;加入更难的样本后,分母和分布改变了,不能用62/64与89/96声称扩样让百分比提升。新增数据的价值,是让我们看到了更多原地动画、局部变化和稳定面板上的错误。

4. 五帧判稳,不代表长片段已经处理好

视频端按5 fps滑动取五帧窗口。连续接收的窗口合成一段,拒绝窗口和时间缺口会切断它。每段选清晰度最高的中心采样帧,同分时靠近中点;段再长也不会每隔几秒重复导出。

但只比较相邻帧不够。一个提示框缓慢出现,相邻图都很像,整段内容却已经变了。第一版在约38分29秒的录屏中合成106段;抽查长魔法书段后,我们加入“与当前段起点比较”的外观变化检查。第二版得到318段,每段一张2560×1440原图。

菜单、选择页、魔法书与战场的候选代表帧

图5:从第二版按候选序号间隔抽查16张。上半部分大量相似菜单,直接显示了过度切段问题;不能只展示下半部分成功选出的战场。

新检查使用160×90灰度图的8×6局部块,与段起点的最大块差超过0.065就切段。它修补了缓慢变化遗漏,却也会受移动云层等背景影响。目前“一段一帧”保证的是算法划出的段,不是已经标注正确的真实语义稳定段。 开头约200秒菜单被切成许多相似片段,这还需要长片段参考和更好的任务区域判断。

完整视频输出 数量与含义
5 fps采样 11,547张
第二版稳定区间候选 318段,每段1张原图
原帧率变化分支 检查69,279张30 fps缩略帧
短暂变化候选 198张,尚未证明都是重要提示

密集分支独立运行,不等待稳定门。它在320×180图上找局部变化,阈值0.015,候选间隔至少0.35秒。当前候选图片只是缩略预览,正式标注时回原视频提原图。更小的文字或更短的事件仍可能漏掉,所以198不是已测出的提示召回率。

稳定分支截图数减少97.25%,但这个比例没有算入198张变化候选,也没有衡量重要内容是否保留。最长候选段222.6秒,尚未完整审核。下轮必须直接标注真实可用区间,测每段是否选到图、是否重复切段和哪些提示完全没选到。五帧分类成绩不能替代这些指标。

5. 速度:模型预测很轻,视频读取更贵

以下在AMD Ryzen 9 9900X 12-Core CPU运行。96组共480张原图,读取、缩放及特征提取6.661秒;七折比较和最终模型训练0.677秒。模型常驻后,批量预测平均每窗口0.040毫秒,不含图像处理。新进程内测到导入及模型加载0.797秒,不含解释器启动,也不是完整冷处理时间。

第二版处理整段38分29秒视频 耗时
已有5 fps缓存检查 0.027秒
顺序读取缓存和提特征 27.969秒
批量模型预测 0.029秒
导出318张原尺寸图片 14.180秒
读取密集缓存、筛选并写候选 21.247秒
整个运行,含其他开销 64.387秒

第二版复用了已经生成的两份缩略视频缓存。第一版从冷媒体缓存开始,总耗时176.374秒,但它导出的是106张稳定代表帧,配置和输出数量也不同。因此不能把176→64解释成算法本身加速;第二版完整冷缓存耗时尚未测量。以上也没有包含OCR、scene分类和日志解析。

复现入口与版本

源码在Desktop的olden-era:perception/experiments/b033_stable-segment-keyframe-mining/README.md给出PowerShell训练、视频运行及测试命令。results/reviewed96-input.json冻结原图路径、来源时间、最终标签和审核修订;reviewed96-model.json保留每个样本的折外分数、环境和首次计时。

训练入口支持--snapshot,重跑冻结输入已复现相同分数和模型选择。OpenCV 4.14.0、scikit-learn 1.9.0;源码提交后由Git记录版本。模型和完整媒体留在本地数据目录,博客不把它们当作公开下载的数据集。

6. 短提示可以直接成为训练原图

魔法书上的可读法术说明原图

图6:一张原尺寸法术说明截图。即使显示时间短,只要文字清晰,也可以标注。这里没有标完整出现/消失时间,不能把这张图当作已验证的短事件召回证据。

下一步的场景表达包含三层:战斗 → 魔法书 → 法术说明;或者战斗 → 普通战场 → 对某个单位的目标预览。第三级描述当前交互细节,目标部队与数值归属另外记录。仅有“伤害”二字,不能判断它是法术描述、普通攻击预览还是战斗日志。

已经整理22张原图到同一个交互详情标注页:12张无额外详情,6张法术说明,2张技能说明,1张普通UI提示,1张确认框。它们包括英雄/单位面板、日志及过渡对照,全部有助手标签和来源;尚未训练三级分类器,也尚未在这22张中取得目标伤害预览正例。

短暂内容不限于魔法。普通攻击、生物/英雄技能、法术在指向目标时,都需要记录释放前画面实际显示的预计伤害。我们为此新建B034,把动作来源、目标对象、文字区域和数字联系起来;“预览过”不等于“已经释放”,显示的法术基础伤害也不等于针对这个目标的预计伤害。

供样方法也不预先定死:先测稳定帧能保留多少提示,再比较局部变化候选和OCR检索的新增覆盖。如果稳定采样已足够,可以简化;如果漏掉短提示,就保留旁路。首要目标是得到足够好的scene与元素标注,关键帧只是为此服务。 同一原图可以同时关联生物框、计时、英雄属性和提示文字,不必为每项任务重新截图。

本机可查看新增32组完整视频候选。后续先补长区间参考及攻击/技能/法术预览的正负例,再训练和比较;现有视频确实缺少某类时,再给出具体补录动作。