Communitygithub.com

zakezhang/tennis-video-private-coach-zh

分析网球练习视频并生成复盘报告:识别每一次挥拍、区分正反手、挑出最好和最差的几拍并制作带挥拍轨迹的慢动作标注视频,统计过网/下网(当能看清时),检查膝盖和脚步,与往次对比,并给出下一次练习的具体安排。适用于用户上传练球视频、要求复盘或询问“接下来怎么练”的场景。

tennis-video-private-coach-zh 是什麼?

这是一个专为业余网球爱好者设计的 AI 技能,能够将一段练习视频自动转化为结构化、可操作的复盘报告。技能全程以用户为中心,首先通过一系列问题明确球员身份、持拍手、练习场景和主要困扰,确保分析有针对性。技能的核心流程包括:视频转码与音频提取、使用 YOLO 姿态模型检测人体关键点、通过手腕速度峰值识别每一次挥拍并区分正反手、利用音频信号辅助定位击球时刻、统计过网/下网比例(在能看清的情况下)、评估膝盖与脚步等关键动作指标,最后自动挑选出正反手各最好和最差的 3 拍,并生成包含轨迹标注的慢动作视频。报告结构遵循“结论先行”原则,给出具体问题、证据、与上次对比,以及可量化、可执行的下一步练习计划。该技能支持练习墙、发球机、教练喂球和对拉等多种场景,适合初学者到中级水平,可在仅有 CPU 的环境中运行,但推荐使用 GPU 以获得更快处理速度。

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

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Tennis Video Private Coach · 中文版

把一段业余球员的练球视频变成一份能直接用的复盘:问题出在哪个环节、证据是哪几拍、下次具体练什么。面向初学者到中级水平,适用于练习墙、发球机、教练喂球和对拉。

需要的环境:能运行 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 帧,统一成 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,conf 0.3)就够;室外人多、人小,改成每 2 帧、imgsz 960、conf 0.25。
  • 选对人:只有一个人时取面积最大的人框。画面里有教练或其他人时,按衣服颜色打分:用两肩和两髋围成的躯干区域算 HSV 亮度和饱和度,用髋到膝区域算裤子颜色;再加上相邻帧位置连续的惩罚项,防止跳到别人身上。
  • 左右一律按画面 x 坐标判断,不要信模型的左右标签。身后机位时,人的右侧就是画面右侧。

2.3 找出每一次挥拍

  • 挥拍 = 手腕速度的峰值:两只手腕帧间位移取较大者,除以人框高度做归一化,2 点平滑,阈值约 0.16(按每 4 帧采样;采样更密时按比例调低)。
  • 两次峰值至少间隔 1.6 秒。间隔设 1 秒会把收拍后的回位算成第二拍。正常节奏是 3–4 秒一拍。
  • 正反手:峰值前 1.1 秒到 0.25 秒这段时间里,双手中点在髋部中线的哪一侧;在持拍手一侧就是正手。少量会误判,挑片段时逐帧确认。
  • 以下所有指标都以手腕速度峰值(记为 tp)为锚点,这样不同日期之间才可比。

2.4 用声音定位击球时刻

  • 1500Hz 高通滤波;按 110 个采样点一个窗口算能量包络;找比周围 401 个窗口中位数高 10dB 以上、彼此间隔不少于 50 个窗口的峰。
  • 时间换算必须用 窗口序号 × 110 / 22050。图省事乘 0.005 会每 4 分钟累计偏差约半秒,长视频后半段会全错。
  • 练习墙:在 [tp-0.1, tp+0.55] 秒内取最响、且高出 15dB 以上的峰,通常在 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 拍

  • 最好:结果好(过网高、落点深),同时动作完整(引拍到位、拍头先落到球下面、收拍完整、两脚踩地)。尽量分布在不同时间段。
  • 最差:下网、飞天或明显失误的拍子;不够就挑动作问题最典型的。优先挑原因不同、或能说明同一个共性的拍子。
  • 先看结果拼图挑候选,再看人物逐帧图(击球前 0.9 秒到击球后 0.5 秒)确认原因。挑反手最差时先确认不是单反。

2.9 做标注慢动作视频

  • 从原片切约 3 秒(击球前 1.1–1.5 秒开始),按人框裁成 16:10 左右、人占画面约 60% 高,缩到 1280 宽。
  • 逐帧跑姿态,人工确定四个帧:引拍最高点(top)、击球帧(contact)、路线起点和终点(去掉准备和回位)。自动找的击球帧经常错,一定要看图修正。
  • 每段视频的结构:
    1. 原速播一遍;
    2. 1/4 慢放,逐帧画出持拍手的路线(正手 = 持拍手腕,双反 = 双手中点,单反击球前用双手中点、击球后用持拍手),橙到青渐变,底部字幕分阶段说明;
    3. 引拍最高点定格约 3 秒,圈出位置(绿 = 对,红 = 有问题)加一行大字;
    4. 击球定格约 3 秒,白圈标击球点(自动位置常常不在球上,最好手动指定),黄圈标前侧膝盖并写角度(单反侧身时两腿重叠,不标);
    5. 整条路线定格。最差的几段再把当天最好那一拍从起点到击球的路线,按躯干长缩放、以肩中心对齐,用带黑边的绿色虚线叠上去,并写一句改法。
  • 编码 H.264、yuv420p、faststart、960 宽,每段 1–2.5MB。每段抽 4 帧拼图检查字幕有没有遮挡、圈的位置对不对。
  • 字幕不要用 ✓ ✗ 这类符号,很多中文字体缺字会显示成方框。

3. 报告结构

产出一个 HTML 页面(或用户要求的其他格式),顺序如下:

  1. 结论:直接回答用户这次最关心的问题;最大的进步、最大的问题、关键数字;对上次判断的更正。下面放一行统计(挥拍数分正反手、抽查下网率或“未统计”及原因、一两个核心指标)。
  2. 原因:把问题归成 2–3 类,每类配一个具体时间点的例子。
  3. 最好 vs 最差:4 组,每组 3 段视频、3 列对比表(引拍、落拍、击球点、收拍、脚、膝盖角度)、一句共性。
  4. 和上次比:最好一拍、最差一拍各变了什么,表格加两次视频并排。
  5. 单手反手(在练时):统计、要点表、好的 3 拍、错的 3 拍、逐拍列表,以及要不要继续练的建议。
  6. 膝盖与脚步:指标表,风险按“优先 / 观察 / 好转”列出,每条附改法。必须写明“不是医生”,并提示出现肿胀、卡住、发软无力或一周不见好时去看运动医学科。
  7. 下一步练什么:见第 5 节。
  8. 拍摄建议(这次素材有缺口时)。
  9. 页脚:数据来源、样本量、测量口径、机位局限。

设计建议(可选):网球主题配色,硬地蓝做主色,网球黄只用于关键数字和高亮,草地绿表示“好”,红土色表示“有问题”。数字和时间用窄体字,有记分牌的感觉。浅色和深色模式都要能看清,手机宽度下不能横向溢出。

4. 常见问题模式和改法

先按下面的模式归类,再用视频里的具体拍子说明。

现象常见根因视频里怎么认改法
正手下网、从上往下扫引拍举过头、大绕环,落拍来不及引拍最高点手高过鼻子,拍头在头后面引拍停在肩高、拍头指向身后;急球缩小引拍
球飞天、出底线挥拍路线太竖;高球站在原地从膝盖往上拉;收拍冲头顶收拍拍子在头顶正上方;击球高度接近肩收拍往前送,正手到非持拍侧肩、双反到持拍侧肩后;高球退一步等它落到腰高,或上前在弹起前打
击球点忽前忽后准备晚:宽球伸手去够(偏后、离身体远),急球在身体侧面甩击球时手臂伸直、人往外倒;或拍子几乎没往后拉对方击球时分腿小跳,球第一次落地时已经侧身、拍子在身后;大步到位、小碎步调整
双反下网或推不出去拍子竖着举在胸前或肩上,落拍来不及引拍时双手高过肩、拍头朝天拍子先平放在非持拍侧腰部等球,拍头在击球前落到手下面
跳着打、单脚落地站得太窄、脚没停住就挥两脚间距小;击球帧双脚离地;打完一条直腿接住体重最后一步先刹住,两脚踩地再挥,打完再迈步
反手转身时膝盖不舒服前脚钉死在地上、腿直着转身击球后前脚不动且膝角大于 155°前脚掌顺势转开,膝盖和脚尖同向
单反引拍晚或太高先摆成双反再临时改单反;手举过头击球帧明显靠后;引拍时手在头上方球离开对方拍面就决定用哪种反手;单反引拍停在身后、手在胸口高;单反放在固定专项时间里练,不在对拉中临时切换
室外比室内差很多室外球更快、弹得更高,习惯了室内的低慢球击球高度偏高;准备时机变晚用发球机或教练专门喂高弹跳的球,练“退一步”和早准备

5. 下一步练习怎么写

  • 按场景给方案:
    • 练习墙:先固定站位、固定节奏,再加左右移动。
    • 发球机:先固定落点,再有规律地变(正反手交替、一深一浅),最后才开随机。随机落点练的是判断方向;如果用户的问题是准备晚、脚没停稳或判断不准高度距离,过早开随机只会让他更赶、把毛病练牢。要模拟室外,就把出球角度调高、开中等上旋,让球弹到胸口高;间隔先 3.5–4 秒,熟练后再缩短。
    • 教练喂球:请教练专门喂暴露问题的球(高球、宽球、急球)。
    • 对拉:只盯一两个要点,不要同时改很多。
  • 每个练习写清:做什么、注意哪一点、多少球或多少分钟、怎么算做到了。
  • 给可数的目标,例如“50 球里有多少球两脚落地且收拍停在肩上”,下次复盘就用这个数对比。
  • 给进阶条件,例如“10 球里 8 球做到,才加速度或开随机”。
  • 一节约一小时的参考结构:热身和无球挥拍 5 分钟 → 主要问题的固定球 15 分钟 → 另一侧固定球 10 分钟 → 前后或左右的规律变化 10 分钟 → 正反手交替 10 分钟 → 满足条件才开随机 10 分钟。
  • 一周安排要考虑恢复,有伤病史时不要连续多天高强度,隔天轻量或休息。
  • 建议每次录一段侧面视频(5 分钟、腰高、网外),下次复盘能看清击球点前后和膝盖角度。

6. 拍摄建议(可以直接发给用户)

  • 身后机位:手机高 1.2–1.5 米,正对中线,全身和球网都在画面内。适合统计过网/下网和左右站位。
  • 侧面机位(最有价值):持拍手一侧网外 3–4 米、腰高,镜头垂直于击球方向。能看清击球点前后、拍头落多低、膝盖角度、有没有跳起来。
  • 正面斜角:前方角落网外、低机位,看脚尖和膝盖是否同向。
  • 设置:横屏,全身入镜,脚下留空间;4K 60 帧或 1080p 120 帧(30 帧拍子会糊);锁定对焦和曝光;尽量拍连续的几分钟,不要拍很多十几秒的短片段。
  • 室外:少拍树和天空、多拍对面场地,否则球几乎找不到。

7. 回复用户

先给结论和这次问题的直接答案,再按“原因 → 最好 vs 最差的共性 → 和上次比 → 膝盖脚步 → 下次练什么”简述,不复述报告全部内容。说明样本量和看不清的部分。语气直接、具体,像一个认真看过录像的教练。

Individual skills in this repo

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

相關技能