MediaPipe姿态识别部署教程:支持批量图像处理的脚本编写
1. 引言
1.1 学习目标
本文将带你从零开始,完整掌握如何在本地环境部署Google MediaPipe Pose模型,并基于其 Python API 编写支持批量图像处理的自动化脚本。你将学会:
- 如何调用 MediaPipe 实现单张图像的姿态关键点检测
- 如何扩展为批量处理文件夹中所有图片
- 如何保存带骨架可视化的结果图与关键点坐标数据
- 如何构建轻量级 WebUI 进行交互式展示
最终实现一个无需GPU、不依赖网络、高鲁棒性的人体姿态分析系统,适用于健身动作评估、舞蹈教学、行为分析等场景。
1.2 前置知识
建议读者具备以下基础: - Python 基础语法(函数、循环、文件操作) - OpenCV 与 NumPy 的基本使用 - 简单的命令行操作能力
本教程完全基于 CPU 运行,适合边缘设备或低配机器部署。
2. 环境准备与基础检测
2.1 安装依赖库
首先创建虚拟环境并安装核心依赖:
pip install mediapipe opencv-python numpy flask pillow✅说明:
mediapipe包已内置模型权重,无需额外下载,真正做到“开箱即用”。
2.2 单图姿态检测示例
以下代码演示如何对一张图像进行骨骼关键点检测和可视化:
import cv2 import mediapipe as mp import numpy as np # 初始化 MediaPipe Pose 模块 mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils pose = mp_pose.Pose(static_image_mode=True, model_complexity=2, enable_segmentation=False) # 读取图像 image_path = "input.jpg" image = cv2.imread(image_path) rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 执行姿态估计 results = pose.process(rgb_image) # 绘制骨架连接图 if results.pose_landmarks: mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2, circle_radius=3), connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2) ) # 保存结果 cv2.imwrite("output_with_skeleton.jpg", image) # 输出关键点坐标(x, y, z, visibility) landmarks = [] for lm in results.pose_landmarks.landmark: landmarks.append([lm.x, lm.y, lm.z, lm.visibility]) print(f"检测到33个关键点,前5个坐标:\n{np.array(landmarks)[:5]}")📌代码解析: -static_image_mode=True:表示输入为静态图像(非视频流) -model_complexity=2:使用最高精度模型(可选 0~2) - 关键点包含(x, y, z, visibility)四维信息,其中z是相对深度,visibility表示置信度 - 使用draw_landmarks自动绘制火柴人结构
3. 批量图像处理脚本开发
3.1 设计需求与目录结构
为了高效处理多张图像,我们设计如下功能: - 支持指定输入/输出文件夹 - 自动遍历.jpg,.png图像 - 分别保存带骨架图和关键点坐标文件(CSV格式)
预期目录结构:
project/ ├── input_images/ # 输入图像 ├── output_images/ # 输出带骨架图 ├── output_keypoints/ # 输出关键点CSV └── batch_pose.py # 主脚本3.2 完整批量处理脚本
import os import cv2 import mediapipe as mp import numpy as np import pandas as pd from pathlib import Path def process_batch_images(input_dir, output_image_dir, output_keypoint_dir): # 初始化 MediaPipe mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils pose = mp_pose.Pose(static_image_mode=True, model_complexity=2) # 创建输出目录 Path(output_image_dir).mkdir(exist_ok=True) Path(output_keypoint_dir).mkdir(exist_ok=True) # 支持的图像格式 extensions = ['.jpg', '.jpeg', '.png', '.bmp'] image_files = [f for f in os.listdir(input_dir) if os.path.splitext(f.lower())[1] in extensions] print(f"共发现 {len(image_files)} 张图像,开始批量处理...") for idx, filename in enumerate(image_files): try: filepath = os.path.join(input_dir, filename) image = cv2.imread(filepath) if image is None: print(f"[警告] 无法读取图像:{filename}") continue rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = pose.process(rgb_image) # 若未检测到人体,跳过 if not results.pose_landmarks: print(f"[跳过] 未检测到人体:{filename}") continue # 绘制骨架 mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2, circle_radius=3), connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2) ) # 保存可视化图像 output_img_path = os.path.join(output_image_dir, filename) cv2.imwrite(output_img_path, image) # 保存关键点坐标为 CSV keypoints = [] for i, lm in enumerate(results.pose_landmarks.landmark): keypoints.append({ 'id': i, 'x': lm.x, 'y': lm.y, 'z': lm.z, 'visibility': lm.visibility }) df = pd.DataFrame(keypoints) csv_name = os.path.splitext(filename)[0] + '.csv' df.to_csv(os.path.join(output_keypoint_dir, csv_name), index=False) print(f"[{idx+1}/{len(image_files)}] 处理完成:{filename}") except Exception as e: print(f"[错误] 处理 {filename} 时出错:{str(e)}") pose.close() print("✅ 批量处理完成!") # 调用示例 if __name__ == "__main__": process_batch_images( input_dir="input_images", output_image_dir="output_images", output_keypoint_dir="output_keypoints" )3.3 脚本运行方式
- 将图像放入
input_images/文件夹 - 执行脚本:
bash python batch_pose.py - 查看输出:
- 可视化图像 →
output_images/ - 关键点数据 →
output_keypoints/*.csv
4. WebUI 快速搭建(Flask 实现)
4.1 构建简易 Web 接口
为了让非技术人员也能使用,我们可以快速搭建一个 Web 页面上传并查看结果。
创建app.py:
from flask import Flask, request, render_template, send_from_directory import os import cv2 import mediapipe as mp import numpy as np app = Flask(__name__) UPLOAD_FOLDER = 'uploads' RESULT_FOLDER = 'results' os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(RESULT_FOLDER, exist_ok=True) mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils pose = mp_pose.Pose(static_image_mode=True, model_complexity=2) @app.route('/') def index(): return ''' <h2>🤸♂️ MediaPipe 姿态识别 WebUI</h2> <form method="POST" enctype="multipart/form-data" action="/upload"> 上传图像: <input type="file" name="image"><br><br> <input type="submit" value="分析姿态"> </form> ''' @app.route('/upload', methods=['POST']) def upload(): file = request.files['image'] if not file: return "无文件上传" # 保存上传图像 input_path = os.path.join(UPLOAD_FOLDER, file.filename) file.save(input_path) # 读取并处理 image = cv2.imread(input_path) rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = pose.process(rgb_image) if results.pose_landmarks: mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2, circle_radius=3), connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=2) ) else: cv2.putText(image, "No person detected", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) # 保存结果 output_path = os.path.join(RESULT_FOLDER, file.filename) cv2.imwrite(output_path, image) return send_from_directory('results', file.filename) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False)4.2 启动 Web 服务
python app.py访问http://localhost:5000即可上传图像并实时查看骨骼图。
🔐安全提示:生产环境请添加文件类型校验、大小限制和身份验证。
5. 总结
5.1 核心收获回顾
通过本文,你已经掌握了:
- MediaPipe Pose 的本地化部署方法:无需联网、无 Token 风险,稳定性极高
- 批量图像处理脚本编写技巧:结合 OpenCV 与 Pandas 实现自动化流水线
- 关键点数据结构理解:33个关节点的
(x, y, z, visibility)含义清晰 - WebUI 快速集成方案:使用 Flask 构建轻量级交互界面,便于团队协作
5.2 最佳实践建议
- 优先使用 CPU 版本:MediaPipe 在 CPU 上性能优异,适合嵌入式设备
- 预处理图像尺寸:建议缩放至 640×480 左右以提升速度
- 过滤低置信度点:根据
visibility < 0.5可剔除不可靠关键点 - 扩展应用场景:可用于动作比对、姿态评分、异常行为检测等任务
💡获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。