用 M4 Pro 跑羽毛球视频 AI 分析(二):TrackNet MPS 加速 3.2 倍、卡尔曼滤波补漏与自动回合剪辑

前言

在上一篇文章《用 M4 Pro 跑羽毛球视频 AI 分析:从满地踩坑到一键出图的复现笔记》中,我们把 Badminton-AI-Analysis 的五大核心模型(球场关键点、球员 YOLOv8 检测、姿态骨架、TrackNet 羽毛球追踪、击球事件识别)整合到了统一的 1000×1000 空间画布下,实现了单命令跑通端到端分析视频:

但在实际跑完整局比赛视频时,初版流水线暴露出了三个非常影响实用体验的痛点:

  1. TrackNet 在 CPU 上推理太慢 :10 秒(300 帧)1080p 视频光跑 TrackNet 就要 21.9s,跑一场 20 分钟的比赛要等大半天。
  2. 杀球瞬间羽毛球严重运动模糊导致漏检:高速扣杀时球托残影拉长,TrackNet 热力图峰值低于阈值,轨迹经常在最精彩的一拍断掉。
  3. 死球/捡球垃圾时间占比超过 65%:实战录播里有大量走动、擦汗、捡球时间,不仅浪费算力,回看视频时也很难快速定位精彩多拍。

趁着最近迭代 v1.1 版本 ,我把这三个问题一次性全部解决了,代码已全部开源更新至 GitHub: 👉 github.com/ychenfen/ba...


升级一:Apple Silicon MPS + FP16 混合精度,TrackNet 提速 3.22 倍

初版为了绕开 PyTorch 部分算子兼容性问题,默认将 TrackNet 放在 CPU 上运行。在 v1.1 中,我们对设备调度与推理循环做了三项针对性优化:

  1. 自动设备探测(cuda > mps > cpu) :在 Apple Silicon(M1/M2/M3/M4 系列)上自动启用 mps 后端。
  2. FP16 半精度推理(torch.autocast):利用 M4 Pro GPU 的原生 FP16 吞吐优势,在不损失热力图质心精度的前提下大幅降低显存带宽开销。
  3. Batch 滑动窗口推理 :将原本逐帧串行的 3 帧滑动窗口改为 batch_size=8 批量送入 GPU。

M4 Pro(24GB)实测基准对比(300 帧 1080p)

推理后端配置 TrackNet 耗时 折算帧率 (FPS) 相对提速比 轨迹像素误差
CPU(FP32,Batch=2) 21.9s 13.7 FPS 1.00x 基准
MPS(FP32,Batch=4) 8.4s 35.7 FPS 2.61x < 0.2 px
MPS(FP16,Batch=8) 6.8s 44.1 FPS 3.22x < 0.4 px

开启 --fp16 --batch-size 8 后,TrackNet 推理耗时直接从 21.9s 压到了 6.8s ,首次在 MacBook Pro 上跑出了超过实时(44.1 FPS)的追踪速度!


升级二:4D 常速度卡尔曼滤波 + 物理加速度门控,修复杀球断轨

羽毛球在空中飞行遵循受空气阻力影响的抛物线运动,但以下两种情况极易引起 TrackNet 失败:

  • 假阳性跳变(离群噪点):球网白带反光、球衣白色图案或场边广告牌被误判为球。
  • 短暂漏检(2~6 帧盲区):重杀初速度超过 300 km/h 时单帧严重模糊,或者球恰好飞过白色背景区域。

我们在 postprocess_trajectory.py 中新增了一套无需重新训练模型的轨迹后处理管线:

python 复制代码
# 1. 物理加速度门控:剔除单帧位移 > 120px 且下一帧不连续的伪检噪点
# 2. 状态向量 [x, y, vx, vy] 的 4D 卡尔曼滤波器平滑观测噪声
# 3. 针对 <= 6 帧的短时漏检窗口,结合三次样条插值补全并标记为预测态(空心圆渲染)

在渲染合成阶段,实测检出点使用实心亮黄圆点 绘制,卡尔曼滤波补偿帧使用半透明空心圆过渡,既保证了彩虹尾迹不断裂,又能一眼区分模型实测值与滤波插值。


升级三:基于轨迹活跃度的「有效多拍回合」自动剪辑

录一场球 30 分钟,真正打球的时间往往不到 10 分钟。我们在 v1.1 中加入了 --export-rallies 回合自动分割器:

  • 判定逻辑 :当滑动窗口(15 帧)内羽毛球有效检出率高于 45% 且帧间位移标准差 > 8.0 px(排除静止在地面上的球)时,触发回合开始;当连续丢球或静止超过 1.5s(45 帧)时判定本回合结束。
  • 自动切片与集锦 :自动过滤时长 < 2.5s 的发球失误或无效片段,调用 ffmpeg 无损导出每个独立回合(rally_01.mp4, rally_02.mp4...)以及合并版纯享集锦 highlights.mp4。

一键复现命令

只需克隆仓库并运行:

bash 复制代码
git clone https://github.com/ychenfen/badminton-pipeline-repro.git
cd badminton-pipeline-repro

# 一键开启 MPS + FP16 加速、卡尔曼滤波补漏与自动回合集锦导出
python run_pipeline.py \
  --input demo.mp4 \
  --output output_v1.1.mp4 \
  --device mps --fp16 --batch-size 8 \
  --kalman-smooth --max-interp-gap 6 \
  --export-rallies

总结与后续计划

目前 v1.1 已经把单机推理速度、轨迹连续性和自动集锦剪辑补齐。下一步(v1.2)计划利用球场单应性矩阵(Homography)将羽毛球落地帧投射到标准 2D 俯视球场,自动生成落点热力图(Shot Placement Heatmap)与杀球初速度估算。

如果你也在做体育视频分析、姿态估计或 Apple Silicon 本地推理优化,欢迎去仓库点个 Star ⭐ 或提 Issue 交流!

相关推荐
用户40199255686142 分钟前
基于对话树回溯的社媒评论流买方意图识别与噪音过滤实践
python
用户0332126663671 小时前
使用 Python 加密或解密 PDF 文档
python
小七-七牛开发者1 小时前
让 Go 走得更远:用 LLGo 打通 Go 与 C/C++/Python 生态
python·编程·编译器·llvm·llgo
CyrusYiVPP2 小时前
实测 Ollama 本地部署:我用 Python 搓了个离线问答机器人,Qwen4 27B 一到换个模型名就能用
人工智能·python
2601_967980113 小时前
Python中flatten( )函数及函数用法详解
python·numpy·数组操作·flatten函数·列表处理
xbzb3 小时前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo
合尘猫6 小时前
图片表格变结构化数据:OCR 后的三个坑
python·ocr
小小张说故事6 小时前
Python 里弱引用到底弱在哪:拆开 weakref.ref、回调陷阱和 WeakValueDictionary
python
用户019027581617 小时前
用 DuckDB 存查 A 股 K 线:零服务、SQL 直接分析
python