状态:草稿(2026-10-18),实测。考场的准确率是模拟器内部的相对比较值。 所有计算均在单台 Mac(Apple M1 Max 10 核,Python 3.9.6,numpy 2.0.2)的 CPU 上完成,未使用 GPU 和集群。未下载新的软件包、图像或数据。 校准和考场测试是固定随机种子(Seed)的确定性执行,因此各运行了一次(相同的命令产生相同的结果),处理时间为重复 5 次的中位数。处理时间是在 Mac 运行其他任务、负载平均值处于 47–76 时测得的。 实际视频使用了公开数据集 OpenTTGames(120 fps,包含人工标注的球坐标和反弹标记)及其扩展标签,两者均遵循 CC BY-NC-SA 4.0 协议。通过此数据校准出的物理参数以及使用该参数绘制的图表(回弹系数图)也遵循相同的条件。 原始数据(校准结果、24,300 行考场判定数据、实际标准表结果)位于工作目录
measure/tt-twin/中。
目录
- 1. 直觉:拥有标准答案的练习场
- 2. 实物校准:1,777 个真实反弹片段
- 3. 拥有标准答案的裁判考场:24,300 次判定
- 4. 改进闭环:轨迹补全
- 5. 扩展 AI 裁判:重力标尺与按规则分类的判断表
- 6. 局限性
- 7. 下一轮迭代
- 参考
1. 直觉:拥有标准答案的练习场
为了改进摄像机记分牌的裁判功能,我们需要收集大量的“错误判定”。实际比赛视频中的标准答案标签很少,像擦边球或遮挡这样罕见的场景几乎没有。 如果在模拟器中,物理引擎知道球落在了哪里,因此我们可以随心所欲地创建所需的场景并展示给裁判。这就是 标准答案考场。
但是,如果考场中的球飞得与真实球不同,测试就会找出错误的弱点。因此,我们将步骤分为了三部分:
- 实物校准(real2sim): 使用真实反弹来校准模拟器的物理参数。
- 考场: 使用校准后的物理参数生成场景,输入到运行判断代码中以找出弱点。
- 改进闭环: 修复一个最大的弱点,并且只有在模拟器和实际视频中 同时有所改善时才予采用。
2. 实物校准:1,777 个真实反弹片段
2.1 方法
- 设置相机。 利用球台的四个角确定每场比赛的相机姿态。由于四个角位于同一平面,无法确定焦距,因此将其固定为 1,400 px(水平视场角约 69°),并分别测量了 ±20% 的敏感度。角的重投影误差为 1.0–4.0 px。
- 校准反弹片段。 对于每个反弹,校准 11 个未知数,包括接触时间、接触点、入射/出射速度以及上旋等。接触点受限于球台平面,且飞行过程遵循重力、阻力和马格努斯效应,这些约束确定了单目相机无法直接看到的深度。
- 划分。 校准按比赛单位划分,包括用于训练的 5 场比赛的 1,537 个片段,以及用于评估的 7 场比赛的 240 个片段。
- 物理。 使用与运行合成装置相同的公式(回弹系数 e = e0 + e1·v_z,滑动/滚动边界 2/5,随速度和旋转变化的阻力/马格努斯系数),仅将回弹、摩擦、阻力乘数和马格努斯乘数作为参数进行求解。
最初,我们尝试通过减少“仅观察反弹后 50 毫秒来预测下一次反弹”的误差来进行校准,但由于测量噪声过大,回弹系数偏离了实际测量值(e0 1.09)。因此,我们放弃了该方法,改为先通过网格选择阻力和马格努斯乘数,然后直接对每个反弹测得的回弹系数进行回归的顺序。失败的方法也被记录了下来。
2.2 结果
| 项目 | 运行默认值 | 校准值 |
|---|---|---|
| 回弹 e0, e1 | 0.98, 0.02 | 0.982, 0.045 |
| 摩擦 μ | 0.25 | 0.160 |
| 阻力乘数 | ×1 | ×0.8(0.8–1.2 之间的差异在 0.02 px 以内,因此只能弱约束) |
| 马格努斯乘数 | ×1 | ×1.5(如果关闭,校准残差将加倍。如果大于 1,则与旋转大小互换而无法区分) |
| 30 厘米下落顶点(不计空气阻力计算) | 26.0 厘米(e 0.931) | 22.9 厘米(e 0.873) |
| 下落速度 | 实测 e 中位数,训练 5 场比赛(四分位数) | 实测 e,测试 7 场比赛 | 默认值 | 校准值 |
|---|---|---|---|---|
| 1.5–2.5 m/s | 0.894(0.781–0.991),n 692 | 0.911,n 93 | 0.939 | 0.889 |
| 2.5–3.5 m/s | 0.831(0.746–0.892),n 507 | 0.854,n 93 | 0.921 | 0.849 |
| 3.5–5.0 m/s | 0.838(0.753–0.880),n 176 | 0.830,n 30 | 0.902 | 0.807 |
实测回弹系数比运行合成装置的值低 0.04–0.07。ITTF 规定(2.1.3)规定,从 30 厘米处落下的球应该弹起约 23 厘米,通过视频校准得到的值向该标准(22.9 厘米)靠拢。 这与我们在第 2 部分中看到的 MuJoCo 的 DeepMind 球台数值(26.4 厘米)和运行默认值(26.0 厘米)都比规定更具弹性处于相同的方向。
2.3 然而,预测几乎没有改善
观察发球第一次弹地前的一小段和弹地后 150 ms 的轨迹,预测后续飞行,并与对手一侧的弹地(B2)进行对比。
| 比赛 | 物理 | 发球数 | B2 位置误差中位数 (p90) | 深度方向 | B2 时间误差中位数 (p90) | 时间偏差 |
|---|---|---|---|---|---|---|
| 训练 5 场比赛 | 默认值 | 207 | 22.7(47.4) cm | 18.8 cm | 24.6(68.3) ms | +9.7 ms |
| 训练 5 场比赛 | 调整值 | 207 | 22.9(45.5) cm | 16.2 cm | 24.1(68.6) ms | +3.1 ms |
| 测试 7 场比赛 | 默认值 | 23 | 21.3(37.4) cm | 20.3 cm | 22.5(52.8) ms | +5.7 ms |
| 测试 7 场比赛 | 调整值 | 23 | 17.4(31.4) cm | 9.9 cm | 13.1(45.7) ms | −0.6 ms |
(因预测触网而未能产生 B2 的发球不计入误差计算。训练集 55–59 个,测试集 7–8 个。)
- 测试 7 场比赛的改进并不显著。 发球仅有 23 个,且中位数的 95% 置信区间(2,000 次自助抽样)重叠:位置为 11.3–30.9 cm 对比 12.7–29.4 cm,时间为 6.6–32.9 ms 对比 8.9–38.3 ms。
- 调整减少的是 偏差(训练比赛时间 +9.7 → +3.1 ms),而离散程度保持不变。
2.4 大多数误差源于单台相机的深度估计
我们使用已知标准答案的重采样来衡量单目相机的局限性。以 600 个实际弹地调整结果作为标准答案,用调整后的物理模型重新绘制并投射到相机上、加入噪声,然后用相同的方法恢复(将其视为物理模型准确的下限)。
| 相机 | 前后帧 | 入射速度误差中位数,长度 / 深度方向 | 接触点误差中位数,长度 / 深度 | 上旋误差中位数 |
|---|---|---|---|---|
| 实际比赛相机 120 fps,人工标记 | 8 / 12 | 0.06 / 0.33 m/s | 0.3 / 0.5 cm | 51 rad/s |
| 记分牌视角相机 512×288, 60 fps | 6 / 6 | 0.09 / 0.67 m/s | 1.1 / 1.7 cm | 60 rad/s |
| 记分牌视角相机 512×288, 30 fps | 3 / 3 | 0.12 / 1.11 m/s | 3.1 / 3.8 cm | 116 rad/s |
- 仅凭一台相机也能很好地确定弹地位置。 在 60 fps 手机上误差为 1–3 cm。
- 深度方向的速度比长度方向不准确 7–10 倍。 飞行 0.3 秒会导致深度位置偏差 10–50 cm,2.3 节表格中的离散度正是这个量级。
- 无法准确测量旋转。 误差等于或大于实际旋转大小(DeepMind 数据中的中位数为 54 rad/s)。
- 由于 30 fps 只有前后 3 帧,在 600 个中只能匹配 157 个。
- 如果将假设的焦距更改为 1,150 / 1,400 / 1,700 px,实测的 e(2.5–3.5 m/s 区间)会变为 0.847 / 0.831 / 0.802。焦距的假设给恢复系数带来了大约 ±0.03 的不确定性。
目前深度误差掩盖了物理值的差异。若要同时确定马格努斯效应系数和深度,需要第二台相机或能看清球体纹理的高速视频。
3. 拥有标准答案的裁判测试场:24,300 次判决
3.1 我们构建了什么
- 物理。 在第 2 节调整值的基础上,增加了球台的边缘和侧面。将其视为厚度 25 mm 的长方体(估计值),如果击中顶面边缘的上方,则判定为擦边(根据 ITTF 2.1.2,属于比赛面,得分有效)。
- 9 种场景。 底线和边线周边(擦边、刚好以内、刚好以外)、擦网过去、发球擦网、双击、快速扣杀、高吊球、截击(接球方在球弹起前击球。在比赛面上方即为阻挡)、标准多拍相持。标准答案不是根据意图,而是根据物理引擎产生的接触顺序来确定的。
- 9 种退化条件。 理想(无噪声)、真实(实测检测噪声)、30 fps、120 fps、2 倍噪声、模糊、遮挡、漏检、手机(30 fps + 2 倍噪声 + 模糊 + 遮挡)。检测置信度取自 71,617 帧实际检测器的分布。
- 判决引擎。 运行判定代码的副本,使用与线上完全相同的开关原封不动地运行。每个场景 300 个,共 9 种条件,总计 24,300 次判决,在 Mac 上耗时 25 分钟。
为什么不使用渲染而是使用投影坐标。 判决引擎的输入是球的屏幕坐标,目的是找出引擎的弱点。在坐标层面上,可以在仅改变条件的情况下将同一场景运行数万次。 代价是 丢失了外观上的差异即是。球被背景、衣服、灯光淹没的情况,将球拍或手识别为球的情况,以及实际模糊痕迹的形状,仅作为检测器错误的概率模型进行了模拟。 实际上,测试场的基准回合(实际条件)准确率为 82%,低于用相同运行路径测量的实际测试 7 场清晰视频的 93%(54/58)。因此, 下表仅应作为场景与条件之间的相对比较来阅读。 切勿将绝对值视为实际准确率。
3.2 三大弱点
- 遮挡(Obstruction)16%(在所有条件下为 12–24%)。引擎没有“在对方击球落在我方半场之前于球台上方击球”的概念,因此大部分被识别为二次弹地(Two-bounce),并将分数判给对方球员。 同一引擎对越过底线后击球的截击(Volley)有 86% 的命中率,但这并不是因为它懂规则,纯属巧合。
- 擦边球(Edge ball)53%,未经确认直接判错 21%。 触及边缘的球在画面中不会绘制出 V 形弹跳。引擎无法看到弹跳并将其判定为出界。在出错的同时由人工确认的比例最低,这是最危险的格子。
- 发球擦网(Serve let)60%(遮挡 41%,手机 44%)。未能发现擦到球网的发球的速度减慢,将网前折射的球识别为弹跳,或者漏掉了接球方的弹跳。
其次是高吊球(进球)60%。球飞出画面上方或飞行超过 1.5 秒,导致“回合结束”被提前判定。不分场景的失败原因第 1 名是 球检测在空白处漏掉弹跳。
120 fps 比 60 fps 表现更差(77% 对 80%)。直觉上帧率高应该更好,但我们认为这是因为引擎的像素阈值和弹跳拒绝规则是针对 60/30 fps 调优的。我们并未单独分离原因进行测量(未实测)。 用实际 120 fps 视频的推理进行验证是下一步的工作。
4. 改进闭环:填补弹道
4.1 修改了什么
我们选择了测试场失败原因第 1 名——“球检测在超过 4 个采样(在 60 fps 下约 0.07 秒)的空白处漏掉弹跳”。先前的记录表明,在实际比赛中,许多漏掉的弹跳也走的是这条路径。
我们将 曲率由重力固定的抛物线拟合到空白处前后的轨迹片段中(曲率 = 该位置的画面比例 × 9.81,仅拟合斜率和截距)。只有当同时满足以下所有条件时,才会用前后的曲线填补空白处:
- 前段下降,后段上升。两条曲线在空白处内相交。
- 交点的水平位置在前后两端均符合乒乓球台长度的 4% 以内,且水平方向保持不变(若颠倒则是击球)。
- 交点位于乒乓球台顶面带内。空白处在 0.3 秒以下,前后片段均在 3 个采样以上,抛物线残差在 2 px 以下。
填补点的置信度设为两侧的一半,该弹跳将转交人工确认。阈值是通过物理原理预先确定的,并未根据测试结果进行挑选。
(图为展示原理而制作的合成轨迹,并非实际判定结果。)
4.2 在模拟器中
| 条件 | 正确基准 → 变更 (/2,700) | 变好 / 变坏 | McNemar p |
|---|---|---|---|
| 理想 | 2,392 → 2,391 | +0 / −1 | 1 |
| 实际 | 2,159 → 2,209 | +57 / −7 | 7.6e−11 |
| 120 fps | 2,075 → 2,163 | +98 / −10 | 2.7e−19 |
| 遮挡 | 1,671 → 1,826 | +223 / −68 | 2e−20 |
| 手机 | 1,512 → 1,548 | +63 / −27 | 0.00019 |
| 整体 (24,300) | 17,900 → 18,483(73.7 → 76.1%) | +778 / −195 | 5.3e−83 |
未经确认直接判错的判定从 1,215 减少到 996。不过, 边缘球(53.1 → 49.9%)和遮挡(16.3 → 14.6%)有所下降。 这并非本次修改的目标,将作为下一轮的课题。
4.3 在实际视频中(决定是否采纳的表格)
仅在模拟器中变好的修改不予采纳。因为测试场是去除了外观特征的近似环境,在那里变好的修改在实际视频中可能会变糟。 因此,我们直接沿用运行时的实时路径,重新运行了实际视频的固定基准表。
| 基准表 | 回合 | 正确基准 → 变更 | 变好 / 变坏 |
|---|---|---|---|
| 测试 7 场 × 12 个条件(清晰、昏暗、30 fps、低分辨率、模糊、干扰、手抖、遮挡、3 种手机画质) | 638 | 536 → 543 | +8 / −1, McNemar p 0.039 |
| 开发用(训练赛清晰、30 fps、坐标遮挡 15%,验证赛 8 个条件) | 1,394 | 1,217 → 1,238 | +36 / −15, p 0.005 |
- 在测试的 12 个条件中,没有变坏的条件(昏暗条件下的 −1 与同条件下的 +3 同时出现)。
- 曾经的难题——高吊球回合得到了正确修正。 测试赛 1 中持续 24.4 秒的高吊球是一个在球下落瞬间检测丢失、从而漏掉弹跳的回合。它在清晰、模糊、手抖和手机画质条件下都得到了正确的修改。
- 在开发用数据中,有 5 个条件各自有一个回合变糟。清晰视频中的两个回合是:在得分结束后,掉落到摄像机前方的球在画面中显得位于台面上,从而弹跳被填补。这依然是单目深度模糊的问题,且两个判定的置信度都是 0.44,因此会转交人工确认。
- 处理开销从每采样 p95 0.445 增加到 0.545 ms(训练赛 3 场清晰),增加的部分在 0.1 ms 左右。在 5 ms 的实时预算之内。
判定:采纳。 不过在运营中,该功能将 保持开关关闭 的状态接入。如果关闭,则计算方式与以往相同,判定不会改变。 在开启之前,我们将通过摄像机记分牌的 E2E 记录(用虚拟摄像机以 30 fps 记录并复现测试 7 场比赛),在实时路径中再次确认“不比运营表现差”,并共同检查上述“掉落到摄像机前方的球”这类情况。
5. 扩展 AI 裁判:重力尺与按规则分类的判定表
5.1 重力尺
发球抛球离开手后必须向上升起 16 厘米以上(ITTF 2.6.2)。然而,由于单台摄像机无法得知到球的距离,因此没有将画面的像素转换为厘米的比例尺。 此时,重力就成了尺子。将离开手的球的画面高度拟合为关于时间的抛物线 y = a·t² + b·t + c,则 a = g·s/2,其中 s 是在该球的深度下 1 米对应的像素数。 这样一来,高度就可以通过“像素差 ÷ s”来测量,并且通过深度(焦距 ÷ s)也能得出球的三维位置。
- 实测。 在实际比赛视频的 80 个发球抛球中,以此测得的比例尺中位数为 330 px/m ,而通过摄像机几何结构求出的网前比例尺在四场比赛中为 303–335 px/m 。重力尺在实际视频中同样准确。
- 局限性。 规则中的 16 厘米是从离开手的一瞬间开始算起的。如果在合成测试中加入手将球向上托举 3–15 厘米后松手的动作(估计),16 厘米的判定准确率会降至 0.70–0.86,在边界 ±4 厘米内降至 0.59–0.66。 而在手不向上托举的理想条件下,该值为 0.99。仅凭球的轨迹很难准确捕捉“离开的一瞬间”。
- 在实际视频(60 fps,275 个发球)中,能够测量高度的发球有 80 个(29%)。由于没有标准答案高度,因此未能测量准确率。
5.2 按规则分类的判定表
原则是为每个信号赋予置信度,如果信号矛盾或确信度低,则转交给人工确认。“已测量”指本次实测,“未测量”指未实测。
| 规则 (ITTF) | 所需信号 | 已测量 | 未测量 | 一级判定 / 人工确认 |
|---|---|---|---|---|
| 抛球 16 cm 以上 (2.6.2) | 球(重力尺)、手离开的瞬间 | 包含手托举动作的合成测试中为 0.70–0.86,边界 ±4 cm 内为 0.59–0.66。实际视频中可测量的发球占 29% | 用手关节寻找离开瞬间,实际标准答案高度 | 人工确认。仅对明显过低的发球进行提示候选 |
| 抛球位置:底线后方、台面高度上方 (2.6.4) | 球(通过重力尺获取深度) | 合成测试 0.89–0.97,距离线条超过 10 cm 时为 0.97–1.00 | 实际视频标准答案 | 10 cm 以外一级,以内人工确认 |
| 手掌张开托球 (2.6.1) | 手关节 | 无 | 手关节模型 | 人工确认 |
| 发球无遮挡 (2.6.4–2.6.5) | 接球方视角可见球 | 无 | 仅凭侧面拍摄的一部手机,原理上无法得知 | 人工确认 |
| 发球擦网 (2.9.1.1) | 球(过网时速度减慢)、网声 | 测试场 60% | 实际手机声音 | 人工确认(由于是重发球,确认成本较低) |
| 擦边 (2.1.2) | 球(无 V 形的急剧折射)、边缘声音 | 测试场 53%,未经确认直接判错 21% | 实际擦边视频,侧面 (Side) 生成 0 例 | 必须人工确认 |
| 二次弹地 | 球 | 测试场 83%,填补弹道后 87.5% | 实际样本较少 | 一级 |
| 遮挡 (2.5.8) | 球(落地前方向反转的位置是否在台面上)、身体·球拍 | 测试场 16% | 实际标签 | 人工确认。接下来需要在测试场中测量“无弹跳方向反转 + 该位置在台面上”的规则 |
6. 局限性
- 测试场的准确率是去除了外观特征的近似值,因此比实际情况更严苛(基准回合 82% 对实际 93%)。表格仅作相对比较。
- 假设乒乓球台板厚度为 25 mm、边缘不圆润、模糊漏掉模型、噪声强度为 2、手向上托举 3–15 cm 均为估计值。在场景生成中从未出现过触碰球台侧面(Side)的情况。
- 摄像机焦距假设为 1,400 px(±20% 时 e ±0.03),旋转无法通过单目确定。
- 发球预测在调整前后的差异由于测试样本只有 23 个,不具有统计学意义。
- 实际基准表中的“未经确认直接判错”不是运营校正,而是用置信度小于 0.6 的规则计算出的代理值。处理开销是在 Mac 负载较高时测量的,需要在安静状态下重新测量。
7. 下一轮
- 开启填补弹道开关前的 E2E 确认。
- 边缘候选 → 人工确认。 在底线带内将“无 V 形且方向急剧折射”标记为边缘候选。首先测量测试场中未经确认直接判错是否减少、常规出界判定是否没有变坏。
- 遮挡规则。 从侧面看时长度方向较为清晰(2.4 节),因此根据方向反转位置的长度坐标进行判定。
- 测试场保真度。 按速度和位置重新测量实际检测器的误差以匹配噪声模型,并用实际 120 fps 推理来验证 120 fps 比 60 fps 表现更差的结果。
TT 小结。 我们在一个拥有标准答案的练习场中对裁判进行了 2.4 万次测试。修复了在那里发现的弱点后,只有在真实比赛视频中也有所改善时才予以采纳。因为只会闭门造车的裁判毫无用处!
参考
所有链接均已于 2026-10-18 确认可访问。
- ITTF 乒乓球规则 2026–27(公开副本): https://www.tabletennisengland.co.uk/content/uploads/2026/07/Laws-of-Table-Tennis-2026-27.pdf
- DeepMind 公开球状态(用于旋转大小时的比较): https://github.com/google-deepmind/competitive_robot_table_tennis(© 2025 Google LLC, CC BY 4.0)
- 实际视频资料:OpenTTGames 数据集及其扩展标签(CC BY-NC-SA 4.0)。本文匹配的物理值与恢复系数图表遵循相同条件(CC BY-NC-SA 4.0)。
- 上一篇: 第2篇:在 MuJoCo 中复现乒乓球物理特性, 第6篇:DeepMind 乒乓球机器人改进方向