ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于PP-TinyPose的健身做操辅助工具:Python源码与姿态估计实战

2026/9/15 22:30:30 拓冰建站 浏览量
基于PP-TinyPose的健身做操辅助工具:Python源码与姿态估计实战 简介这套基于PP-TinyPose的健身做操辅助工具源码面向Python开发者、计算机视觉学习者及毕业设计选题学生聚焦利用姿态估计技术识别人体关键点辅助运动动作规范与科学训练。项目完整度较高共112个文件、压缩包约165MB主要包含38个Python脚本主程序、视频预处理、界面演示等、26个编译后的pyc文件、4组模型权重参数.pdiparams/.pdmodel、6个YAML配置文件、UI界面文件、JSON数据及MP4示例视频并附带项目说明与依赖列表便于快速搭建运行环境。当前已有104人学习下载适合作为人工智能或计算机视觉课程的实践项目。通过阅读和运行这套代码能够深入理解PP-TinyPose在真实场景中的调用方式、视频关键帧处理流程以及从模型推理到交互界面的完整实现思路为后续开展运动分析或智能健身应用开发提供扎实参考。1. 为什么健身做操辅助工具选择 PP-TinyPose先给结论我们不需要“看懂人在做什么”只需要知道“人做得到不到位”。健身做操辅助工具的核心是把摄像头画面里的人体骨骼抽出来再把肩、肘、腕、髋、膝、踝这几个关节的角度变成可计算的数字。PP-TinyPose 在这里的定位是轻量级姿态估计模型它能在 CPU 上跑出可用帧率对单人或小范围多人场景足够稳所以很多 Python 源码项目拿它来做健身纠错、跟练打卡和动作计数。标题里那个python开发基于PP-TinyPose的健身做操辅助工具程序源码.zip落地时其实不是一个大模型工程而是“姿态估计模型 动作规则 视频流控制 结果展示”的组合。我一般把它拆成四条线模型推理线负责出 17 个关键点坐标规则线负责把坐标换算成角度和计数输出线负责在画面上画骨架和提示打包线负责让源码 zip 在别人电脑上能解压即跑。这条线对新手友好对老手来说真正值得花时间的反而是角度阈值、状态机和计数的防抖逻辑。2. 先理解 PP-TinyPose 的姿态估计基础与工程取舍2.1 PP-TinyPose 在 PaddleDetection 全家桶里的位置PP-TinyPose 是 PaddleDetection 里常见的轻量级关键点检测方案。和 OpenPose 那种 bottom-up 思路不同PP-TinyPose 走的是 top-down 思路先从画面里检测出人框再在框内做关键点回归。这个思路意味着人越少效果越稳两个人互相遮挡时检测框重叠会直接拉低关键点精度。做居家健身辅助工具时摄像头正对单人是最理想的这点很关键。PaddleDetection 把 PP-TinyPose 和前置检测器打包成一套推理流程。前置检测器负责给人框PP-TinyPose 负责在每个人框里输出 17 个 COCO 格式关键点。工程上我们不需要自己写网络结构官方推理脚本已经完成了解码、后处理和坐标还原我们要做的是把关键点数组接到自己的逻辑里。源码 zip 里如果带着deploy/python/keypoint_infer.py那推理入口基本就在这。2.2 输入图像归一化与关键点输出格式关键点输出一般是一个[人数, 17, 3]的结构最后一维是x, y, score。x 和 y 已经还原回原图分辨率score 是关键点置信度范围 0 到 1。做健身辅助时我一般只取 score 大于 0.5 的骨架点参与计算低于这个阈值的点位置不可信宁可不算也不要拿噪声去算角度。模型输入前需要做归一化官方脚本会处理 resize、归一化和通道顺序。自定义推理时常见的错误是直接把 OpenCV 的 BGR 帧传给模型结果通道对不上。正确的顺序是cv2.resize到模型输入尺寸用cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)转 RGB再按模型配置做标准化。这个细节看起来小实际经常造成“检测框在但骨架乱飘”。2.3 为什么不用 OpenPose 或 MediaPipe 而用 PP-TinyPoseMediaPipe 也有姿态估计轻量且易用但它的输出逻辑和 Paddle 生态的解析方式不一样。OpenPose 精度高但是体积大、CPU 慢做本地源码工具并不划算。选择 PP-TinyPose 的主要原因有三个第一它能在 CPU 上用较短推理延迟跑出单路视频流第二PaddleDetection 自带导出和推理工具不用自己拼后处理第三如果后续要换国产加速硬件或用 PaddleLite 转部署同一套模型能少踩一遍格式坑。如果你跑的是健身做操辅助工具需要 25 帧左右的关键点输出才能让计数不卡顿。GPU 随意CPU 上则要控制输入分辨率一般 128x96 或 192x128 的输入足够判断大动作再高就会拖慢帧率。这里要提醒一点模型输入分辨率决定的是“人体姿态”的精度不是画面显示分辨率。显示可以 1080p推理输入缩到小图即可。提示在源码里看到tinypose_128x96或tinypose_256x192这类目录名指的就是模型输入尺寸 MMxNN前者更适合 CPU 实时后者精度更高但更慢。3. 搭建本地 Python 工程依赖、配置与最小推理代码3.1 建立项目目录并正确配置 Python 环境先不要急着双击运行先把环境做干净。项目目录我一般按“模型、代码、测试图片、配置”四块组织避免把权重和源码混在一起fitness_pose/ ├── .venv/ ├── model/ │ └── pptinypose_128x96/ ├── src/ │ ├── detector.py │ ├── skeleton.py │ └── counter.py ├── configs/ │ └── infer_cfg.yml ├── tests/ │ └── squat.jpg └── requirements.txt创建虚拟环境时用 python 安装教程里最常见的步骤即可cd fitness_pose python -m venv .venv source .venv/bin/activate注意 Windows 下激活命令是.venv\Scripts\activatemacOS/Linux 下才是source。激活后建议先把基础包装上pip install --upgrade pip pip install paddlepaddle opencv-python numpy其中paddlepaddle是 CPU 版带 GPU 的机器可以按自己 CUDA 环境换成paddlepaddle-gpu。这里我故意不装 pandas 之类的大包健身辅助工具的推理链路用不到。装完后跑python -c import paddle; print(paddle.__version__)确认环境能用后面所有报错都先回到这一步看是环境问题还是代码问题。3.2 用官方推理脚本验证模型是否连通推理入口不建议自己重写尤其是后处理那段。PaddleDetection 的deploy/python/keypoint_infer.py已经能把帧或者视频文件变成带关键点的可视化结果。先用一张手机拍的全身照验证模型和依赖python deploy/python/keypoint_infer.py \ --model_dirmodel/pptinypose_128x96 \ --image_filetests/squat.jpg \ --deviceCPU \ --threshold0.5 \ --save_diroutput/这段命令的参数含义--model_dir指向导出的模型目录目录里至少要有inference.pdmodel、inference.pdiparams和inference.yml--image_file是输入图片--deviceCPU强制用 CPU--threshold是关键点置信度阈值低于 0.5 的点不画--save_dir指定输出目录。如果这一步能生成带骨架的图片说明依赖和模型都通接下来才可以接入摄像头。3.3 把摄像头帧接入姿态估计主循环官方脚本能处理单张图但做操辅助工具要处理摄像头连续帧所以我会把它封装成一个可复用的检测器。核心循环如下import cv2 from detector import PoseDetector det PoseDetector( model_dirmodel/pptinypose_128x96, deviceCPU, threshold0.5, ) cap cv2.VideoCapture(0) if not cap.isOpened(): raise RuntimeError(无法打开摄像头检查索引 0 是否被占用) while True: ok, frame cap.read() if not ok: break keypoints, scores det.infer(frame) for idx, (x, y) in enumerate(keypoints): if scores[idx] det.threshold: cv2.circle(frame, (int(x), int(y)), 4, (0, 255, 0), -1) cv2.imshow(fitness_pose, frame) if cv2.waitKey(1) 0xFF 27: break cap.release() cv2.destroyAllWindows()PoseDetector内部负责调keypoint_infer.py对应的 Python API整个循环只要关心三件事读帧、取关键点、画骨架。cv2.waitKey(1)括号里的 1 表示每帧等待 1 毫秒同时给 OpenCV 处理窗口事件的机会改成 0 会导致画面卡在按任意键才继续。det.infer返回的是归一化到原图尺寸的x, y坐标所以可以直接画在原帧上不需要手动缩放。若返回的是相对坐标就需要乘回frame.shape[1]和frame.shape[0]这个要看封装层的约定。3.4 检测不到人时先检查这几个参数运行后如果画面里没人或者骨架偶尔消失我先检查三处置信度阈值是否设得过高、模型输入尺寸是否太大拖慢 CPU、前后帧之间是否做了关键点跟踪。PP-TinyPose 本身不做跨帧跟踪每帧独立输出。如果分数忽高忽低可以在帧层面做个轻量级临时处理上一帧有关键点、这一帧缺失时沿用上一帧坐标最多沿用 3 帧。这个策略做动作计数时很实用但要注意别让静止画面“冻结”太久。下面的参数表是 CPU 场景下我通常会调的参数建议值作用threshold0.4~0.6控制关键点置信度过滤越低越容易画出噪声warmup_frames5推理时跳过前 5 帧让 CPU 调度和内存预分配稳定box_thresh0.5控制前置人框置信度多人遮挡时提高这个值input_size128x96 或 256x192越小越快越大约准做操场景先选小尺寸4. 把关键点变成健身动作夹角计算、动作计数与做操质量判断4.1 COCO 17 关键点索引映射PP-TinyPose 输出的是 COCO 17 点格式索引顺序直接决定角度公式取哪几个点。做操辅助工具最常用的是肩、肘、腕、髋、膝、踝这 12 个点索引关键点索引关键点5左肩6右肩7左肘8右肘9左腕10右腕11左髋12右髋13左膝14右膝15左踝16右踝取点时最容易被绕晕的是“左右”方向。有些模型按画面视角的左右标有些按人物自身的左右标建议先在测试图上把每个索引号的 x 坐标打印出来对比左右肩的 x 大小确定自己手里的模型是哪一种。这个方向一旦反了左右对称性检查就会完全错误。4.2 用余弦定理计算肘关节和膝关节角度角度计算用三个关键点构成两条向量求向量夹角的余弦值。以右肘角为例点分别是右肩、右肘、右腕import numpy as np def angle_between(a, b, c): ba a - b bc c - b cosine np.dot(ba, bc) / ( np.linalg.norm(ba) * np.linalg.norm(bc) 1e-6 ) return float(np.degrees(np.arccos(np.clip(cosine, -1.0, 1.0)))) right_elbow_angle angle_between( keypoints[6], keypoints[8], keypoints[10] )np.clip(cosine, -1.0, 1.0)是为了避免浮点误差导致arccos收到略大于 1 或小于 -1 的值而返回 NaN。分母里加1e-6是为了防止三点完全重合时除零。这个函数同样能算膝盖角、髋角、肩角只需要换传入的索引。肩关节和髋关节在身体没有侧转时基本能反映躯干角度变化。肘角和膝角是健身动作里最容易定义阈值的两个量因为它们对“伸直”和“弯曲”区分明显。做操动作质量判断不追求医学级角度只追求稳定一致因此阈值范围比精确数值更重要。4.3 用阈值状态机完成动作计数而不是裸阈值做计数时最忌讳的是每帧单独判断“是否达到阈值”。比如深蹲膝盖角小于 90 度算下蹲大于 170 度算站直。如果一帧膝盖角是 91 度下一帧是 89 度计数会不停地重复触发所以需要状态机。def count_squat(knee_angle, state): if knee_angle 90 and state[phase] ! down: state[phase] down elif knee_angle 160 and state[phase] down: state[count] 1 state[phase] up return state[count]状态变量phase只经历up - down - up的切换只有从 down 回到 up 时才计数一次。先进入 down 状态再回到 up 状态这样一段完整动作只触发一次。参数 90 和 160 是阈值phase初始值是up。如果你要计数的是向上举手臂就把阈值换成肘角 90 表示上举、 150 表示放下思路不变。这个状态机对噪声还不够我一般会再加一个“连续 N 帧满足条件才切换”。比如膝盖角连续 5 帧小于 90 度才确认进入 down连续 5 帧大于 160 度才确认回到 up。这样即使有 1 到 2 帧的偶然抖动计数不会乱。这个连续帧数stable_frames是动作灵敏度参数我通常取 3 到 5拿摄像头的真实帧率微调。4.4 做操质量判断左右角度差和躯干倾斜做操辅助工具除了计数还要能提醒“这次动作不标准”。最实用的指标是左右对称度和躯干倾斜度。左右对称度用左肘角和右肘角的差值差值的绝对值超过 15 到 20 度时提示身体歪。躯干倾斜度用左肩到左髋的向量和垂直方向的夹角超过 15 度提示弯腰。def quality_report(kpt, threshold15.0): left_elbow angle_between(kpt[5], kpt[7], kpt[9]) right_elbow angle_between(kpt[6], kpt[8], kpt[10]) asymmetry abs(left_elbow - right_elbow) torso_vec kpt[5] - kpt[11] vertical np.array([0.0, 1.0]) cos_tilt np.dot(torso_vec, vertical) / (np.linalg.norm(torso_vec) 1e-6) tilt abs(np.degrees(np.arccos(np.clip(cos_tilt, -1.0, 1.0)))) if asymmetry threshold: return 左右肩臂不对称, asymmetry if tilt threshold: return 躯干倾斜, tilt return 动作基本正常, max(asymmetry, tilt)这段代码每次都返回提示文字和偏差值。实际产品里不要直接显示“动作基本正常”容易让用户疲劳更好的做法是只在偏差超过阈值时显示红色提示其他时间保持安静。threshold可以按动作类型分别配置比如开合跳关注手肘和膝盖深蹲关注膝盖和躯干而不是一套阈值通吃。5. 打包与分发整理源码 zip、冻结依赖与常见坑5.1 源码 zip 里到底应该放什么标题里的 zip 代表的是交付物不是项目目录本身。我一般不会把paddlepaddle这种 400MB 以上的依赖打进 zip也不会把模型权重打进去。压缩包只放 Python 源码、配置、测试图片和requirements.txt模型权重让用户按 README 里的下载脚本自己拉。否则 zip 解压后用户跑不起来大概率是模型权重路径对不上而不是代码写错。requirements.txt不要用pip freeze一股脑导出那会把本地环境里所有包都带上。只需要手写推理链路真正依赖的包paddlepaddle2.5.1 opencv-python4.8.1.78 numpy1.24.3这里列出来的版本范围只是为了演示固定版本的重要性具体以你的模型和部署设备环境为准。手写的好处是用户能一眼看出要装什么坏处是版本没有全局锁所以我通常在 README 里再写一句“以上版本均为最低测试版本更新小版本不影响运行”。5.2 打包前要清理的三类文件第一类是虚拟环境和缓存.venv、__pycache__、*.pyc会让 zip 体积膨胀且在不同电脑上不可移植。第二类是模型输出和临时目录比如output/、inference_result/下的一大堆推理图片。第三类是隐私数据测试图片里如果有完整人脸放进 zip 发布前要想清楚要不要模糊处理。一个稳妥的打包命令是zip -r fitness_pose.zip . \ -x .venv/* \ -x __pycache__/* \ -x *.pyc \ -x output/* \ -x model/*这条命令用-x排除路径和通配符。由于 zip 默认会保留空目录建议打包前先删掉output等目录或者接受 zip 里多个空目录这对运行没有影响。5.3 验证 zip 可复现的三步命令给别人发源码 zip 之前我会先换一个干净目录验证一遍。第一步看压缩包完整性第二步解压第三步按新环境安装依赖并跑通最小命令unzip -t fitness_pose.zip cd /tmp unzip -q fitness_pose.zip cd fitness_pose python -m venv .venv source .venv/bin/activate pip install -r requirements.txt python src/detector.py --demo如果pip install因为网速或源的问题失败常见做法是在 README 里给出国内镜像源命令。这一步不是为了演示打包而是要回答“为什么在我电脑上能跑在用户电脑上就跑不起来”这类问题。5.4 发布 zip 前最后一个动作跑一次带计数的回归测试给动作计数代码发一个新 zip 版本时我会固定用同一段做操视频做回归测试。视频时长 30 秒内容包含 10 次完整动作代码跑完后自动打印count10才允许发布。把这段回归测试放进tests/test_counter.py用pytest执行比每次手工摆姿势靠谱得多。最终 zip 里带上这个回归测试文件和测试视频的下载地址源码包的专业度会高一个档次。本文还有配套的精品资源点击获取