MediaPipe 实时媒体处理快速上手教程:10 分钟跑通 33 点姿态估计
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
MediaPipe 是 Google 的跨平台机器学习框架,专门处理摄像头和视频这类实时媒体流:输入一帧图像,它实时返回人体姿态、手部关键点或分割掩码。这篇文章按任务推进,你能在 10 分钟内拿到一个摄像头姿态估计 demo,再依次做出手部追踪、虚拟背景合成,最后拼出一个完整的深蹲计数小项目。
一条命令装好 MediaPipe Python 环境
最省事的路线是 pip 预编译包,不需要自己编译任何 C++ 代码:
# 安装官方 PyPI 包,Linux/macOS/Windows 都有预编译 wheel pip install mediapipe # 验证:能打印版本号就说明环境可用 python3 -c "import mediapipe as mp; print(mp.__version__)"看到版本号就可以往下走了。各方案的 API 细节在 docs/getting_started/python.md。
如果你要动 C++ 侧的图(graph),用 Docker 一条命令验证环境:先执行git clone https://gitcode.com/GitHub_Trending/med/mediapipe,然后构建并运行容器,在容器内执行GLOG_logtostderr=1 bazel run --define MEDIAPIPE_DISABLE_GPU=1 mediapipe/examples/desktop/hello_world,看到连续输出 10 行 "Hello World!" 即环境就绪。依赖安装细节见 docs/getting_started/install.md。
10 分钟跑通实时姿态估计
解决什么问题:健身、体态分析、动作教学类应用,需要逐帧拿到人体 33 个关键点(鼻、眼、肩、肘、髋、膝、踝等),且要带世界坐标系 3D 坐标。
关键 API:mp.solutions.pose.Pose。三个核心参数是model_complexity(0/1/2,模型大小)、min_detection_confidence(首帧检测阈值)、static_image_mode(是否按静态图处理)。输出里pose_landmarks是 33 点归一化坐标,pose_world_landmarks是以髋部中点为原点的米制 3D 坐标。
最小可运行代码:
import cv2 import mediapipe as mp mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils cap = cv2.VideoCapture(0) with mp_pose.Pose(model_complexity=1, # 0=最快, 2=最准 min_detection_confidence=0.5) as pose: while cap.isOpened(): ok, frame = cap.read() if not ok: continue frame = cv2.cvtColor(cv2.flip(frame, 1), cv2.COLOR_BGR2RGB) # 必须转 RGB results = pose.process(frame) # 只有检测到人才画 33 个关键点和连线 if results.pose_landmarks: out = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) mp_drawing.draw_landmarks(out, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) cv2.imshow('MediaPipe Pose', out) if cv2.waitKey(5) & 0xFF == 27: break cap.release()怎么判断效果:画面里出现人体骨架连线即成功;人体离开画面后骨架应在 1-2 秒内消失;如果人稍微转身就检测不到,把min_detection_confidence从 0.5 降到 0.3 再看。
手部追踪:21 个点读懂一个手势
解决什么问题:手势交互、虚拟键盘、AR 特效需要逐帧拿到 21 个手部关键点(拇指 CMC 到小指 TIP)以及左右手判定。
关键 API:mp.solutions.hands.Hands,参数比 Pose 少,但多一个max_num_hands(1-2)。注意官方源码(mediapipe/python/solutions/hands.py)里写明:左右手判定默认假设输入是镜像图,所以要先cv2.flip。调用方式和 Pose 完全一样——hands.process(rgb_image)后从results.multi_hand_landmarks取点、从results.multi_handedness取左右手。
最小验证:对任意一张手势图调用一次process,断言landmarks长度为 21,并打印handedness的 label——对着镜子确认左右手和现实一致,说明 flip 没漏做。
一行调用拿人物分割掩码
解决什么问题:视频会议虚拟背景、前景抠图。
关键 API:mp.solutions.selfie_segmentation.SelfieSegmentation(),唯一参数model_selection:0 是通用模型,1 偏向风景类横图。process返回一张与输入同尺寸的浮点 2D 掩码,值域 0-1,越接近 1 越是"人"。
效果验证:把掩码乘以 255 存成灰度图,人形区域应该是白色,边缘平滑过渡——这比肉眼看合成结果更容易判断模型质量。
决定速度与稳定性的 4 个参数
这些是实战中真正要反复调的开关,每个都给了调整方向:
- ⚡model_complexity(Pose 取 0/1/2,Hands 取 0/1):先看帧率再定。用 0 跑一遍,若 CPU 占用高、帧率掉到 20fps 以下,先降复杂度而不是降分辨率;精度不够再升到 2,代价是推理时间几乎翻倍。
- min_detection_confidence:控制"要不要人/手"。检测不到目标就往 0.3 调;背景里有人影被误检就往 0.7 调。它只在丢失追踪后重新检测时生效,别指望它每帧都作用。
- min_tracking_confidence:控制"追踪丢不丢"。目标部分被遮挡时追踪频繁中断,把它从 0.5 降到 0.3,让旧关键点在低置信度下继续保留。
- static_image_mode / smooth_landmarks:批量处理照片时务必设
static_image_mode=True,否则会错误地用上一帧结果做平滑;实时流保持默认,smooth_landmarks开启可明显减少抖动。
完整小项目:实时深蹲角度监视器
功能:摄像头实时监测深蹲,膝关节弯曲到 120° 以内判定一次到位。拆成 4 步:
- 复用前面 Pose 循环,每帧拿到
results.pose_landmarks.landmark(一个 33 元素的列表)。 - 按下标取出左髋(LEFT_HIP=23)、左膝(LEFT_KNEE=25)、左踝(LEFT_ANKLE=27)三个点。
- 用两个向量夹角算膝盖角度,核心函数如下:
import math import mediapipe as mp mp_pose = mp.solutions.pose def knee_angle(landmarks): """返回左膝角度(髋-膝-踝),180 度是腿伸直。""" hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP] knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE] ankle = landmarks[mp_pose.PoseLandmark.LEFT_ANKLE] a = math.atan2(ankle.y - knee.y, ankle.x - knee.x) # 小腿向量 b = math.atan2(hip.y - knee.y, hip.x - knee.x) # 大腿向量 angle = abs((a - b) * 180.0 / math.pi) return angle if angle <= 180 else 360 - angle with mp_pose.Pose(model_complexity=0) as pose: # 计数场景用最快模型 results = pose.process(rgb_frame) if results.pose_landmarks: angle = knee_angle(results.pose_landmarks.landmark) print('膝角 %.0f°,%s' % (angle, '到位' if angle < 120 else '未到位'))- 加一个状态机:角度从 120° 以上降到以下记一次下蹲,回到以上复位,即可做计数器。
新手最容易踩的 5 个坑
- 输入必须是 RGB。OpenCV 读出来是 BGR,直接传给
process会抛 ValueError,或颜色发绿。所有地方都记得cvtColor(..., cv2.COLOR_BGR2RGB)。 - 漏了 flip 导致左右手反了。Hands 的 handedness 假设镜像输入,用后置摄像头拍到的画面要先
cv2.flip(img, 1)。 - 第一次运行卡在下载模型。解决方案首次启动会按
model_complexity自动下载 lite/full/heavy 的.tflite文件,断网环境会卡住。可以提前联网跑一次,或参考 mediapipe/model_maker/ 自带模型。 - 批量照片没开 static_image_mode。处理一组不相关的照片时,帧间平滑会让第一张图污染后面的结果,检测率整体偏低。
- C++ 编译报 TensorFlow 相关错误。gcc/g++ 6.3 和 7.3 与 TF calculators 有已知不兼容,换编译器版本,排查手册在 docs/getting_started/troubleshooting.md。
边界与下一步
MediaPipe 的预置方案是单人体 Pose、最多 2 只手,多人场景或更高精度要换方案或自定义图;帧率瓶颈出现时,用 docs/tools/tracing_and_profiling.md 先定位是推理慢还是 IO 慢。两个自然的下一步:一是用 mediapipe/model_maker/ 把自己的手势数据微调成专属模型;二是读 mediapipe/examples/desktop/ 下的 C++ 示例,把这套能力搬进你自己的 C++ 应用里。
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考