说明:本实验目录里没有原始报告,只有两段脚本。本文是补记:根据脚本、保存下来的结果文件(比较结果、生产回归回执、测试记录),以及项目历史文档中一份同日的诊断笔记整理而成。

摘要

战斗画面左上和右上角各有一个英雄头像,分别是己方和敌方的英雄。程序(路由器 router,把截图分给各个读取器的程序)会把头像裁下来,与游戏里 77 个竞技场可用英雄的标准头像逐一做模板匹配,最高分足够高、且领先第二名足够多,才给出身份。

在一组开发截图里,双方英雄身份都返回“未知”:最高分只有约 0.69–0.71,低于 0.75 的分数门槛。诊断发现一个几何问题:屏幕上的头像裁图是 194×226 的长方形,而标准头像是正方形,通用匹配函数会把长方形裁图直接缩放到 96×96,把画面压扁。

改法很小:匹配前用中性深色把裁图对称补边成正方形,其它一切不变。在 3 张截图、左右共 6 个裁图上,最高分升到 0.82–0.96,全部通过原有门槛,第一名候选与原来相同。随后这一改动以私有辅助函数的形式进入生产代码,91 项聚焦测试通过,原截图上的生产回归与开发比较逐位一致。

要回答的问题

  • 为什么这组截图里两个英雄身份都读不出来?是区域选错、阵营映射错,还是门槛太严?
  • 如果是头像几何变形,保持长宽比的补边能否在不改门槛的前提下让分数通过?

数据与来源

  • 一组 4 张开发截图(同一段 10 月 2 日 00:44 的录像),这是已经暴露过的开发数据,不是留出测试集,也不是新的独立对局。
  • 4 张图分别是:准备页(297 秒)、生物面板(350 秒)、布阵(360 秒)、战场(420 秒)。只有 420 秒的战场图属于路由器认可的“战场”布局;350 和 360 秒两张只作为诊断对照,不会写入任何身份。
  • 英雄标准库:77 个竞技场可用英雄的正式头像资源。
  • 左侧头像区域 [25,20,219,246],右侧 [2341,20,2535,246],在 2560×1440 原图上各 194×226 像素。

方法

先确认问题出在哪

读取已保存的路由结果(没有重新识别):420 秒图中两个英雄都被定位到,但身份为空。

侧 前三候选(模板相关分) 门槛判断
左(己方) 第一 0.70925,第二 0.38056,第三 0.36921 领先 0.32869 过 0.08;分数没过 0.75
右(敌方) 第一 0.68964,第二 0.52405,第三 0.46350 领先 0.16559 过 0.08;分数没过 0.75

这些分是模板相关系数,不是概率。阵营判断本身正确:左边的玩家头像匹配到 0.99167,确定左侧是己方;敌方的攻击、防御、法强、魔法值都已作为候选送到状态估计(SE,把读到的观察累积成对局状态和对手构筑推断的模块)中的“敌方英雄”对象,只是身份为空。

诊断笔记明确:没有证据支持“换区域”“改阵营映射”“降低 0.75 / 0.08 门槛”或“直接采用第一名”这些做法。唯一具体的假设是几何变形:通用匹配函数把长方形头像缩放到 96×96,而标准头像是正方形;它在 72/80/88/96/104 五种尺寸、内边框比例 0.22、中心 ±20 像素范围内搜索。变形在代码里可以看到,但它对分数影响多大,之前没有测量。

一次性的固定比较

  • 只读取 350、360、420 秒三张原图各一次,取左右共 6 个裁图。
  • 每个裁图跑两次完整的 77 英雄排名:一次用原样的匹配函数(基线),一次先用中性颜色 BGR (35,28,20) 对称补边成正方形,再交给同一个匹配函数。共 12 次排名。
  • 标准库、五种尺寸、中心搜索、排名方式和 0.75 / 0.08 门槛全部不变;不做整图搜索,也不缩小候选库。
  • 先要求 420 秒基线的分数和前三名与保存的原始结果一致,再看补边结果。
  • 运行限制:单线程 CPU,45 秒预算(40 秒截止),禁止加载神经网络 OCR 或深度学习框架;结果文件只写一次,原图前后大小与修改时间必须不变。

设置

比较只运行一次,正常退出,用时 1.313 秒:3 次原图解码、12 次排名,每次排名保留全部 77 个英雄的分数;OCR、神经模型构造、深度学习框架导入次数均为 0。420 秒基线的两侧前三名和分数都复现了原始保存结果。

结果

帧 / 侧 原始最高分 补边后最高分 补边后领先第二名
350 秒 左 0.70974 0.95951 0.56332
350 秒 右 0.68963 0.82722 0.30489
360 秒 左 0.70936 0.96015 0.57644
360 秒 右 0.68735 0.82344 0.30190
420 秒 左 0.70925 0.96011 0.58641
420 秒 右 0.68964 0.82609 0.30369

第一名候选在补边前后不变(左右各是同一个英雄)。补边后 6 个裁图全部通过原有门槛。这是诊断上的改善,不证明身份独立正确,也不意味着可以放宽对 350/360 秒画面的场景限制。

进入生产

经批准的最小改动:在英雄开局读取模块旁新增一个私有辅助函数,对英雄头像对称补边成正方形,再调用原有匹配函数。只作用于两条英雄路径(开局读取和战场可见读取);输出框仍是原图坐标,标准库、分数门槛、布局/顶部状态栏门槛、数据格式、默认值和候选状态都不变;生物、法术、装备的匹配器不动。

  • 聚焦软件回归:91 项通过(约 1.8 秒),其中 7 项新增:长方形和奇数尺寸裁图补边后保留每个原像素;正方形裁图保持旧判断;候选库内重复时仍为未知;无关图或完全遮挡的裁图仍不过门槛;空裁图直接弃权。
  • 原 420 秒图上的生产辅助函数回归:一次解码、两次排名,0.484 秒,0 次 OCR/模型构造;左 0.96011、右 0.82609,与固定比较逐位一致。

失败与负结果

原始问题本身就是一个失败:这组截图里双方英雄身份都读不出来。本实验没有出现新的退化。需要注意的是,那条生产回归只直接测试了私有辅助函数,没有重新跑完整路由器、SE 或 App。

局限

  • 全部是暴露过的开发数据,只有 3 张图、2 个英雄;没有读取留出数据,也没有针对它调参。不能说明在其它英雄、其它画面上的准确率。
  • 第一名候选的正确性来自目视资源与截图的比较,不是独立的参考标签。
  • 补边只解决长宽比变形,不负责定位头像或去掉底部职业徽记之类的遮挡。
  • 比较结果不是端到端时延,也不是热启动 p95。

结论与下一步

两个英雄身份读不出来的直接原因是匹配前把长方形头像压成正方形。保持长宽比的对称补边让 6 个裁图全部以原门槛通过,且第一名不变;这一改动已以最小范围进入生产,并有软件回归和单图生产回归。新截图包上的完整路由运行、以及独立参考标签下的准确率,仍需后续单独安排;固定比较不会在没有新范围的情况下重跑。