Communitygithub.com

zakezhang/tennis-video-private-coach

分析网球训练视频,生成包含慢动作回放和技术统计的教练报告。检测每一次挥拍,区分正手和反手,挑选最佳和最差击球,并渲染带挥拍轨迹标注的慢动作剪辑,还能统计过网/出界(当球可见时),检查膝盖和步法,与过往训练对比,并制定下一次训练的具体计划。

tennis-video-private-coach 是什么?

该技能旨在将业余球员的训练视频转化为可执行的教练报告。它利用计算机视觉和音频分析,自动检测视频中的每一次挥拍,区分正手、反手(包括单反和双反),并通过手腕速度峰值定位击球瞬间。技能会基于击球结果和技术指标(如引拍高度、膝盖弯曲角度、站位宽度等)自动挑选出3个最佳和3个最差击球样本,并为每个样本生成带挥拍轨迹和关键相位标注的慢动作剪辑。报告会指出技术问题、对比过往训练数据,并提供具体的改进训练计划。该技能支持对墙、球机、教练喂球等多种训练场景,并特别注重球员的膝盖和步法安全。需要Python 3、ffmpeg以及 ultralytics、opencv-python 等依赖库。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/zakezhang/tennis-video-review-public/tree/main/skills/tennis-video-private-coach

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

网球视频私人教练

将业余球员的训练视频转化为他们可以执行的复盘报告:击球的哪个环节出了问题,哪些镜头证明了问题,以及下一步具体该练习什么。专为初学者到中级球员设计,适用于对墙、球机、教练喂球或与搭档对练等场景。

环境要求:能够运行 Python 3 和 ffmpeg,并安装 pip 包(ultralytics、opencv-python、numpy、scipy、Pillow)。有 GPU 会更快,但不是必须的。

0. 首先提问(仅限你不知道的信息)

  1. 画面中的球员是哪个人:服装颜色、头发、位置。教练、搭档以及隔壁球场的其他人通常也会入镜。
  2. 惯用手,以及反手是单手还是双手(或者正在学习两者)。
  3. 水平和目标:打了多久球,想达到什么水平(例如,“能对拉并在年底前打完一局比赛”)。
  4. 训练环境:练习墙 / 球机 / 教练喂球 / 对练;室内还是室外。
  5. 摄像头:背后、侧面还是正面;手机高度;帧率。
  6. 伤病:近期膝盖、肩膀、手肘或背部是否有疼痛。如果有,会重点关注步法和落地情况。
  7. 他们最想解决的一个问题(例如,“很多球飞得远”或“我的击球点不稳定”)。报告必须首先回答这个问题。
  8. 过往报告(如有),用于对比。

1. 报告必须达成的目标

  • **以结论开头。**一句话说明最大问题和最大进步,然后详细展开。要具体,每一个批评都要有证据支持;不要只表扬。如果之前的复盘有错误,要明确指出。
  • **每一个判断都要有视频证据。**每个案例都要有带标注的慢动作剪辑,标注是画在球员真实视频上的,而不是火柴人动画。
  • 默认 4 个类别 × 3 个镜头:最佳正手、最差正手、最佳反手、最差反手(共 12 个剪辑)。每个类别需要一个 3 列的对比表格和一句话总结这三个镜头的共同点。如果一个类别可用镜头少于 3 个,请说明找到了多少个。
  • **将单手和双手反手分开。**如果球员两种都在练习,单反要单独成章,并且不纳入双反的统计数据。
  • 指出出问题的阶段:引拍 / 掉拍头 / 击球点 / 随挥方向 / 步法 / 准备时机 / 处理高球 / 正反手决策。
  • 始终检查膝盖和步法:腾空击球、单脚落地、在锁直的腿上转身。
  • 说明数据的局限性:样本量、不可读的击球数、摄像头角度偏差。如果某些东西看不到,就如实说,不要猜测数字。
  • 以球员可以执行的计划结尾:2-4 个训练项目,包含次数或时长,以及进入下一阶段的判断条件。

2. 管线

2.1 转码和提取音频

  • 4K HEVC 手机视频文件很大。创建一个宽 960 像素的 H.264 分析副本: ffmpeg -i IN.MOV -vf scale=960:-2 -r 30 -an -c:v libx264 -preset veryfast -crf 24 p.mp4 (有些手机录制的是 29.97 fps;强制设为 30 可以简化时间计算。)
  • 分别提取音频以定位击球声: ffmpeg -i IN.MOV -vn -ac 1 -ar 22050 a.wav
  • 将长视频以 4-5 分钟为一段进行处理,避免超时。对于很多短片段,先从每个片段中抽取一帧做成概览图,然后决定哪些是背后角度可用,哪些太远(后者只能用来观察技术动作)。
  • 对于对墙练习,还要沿球网线裁剪出一个放大的“墙”画面副本,用于判断过网/出界。

2.2 姿态估计

  • 使用 Ultralytics YOLO 姿态模型(yolo11n-pose.pt;追求更高精度用 yolo11m-pose.pt)。室内场景下,每 4 帧处理一次,imgsz 640,置信度 0.3 就够了。室外场景,人物更小、更多,每 2 帧处理一次,imgsz 960,置信度 0.25。
  • **追踪正确的人。**画面中只有一个人时,取最大的检测框。有教练或其他人在场时,根据服装打分:计算躯干多边形(肩膀+臀部)内 HSV 亮度和饱和度的中位数,以及髋部到膝盖区域(裤子/短裤)的颜色。对远离上一帧位置的检测施加惩罚,避免追踪对象切换。
  • 通过图像的 x 坐标来判断左右,而不是模型给出的左右标签。从背后拍摄时,球员的右侧就是图像的右侧。

2.3 找到每一次挥拍

  • 挥拍的定义是手腕速度的峰值:两个手腕中移动较多的那个的逐帧位移,除以检测框高度,经过 2 个样本平滑,阈值约为 0.16(适用于每 4 帧采样;如果采样更密集,阈值需按比例降低)。
  • **要求峰值之间至少间隔 1.6 秒。**间隔 1.0 秒会把随挥后的回摆错误地计为第二次挥拍。正常节奏是每 3-4 秒一次挥拍。
  • 正手或反手:在峰值前 1.1 秒到 0.25 秒的时间窗口内,双手连线的中点位于臀部中线的哪一侧。在惯用手一侧为正手。会有少量误判,在任何你选中的镜头中,都需要逐帧确认。
  • 将下面的所有指标锚定在手腕速度峰值上(称为 tp),以便不同训练之间可以相互比较。

2.4 通过声音定位击球点

  • 高通滤波 1500 Hz;计算 110 个样本窗口的能量包络;寻找比周围 401 个窗口中位数高出至少 10 dB 且间隔至少 50 个窗口的峰值。
  • 转换为秒数:window_index × 110 / 22050。 使用乘以 0.005 的快捷算法每 4 分钟会漂移约半秒,从而毁掉长视频的后半部分。
  • 对墙练习:在 [tp−0.1, tp+0.55] 秒内,取比背景噪声高至少 15 dB 的最大峰值,通常出现在 tp 后 0.2-0.35 秒。球撞击墙壁的声音大约在击球后 0.45 秒出现,也很响,不要选它。
  • 室外场景:教练击球和其他球场的声音会带来干扰。在 [tp−0.45, tp+0.25] 秒内搜索;如果没有符合条件的,就使用 tp。
  • 对于最终进入剪辑的每一个击球,都要通过查看视频帧来确认真正的击球帧。

2.5 检测单手反手(如果球员正在学习)

  • 在所有反手中,取 tp 后 0.7 秒内两个手腕之间的最大距离(除以躯干长度)。双反球员在随挥结束后双手通常仍在一起(距离通常小于 1.5);单反球员非持拍手会向后打开(距离通常为 2.0-2.5)。差距很明显;阈值设为 1.95 左右。
  • 近摄像头角度会产生误报;每个候选对象都需要通过视觉确认。
  • 对于每个单反击球,记录:引拍时手是否超过头顶,引拍是否过晚(像双反一样准备,最后一刻才向上引拍),击球时手臂是否伸直,随挥高度,以及击球结果。
  • 单反检查清单(每项包括:正确动作 / 本次训练情况 / 结论):用非持拍手扶拍颈做转体,引拍高度在胸和肩之间且拍头向后,拍头下降后自下而上挥击,身前击球且手臂伸直,非持拍手向后打开,随挥完成且保持,胸部不要过早转正,膝盖弯曲并迈步上步。从背后角度看不到握拍方式;建议球员找教练确认。

2.6 过网 / 出界计数(仅在球可见时)

  • 对墙练习:在放大的墙壁视频中标出球网线。对于每个击球,生成一个图块:击球后 30 帧内的移动黄色斑点,按时间从红到绿绘制,同时以另一种颜色绘制网线上方区域的运动(如帘子)。通过肉眼判断每个图块:帘子移动或球击在线以上 = 界内;球击中板子但帘子不动 = 下网;被球员遮挡 = 不可读。全自动判断与人类判断的一致性仅为 60% 左右,因此只能作为提示。
  • 采样:判断均匀分布在整个训练中的 100 个击球,排除不可读的,分别报告正手/双反/单反的数据。然后检查剩余的最可疑的 20 个击球,看错误是否集中在某段时间(通常出现在疲劳之后)。
  • 室外场景:背景有树木摇动或周围有很多球员时,基于颜色和运动的球检测通常会失败。不要报告百分比。在报告中说明原因,转而根据技术动作挑选最佳/最差镜头,并给出能使计数成为可能的拍摄建议。

2.7 技术指标(对每次挥拍测量)

指标测量方法揭示的问题
正手持拍手高于鼻子在 [tp−1.1, tp−0.25] 区间内,持拍手腕高于鼻子的帧占比引拍过高,挥拍弧线太大
双手高于肩膀在同一窗口内,双手手腕均高于肩部中心的帧占比反手握拍过高
最深膝盖弯曲在 [tp−0.6, tp+0.3] 区间内,前腿髋-膝-踝角度的最小值,取所有挥拍的中位数腿部太直(在背后拍摄角度下,前屈会被低估;只能与自身比较)
站位宽度tp 时刻两脚踝的水平距离 ÷ 躯干长度站位过窄通常与跳跃有关
落地锁直tp 后 0.7 秒内,一只脚踝移动少于 0.4 个躯干长度,且该侧膝盖角度大于 155°膝盖承受扭转负荷(常见于反手转身)
击球高度在 tp 前 0.07-0.2 秒,持拍手位置在臀部(0)到肩膀(1)之间的值高球有多少,以及球员是否主动调整位置
跳跃 / 单脚落地通过逐帧查看你回顾的镜头时肉眼判断尚无可靠的自动指标
  • 对于长时间训练,分别报告前半段和后半段的数据,以观察疲劳后哪些技术会崩溃。
  • 如果摄像头、场地或测量方法发生变化,要么用新方法重新测量旧视频,要么明确说明数据不可比。

2.8 挑选 3 个最佳和 3 个最差击球

  • 最佳:结果好(舒服地过网,落点深)且技术完整(引拍到位、拍头降到球下方、完整随挥、双脚落地)。在整个训练中分布选取。
  • 最差:下网、高射炮或明显失误;如果数量不足,就选技术缺陷最明显的。优先选择反映不同原因的镜头,或者共同证明同一原因的镜头。
  • 从结果图块中进行初步筛选,然后通过逐帧球员技术图(tp 前 0.9 秒至 tp 后 0.5 秒)确认原因。在挑选最差反手时,要确保它们不是单反。

2.9 渲染带标注的慢动作剪辑

  • 从原始视频中截取约 3 秒(从 tp 前 1.1-1.5 秒开始),以球员为中心裁剪至约 16:10 比例,球员高度约占画面 60%,然后缩放至宽 1280 像素。
  • 对每一帧进行姿态估计。手动选择四个关键帧:引拍最高点、击球点、以及绘制路径的起点和终点(不包括准备姿势和回动阶段)。自动检测的击球帧经常不准确,务必通过视觉检查。
  • 剪辑结构:
    1. 正常速度播放一次。
    2. 四分之一速度播放,逐帧绘制持拍手的路径(正手 = 持拍手腕;双反 = 双手手腕中点;单反 = 击球前为双手手腕中点,击球后为持拍手腕),路径颜色从橙色渐变到青色,底部有每个阶段的说明文字。
    3. 在引拍最高点定格约 3 秒,用圆圈标出该点(绿色 = 正确,红色 = 问题),并配上简短的标题。
    4. 在击球点定格约 3 秒:在击球点上画白色圆圈(自动识别常会漏掉球,请手动调整),在前腿膝盖处画黄色圆圈并标注角度(单反可跳过,因为侧向角度下双腿会重叠)。
    5. **定格显示完整路径。**在最差的剪辑中,叠加本次训练中同类最佳击球的路径(从路径起点到击球点),根据躯干长度缩放并在肩部中心对齐,用带黑色轮廓的绿色动画虚线表示,并附上一句纠正建议。
  • 编码为 H.264,yuv420p,faststart,宽 960 像素,每个剪辑约 1-2.5 MB。从每个剪辑中提取 4 帧作为联系表,检查说明文字是否遮挡了内容,圆圈是否在正确位置。
  • 在说明文字中避免使用 ✓ 和 ✗;许多 CJK 字体缺少这些字符,会显示为方框。

3. 报告结构

生成 HTML 页面(或用户要求的格式),按以下顺序组织:

  1. 结论:直接回答球员的问题;最大的进步、最大的问题、关键数据;对之前复盘的修正。下方是一个数据汇总条(各技术击球次数、采样过网率或“未统计”及原因、一两个关键指标)。
  2. 原因:将问题归纳为 2-3 个原因,每个原因附上一个带时间戳的例子。
  3. 最佳 vs 最差:4 个组,每组 3 个剪辑,一个 3 列表格(引拍、掉拍、击球、随挥、脚步、膝盖角度)和一句关于模式的总结。
  4. 与上次对比:以表格和并排剪辑的方式展示最佳和最差点球的变化。
  5. 单手反手(如正在练习):统计数据、检查清单、3 个好和 3 个差的剪辑、逐球列表,以及关于现阶段是否应继续练习的建议。
  6. 膝盖和步法:指标表和按“优先处理 / 关注 / 改善”分类的风险,每项附有纠正方法。明确指出这不是医疗建议,并建议如果出现肿胀、关节异响、无力或疼痛持续超过一周,应咨询运动医学医生。
  7. 下一步练习什么:见第 5 节。
  8. 拍摄建议(如果素材有缺口)。
  9. 页脚:数据来源、样本量、指标定义、摄像头限制。

可选设计方向:使用网球主题色板,以硬地球场的蓝色作为主色,仅关键数字和亮点使用球黄色,用草地绿表示“好”,用红土场的红色表示“问题”。使用紧凑数字以获得记分牌风格。确保在浅色和深色模式下均清晰可读,并且在手机上无需横向滚动。

4. 常见问题及纠正

首先用下表对观察到的问题进行分类,然后用具体镜头来证明。

症状常见原因在视频上的表现纠正方法
正手下网、向下挥拍引拍过高、挥拍弧线太大,来不及掉拍头持拍手在引拍时高于鼻子练习低引拍,强调从低到高的挥拍路径
……………………
反手击球不稳、出界引拍过晚或随挥不完整引拍动作匆忙,击球后手臂停止过早提前做转体引拍,强调完整随挥至肩膀上方

5. 下一步练习计划

计划必须具体、可执行,并且直接针对报告中指出的问题。

  • 练习 1: [描述一个特定练习,例如:用半西方式握拍练习 50 个正手落点,强调低到高的挥拍,目标是将球打到发球线和底线之间。](约 10 分钟 / 50 次)
  • 练习 2: [描述第二个练习,针对不同的问题。](约 15 分钟 / 80 次)
  • 练习 3 (进阶条件): 当在练习 1 中连续 10 个正手落点都落在目标区域时,进入下一个练习……
  • 练习 4 (可选): …

下次训练前的关键提醒:

  • [一个最重要的技术要点]
  • [一个关于身体状态或体能的提醒]

每次训练后使用本系统,以追踪进展并调整计划。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能