用 AI 记录每一次深蹲:健身姿态识别入门
从一颗摄像头到一份实时反馈,聊聊我如何用姿态识别把「动作对不对」这件事变得可被看见、可被纠正。
训练里最难的从来不是坚持一次,而是每一次都做对。一个人练深蹲,最缺的其实是一双能在旁边提醒你的眼睛。于是我想:能不能让一颗普通的摄像头,成为那双眼睛。
这篇文章记录我做 AI 智能健身助手时,姿态识别部分从零到可用的思路。它不追求炫技,只想把「动作对不对」这件模糊的事,变成可被看见、可被纠正的小步骤——像劈竹一样,第一节最难,之后顺势而下。
为什么是姿态识别
传统的计次 App 只知道你「动了」,却不知道你「动得对不对」。而大多数运动损伤,恰恰来自那些没被察觉的细节:膝盖内扣、腰椎代偿、幅度不够。
姿态识别的价值在于,它能把身体的关键点实时抽取出来,让「发力是否到位」这种主观感受,第一次拥有了客观的度量。
能被测量的东西,才能被温柔地改进。
整体流程
从一帧画面到一句提示,中间只需要四步。用一张图就能说清:
flowchart LR
A[摄像头帧] --> B[关键点检测]
B --> C[关节角度计算]
C --> D{是否达标}
D -->|是| E[记录一次有效动作]
D -->|否| F[实时纠正提示]
整个链路刻意保持轻量:检测在本地完成,不上传任何画面,既快又让人安心。
计算关节角度
判断深蹲是否到位,核心是膝关节的角度。给定髋、膝、踝三个关键点,我们用向量夹角求出膝盖弯曲的程度:
其中 是膝到髋的向量, 是膝到踝的向量。当 小于设定阈值时,说明蹲得足够深。
落到代码里,它其实很短:
import numpy as np
def joint_angle(hip, knee, ankle):
"""返回膝关节角度(度)。三个点均为 (x, y)。"""
a = np.array(hip) - np.array(knee)
b = np.array(ankle) - np.array(knee)
cos = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-8)
return np.degrees(np.arccos(np.clip(cos, -1.0, 1.0)))
def is_valid_squat(angle, threshold=95.0):
# 角度越小,蹲得越深;小于阈值视为一次有效深蹲
return angle <= threshold
1e-8 是为了避免除零;np.clip 则确保浮点误差不会让 arccos 收到超出 [-1, 1] 的输入。这些小心思,往往是稳定运行的关键。
阈值不是拍脑袋定的
不同身高、不同柔韧度的人,「标准深蹲」的角度并不一样。我采集了一小批样本,观察有效与无效动作的角度分布:
| 动作质量 | 平均膝角 | 建议阈值 | 提示语气 |
|---|---|---|---|
| 过浅 | 118° | > 100° | 「再往下一点」 |
| 达标 | 88° | 85°–95° | 「很好,保持」 |
| 过深 | 62° | < 70° | 「注意膝盖压力」 |
于是阈值从固定值,变成了一个会根据个人历史微调的区间。这一步之后,误报明显少了。
一些还没解决的事
- 侧面遮挡时,踝关节的关键点会抖动,需要做时序平滑;
- 光线很暗时检测置信度下降,得给用户一个诚实的「暂时看不清」状态;
- 计划把「一组动作」的节奏也纳入评估,而不只是单次。
这些留待下一篇慢慢写。做产品和练身体一样,忍耐便是必修课——先把一节竹子劈开,剩下的自然会顺。
如果你也在做类似的事,欢迎在评论里聊聊你的思路。
评论
0 条正在加载评论…