
简介基于mediapipe设计实现的人体姿态识别Python源码与配套模型面向计算机相关专业的学生、教师及企业开发者尤其适合毕业设计、课程设计或期末大作业场景。资源覆盖从视频输入、关键点提取到动作分类的完整流程可快速搭建人体姿态识别演示项目也适合作为项目初期立项演示或进阶实战练习。资源共138个文件包含120个npy数据文件、8个mp4演示视频、7个py源码文件以及h5模型权重和README说明压缩包约11.04MB目录结构清晰便于按模块对照学习。目前已有205人学习下载。源码经完整测试运行成功评审得分96.5分具备较高参考价值附带的动作视频样本与模型文件可帮助复现实验、理解数据组织方式也能在此基础扩展其他动作识别功能。1. 拿到的 mediapipe 人体姿态识别项目先搞清楚里面是什么如果你下载过那种“毕业设计源码模型”压缩包大概率见过类似的目录一堆 mp4、一个 README.md、一个不知道哪来的 action.h5。这次拆的这份《基于 mediapipe 设计实现人体姿态识别 python 源码模型》本质是一套完整的动作识别链路摄像头或视频输入 → mediapipe 提取人体关键点 → 序列数据送进分类模型 action.h5 → 输出动作类别。它不是单纯的“画骨架” demo而是把姿态估计和时序分类串起来能识别“举手、下蹲、挥手”这类动作的完整工程。这个资源适合正在做毕业设计、课程设计或者刚入门深度学习想做点能跑出结果的项目的人。直接跑通 demo 只需要装好 python 环境项目里自带了训练好的 action.h5 模型和几个视频样本不需要自己先训练。我把它从头到尾拆一遍把文件清单、依赖安装、关键点提取逻辑、模型推理流程和坑位都摆出来方便你先跑通再考虑改造。2. 工程骨架拆解README、视频样本与 action.h5 各负责什么2.1 文件清单别被一坨 mp4 吓到压缩包解压后的结构是这样的文件类型作用README.md文档运行说明、依赖清单、版本要求action.h5h5 模型文件训练好的动作分类模型Keras/TF 格式detection.py / train.py 等python 源码姿态检测、数据采集、训练脚本视解压情况而定l0.mp4、r0.mp4、r1.mp4、1.mp4样本视频自带测试视频用于验证动作识别效果这几个 mp4 命名很有意思l0和r0大概率是 left/right 的 0 号样本r1是右动作的第 1 个样本1.mp4可能是编号 1 的独立场景。这类命名在毕设项目里很常见——作者自己采集数据时按动作类别和时间顺序编号并没有统一规范所以你别指望从文件名看出“这是哪个动作”。真正判断动作类别要看训练代码里的标签映射通常是label_map或actions列表。2.2 README.md 是绕不开的第一份文档很多人下载后直接去pip install mediapipe然后跑代码结果报错。这个项目里有 README.md 的情况下务必先打开看。里面一般写着三件关键信息Python 版本要求。mediapipe 对 Python 版本有约束通常要求 3.8~3.11太新的 3.12 早期版本会装不上。依赖安装命令。常见的是下面这种组合pip install mediapipe opencv-python numpy tensorflow运行顺序。一般是先跑数据采集脚本data_collection.py录自己的动作再跑train.py训练模型最后跑detection.py实时推理。如果你只验证现成模型直接跑推理脚本即可。关于依赖版本需要特别留意 tensorflow 和 mediapipe 的搭配。我的建议是先用pip install mediapipe它会自动装上匹配的 protobuf 和 numpy 版本再装 tensorflow-cpu 而不是完整版 tensorflow能少踩一堆 CUDA 配置的坑。CPU 版本的 tensorflow 跑这种小模型完全够用推理速度在普通笔记本上也能稳定在 20~30 FPS。2.3 action.h5整个项目里最值钱的东西action.h5是训练好的分类模型它接收的不是图片而是连续帧的关键点坐标序列。我们后面会详细说这个模型的输入 shape。现在的重点是你不需要重新训练就能验证整个流程直接用它推理就行。如果想自己重新训练源码里的train.py会读取采集到的关键点序列 npy 文件重新生成 action.h5。3. MediaPipe 姿态关键点提取把视频转成骨架序列3.1 为什么选 MediaPipe 而不是 OpenPose做姿态识别主流方案有 OpenPose、MediaPipe、mmpose 三种。毕设项目之所以普遍用 mediapipe核心原因是“轻”和“省事”。OpenPose 精度高但模型体积大、推理慢还要处理复杂的依赖mmpose 功能全但配置门槛高mediapipe 的 BlazePose 方案在 CPU 上就能实时跑提供 33 个关键点对单人场景足够用。它的输出是一组归一化坐标每个关键点包含 x、y、z 三个值x、y 是图像坐标系下的归一化位置0~1z 是深度估计值。33 个点就是 99 维特征。3.2 提取关键点的核心代码下面这段代码是从视频中逐帧提取关键点并保存为可训练的序列数据import cv2 import mediapipe as mp import numpy as np mp_pose mp.solutions.pose pose mp_pose.Pose( static_image_modeFalse, model_complexity1, min_detection_confidence0.5, min_tracking_confidence0.5 ) cap cv2.VideoCapture(r0.mp4) sequence [] while True: ret, frame cap.read() if not ret: break # BGR 转 RGBmediapipe 内部基于 RGB 处理 rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results pose.process(rgb) if results.pose_landmarks: # 按固定顺序取 33 个关键点的 x, y, z landmarks results.pose_landmarks.landmark frame_features [] for lm in landmarks: frame_features.append([lm.x, lm.y, lm.z]) sequence.append(np.array(frame_features).flatten()) # 单帧 99 维 cap.release() pose.close() # 保存为 npy训练时再用滑动窗口截取序列 np.save(extracted_keypoints.npy, np.array(sequence), allow_pickleTrue)这里有一个容易被忽略的细节results.pose_landmarks只有在检测到人时才非空。如果某几帧没检测到人直接跳过而不是补零否则会把“无人帧”当成正常数据送进模型干扰动作判断。视频里如果人一直在画面内这种丢帧情况很少但真实场景下很常见所以判断逻辑要写严格。3.3 参数对效果的影响上面代码里的三个参数决定了识别的稳定性和速度static_image_modeFalse用在视频流场景开启跟踪模式帧间关键点更平滑设为 True 会让每帧都走完整检测精度略高但速度慢一倍以上。model_complexity10 对应最快但最粗糙2 对应最准但速度低1 是折中档。我在笔记本上测过0 和 1 的速度差别不明显没必要用 0。min_detection_confidence0.5低于这个置信度就认为没检测到人。在实际测试中背对摄像头或人物过小会让置信度掉到 0.3 以下此时建议调低到 0.3而不是调高。另外一个玄学点mediapipe 检测到的人体框如果太靠边关键点坐标会剧烈抖动导致后面模型推理出来的动作类别跳来跳去。解决方案并不是改参数而是在数据采集阶段让人物居中。4. action.h5 动作分类从 99 维骨架序列到动作标签4.1 模型本质时序分类而不是单帧分类很多人误以为 action.h5 是“看一眼图片就判断动作”其实不是。动作是时序概念单帧静态姿态无法区分“蹲下”和“站起前的瞬间”。action.h5 的输入是一段连续帧的关键点序列比如 30 帧 × 99 维输出是每个动作类别的概率。这个工程里的动作类别一般是几个固定动作。README 里如果没有写明去看train.py或推理脚本里的actions数组常见写法如下actions np.array([stand, wave, sit, raise_hand])4.2 模型结构与推理代码训练侧通常是一个 LSTM 或全连接 时序平滑的分类器。对于毕设体量LSTM 是最常见的配置import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential([ # 输入 shape(时间步数, 特征维度) LSTM(64, return_sequencesTrue, input_shape(30, 99)), Dropout(0.3), LSTM(32), Dense(16, activationrelu), Dense(len(actions), activationsoftmax) ]) model.compile(optimizeradam, losscategorical_crossentropy, metrics[accuracy])推理时用固定长度的滑动窗口从实时关键点流中截取最近 30 帧def predict_action(sequence_buffer): # sequence_buffer 维护最近 30 帧的 99 维特征 if len(sequence_buffer) 30: return None # 帧数不够不推理 window np.array(sequence_buffer[-30:]).reshape(1, 30, 99) probs model.predict(window, verbose0)[0] return actions[np.argmax(probs)], float(np.max(probs))这里有三个参数决定识别质量30是时间窗口长度窗口越长越平滑但动作切换越迟钝。我对这个项目实测30 帧约 1 秒是识别“挥手、站立、坐下”这类动作的平衡点。64/32是 LSTM 隐层单元数对整个项目的数据量来说已经偏大如果自己重新训练可以减半加快训练速度。Dropout(0.3)非常关键。毕设采集的数据量一般不大不加 Dropout 几乎必过拟合。4.3 模型推理的一个隐性坑action.h5是训练好的权重文件但如果你改造代码必须保证新代码里的模型结构和训练时完全一致否则load_model(action.h5)会直接报错。常见情况是源码里训练时用的是return_sequencesTrue接第二个 LSTM你改脚本时把第二层 LSTM 删了模型结构对不上加载失败。所以我的习惯是拿到 h5 文件后先用model.summary()打印结构确认输入输出再去动推理代码。5. 运行避坑这些坑我替你踩过了5.1 现象pip install mediapipe报错提示找不到匹配版本原因Python 3.12 的早期 mediapipe 版本没有预编译 wheelpip 会搜索到需要编译源码的版本然后失败。 解决安装 Python 3.8~3.11或者使用虚拟环境定位到 3.10。windows 和 linux 上 mediapipe 都有对应轮子3.10 是最稳的。5.2 现象能跑动但推理脚本报NameError: name actions is not defined原因actions动作标签数组定义在训练脚本里推理脚本没有同步引用。毕设作者经常把训练和推理分开写但推理脚本里漏掉了标签定义。 解决在推理脚本里找到模型输出维度比如 4手动补一个actions np.array([stand, wave, sit, raise_hand])顺序必须和训练时一致。5.3 现象检测一直成功但模型输出始终是同一个类别原因滑动窗口逻辑出了问题。如果推理代码里没有做 30 帧的时间序列累积而是把单帧 99 维 reshape 成(1, 1, 99)送进模型LSTM 看到的序列长度是 1所有输入的时序信息都丢了模型只能给出训练集频率最高的那个类别。 解决确认sequence_buffer确实在逐帧 append并且推理时取的是[-30:]的完整窗口。注意第一次推理前要积累 30 帧。5.4 现象读视频文件时报cv2.error: OpenCV(4.x) ... cant open/read file原因视频路径中包含中文或文件损坏。代码用的cv2.VideoCapture(1.mp4)在 Windows 中文路径下经常翻车。 解决把视频和代码放在纯英文路径下或者用np.fromfilecv2.imdecode手动读取。顺便提醒README 里如果没写视频对应关系优先拿r0.mp4试因为它通常是动作样本里最规整的一段。5.5 现象模型推理延迟高画面卡顿原因使用了完整版 tensorflow带 GPU 支持它初始化 CUDA 上下文会耗几秒钟且每次model.predict()都有调用开销。 解决换成tensorflow-cpu把model.predict(window)改为model(window, trainingFalse)直接张量调用速度明显提升这也是我后来一直保留的习惯。6. 落地技巧把自己录的视频变成新模型再量化微调6.1 快速自测换动作样本但不重训先不改任何训练代码用你手机横屏录制一个 3~5 秒、人物居中的动作视频转成 mp4 后用推理脚本喂进去。如果输出是你预想的类别说明整套链路是通的。如果不对优先看置信度超过 0.8 说明模型判断稳定只是这个动作不在训练类别里低于 0.4 说明关键点提取环节有问题回头查视频分辨率和人物大小。6.2 加一个新动作的最小成本方案我在改造这类项目时一般走四步在actions里追加新动作名比如clap。录制 20~30 段该动作视频用extract_keypoints.py逐段提取关键点序列每段保存一个 npy。把序列按 30 帧窗口切成样本打标签后训练训练轮数控制在 30 左右batch_size 用 8。用 5~10 段未参与训练的新视频做验证计算每类准确率低于 80% 就补采集。这样做一遍动作总数从 4 类扩到 5 类整个流程花费不到一小时效果比调参明显得多。6.3 我每次都会做的模型量化action.h5 体积不小CPU 推理时可以用下面三行代码转成半精度或 int8速度提升明显import tensorflow as tf model tf.keras.models.load_model(action.h5) # 转成 float16减小体积加速 CPU 推理 converter tf.lite.TFLiteConverter.from_keras_model(model) converter.optimizations [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_types [tf.float16] tflite_model converter.convert() with open(action.tflite, wb) as f: f.write(tflite_model)转出来的 action.tflite 可以直接用 mediapipe 同帧率驱动大约能提升 10%~20% 的吞吐。这套资源最好的地方在于它是一个“完整闭环”——从视频样本到关键点序列再到模型权重全都有不是那种给你个模型文件就跑不起来的半成品。我从这套项目里学到的习惯是拿到任何 h5 模型第一件事永远是model.summary()打印输入输出然后在推理脚本里强行走一遍滑动窗口判断确认时序长度对上号再开工。从那以后我跑完一个项目都会强制自己留一份调参记录把运行环境、Python 版本、各依赖版本写进 README。不然半年后回来连自己都装不起环境。这份折腾下来的经验希望帮到你。本文还有配套的精品资源点击获取