MediaPipe实时人脸检测与手部跟踪5分钟跑通:从单张图片到多平台部署
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
当你需要在摄像头画面上叠加人脸框、并实时标出手部关键点时,MediaPipe(Google 开源的跨平台实时媒体机器学习框架)是常见选择:pip install mediapipe之后,人脸检测、手部跟踪、人体姿态估计都可以直接调用。下文从一个单张图片示例开始,走通安装与运行的最小路径,再拆解各场景的配参与结果含义,最后给出调优数据和多端部署对照。
项目定位
MediaPipe 是一套面向 live 和流式媒体的机器学习解决方案框架,仓库里既有预构建的解决方案(人脸、手部、姿态、分割等),也有低层框架(用 Graph 和 Calculator 自定义管道)。它解决的问题是:把端侧实时推理的模型、运行时和跨平台封装打包好,你不必自己拼模型加载、帧调度和推理后端。适合移动端、桌面、Web 和边缘设备上的实时视觉应用。
能力速览
| 能力 | 输出内容 | 关键配置 | Python 入口类 |
|---|---|---|---|
| 人脸检测 | 人脸框 + 6 个关键点 | model_selection、min_detection_confidence | FaceDetection |
| 手部跟踪 | 21 个 3D 关键点 + 左右手判断 | max_num_hands、model_complexity | Hands |
| 人体姿态 | 33 个关键点 + 可选分割掩码 | model_complexity、enable_segmentation | Pose |
| 自拍分割 | 人物二值掩码 | model_selection | SelfieSegmentation |
关键点(landmark)是模型回归出的归一化坐标点,后续小节都会围绕"输出什么、怎么配"展开。
最小上手路径:两条命令装好,单张图片检出人脸
先建虚拟环境并安装,PyPI 提供 Linux、macOS、Windows 的 wheel:
python3 -m venv mp_env && source mp_env/bin/activate pip install mediapipe然后用仓库自带的测试图跑一次人脸检测(人脸检测方案基于轻量检测器 BlazeFace,专为移动端实时推理设计):
import cv2 import mediapipe as mp mp_face_detection = mp.solutions.face_detection mp_drawing = mp.solutions.drawing_utils image = cv2.imread('mediapipe/calculators/image/testdata/dino.jpg') rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) with mp_face_detection.FaceDetection( model_selection=1, min_detection_confidence=0.5) as det: results = det.process(rgb) if results.detections: for d in results.detections: mp_drawing.draw_detection(image, d) cv2.imwrite('/tmp/face_result.png', image)运行后你会看到/tmp/face_result.png,图中人脸被画上了边界框和 6 个关键点标记。输入必须转成 RGB,cv2.imread读出来是 BGR,这是最常见的失败原因。
人脸检测怎么配:近距与远距模型怎么选
方案输出每张脸的边界框和 6 个关键点:右眼、左眼、鼻尖、嘴角中心、左右耳屏,坐标都归一化到 [0.0, 1.0]。
| 参数 | 含义 | 取值 |
|---|---|---|
model_selection | 0 为近距模型(2 米内效果好),1 为远距模型(5 米内,用稀疏模型换推理速度) | 0/1,默认 0 |
min_detection_confidence | 判定一次检测成功的最低置信度 | 0.0–1.0,默认 0.5 |
if results.detections: for detection in results.detections: nose = mp_face_detection.get_key_point( detection, mp_face_detection.FaceKeyPoint.NOSE_TIP) print('鼻尖归一化坐标:', nose.x, nose.y)结果说明:nose.x、nose.y相对图片宽高归一化,乘以实际分辨率即可得到像素坐标,适合做裁剪送后续模型。视频会议这类 2 米内场景用 0,监控这类 5 米内场景用 1。
手部跟踪参数怎么配:21 个关键点与左右手输出
手部方案用"掌检测 + 手部关键点"两级模型,从单帧推断 21 个 3D 手部关键点,视频模式下跟踪成功后只在丢跟时重新触发检测,这是它能实时跑在手机上并支持双手的原因。
| 参数 | 含义 | 默认 |
|---|---|---|
static_image_mode | True 时每张图片独立跑检测(批量静态图用),False 按视频流跟踪 | False |
max_num_hands | 最大检测手数 | 2 |
model_complexity | 关键点模型复杂度,越高越准但越慢 | 1 |
min_tracking_confidence | 低于此值下一帧重新检测;静态模式下被忽略 | 0.5 |
mp_hands = mp.solutions.hands mp_drawing = mp.solutions.drawing_utils with mp_hands.Hands(static_image_mode=True, max_num_hands=2, model_complexity=1) as hands: results = hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) if results.multi_hand_landmarks: for lm in results.multi_hand_landmarks: mp_drawing.draw_landmarks( image, lm, mp_hands.HAND_CONNECTIONS)结果说明:draw_landmarks会在原图上画出 21 个关键点和关节连线;multi_hand_world_landmarks额外提供以手掌几何中心为原点的米制 3D 坐标。注意左右手判断默认假设输入是镜像(前置自拍)画面,非镜像输入需要自行交换 Left/Right。
姿态估计怎么开:33 个关键点加背景分割
姿态方案检测 33 个全身关键点,可选输出人物分割掩码,视频模式下同样遵循"首帧检测、后续跟踪"的省算力策略。
model_complexity:0/1/2 三档,默认 1,档位越高精度和延迟同步上升smooth_landmarks:跨帧滤波关键点,减少抖动(静态模式下不生效)enable_segmentation:是否输出人物二分类掩码(人物/背景)
mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils with mp_pose.Pose(model_complexity=1, enable_segmentation=True) as pose: results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) if results.pose_landmarks: mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) if results.segmentation_mask is not None: cv2.imwrite('/tmp/mask.png', results.segmentation_mask)结果说明:原图上画出 33 个姿态关键点与骨架连线,segmentation_mask是与输入同尺寸的 0–1 浮点图,可直接用于抠人或背景替换。
调优与性能:模型降到 0 档能省多少
官方文档给出姿态模型三档在 Pixel 3(TFLite GPU)上的实测延迟和 Yoga 数据集精度,可作为档位选择的量化依据:
model_complexity | Pixel 3 延迟 | Yoga mAP |
|---|---|---|
| 0(Lite) | 20 ms | 45.0 |
| 1(Full,默认) | 25 ms | 62.6 |
| 2(Heavy) | 53 ms | 68.1 |
- 从 2 档降到 0 档,延迟 53ms 降到 20ms(约省 62%),代价是 mAP 从 68.1 掉到 45.0;移动端实时场景通常选 0 或 1 即可
- 手部方案只有 0/1 两档,低端设备建议直接 0
- 视频流保持
static_image_mode=False:检测器只在首帧和丢跟时运行,其余帧只做跟踪 - 调
min_detection_confidence前先确认输入是 RGB 且人脸占画面比例合适:调高减误检但会漏检,小脸/远距离场景反而要调低 - 边缘设备(如 Coral USB Accelerator)可跑官方 Coral 示例,见 Coral 示例目录
多平台部署对照:各平台怎么选入口
Python
预构建包直接pip install mediapipe,覆盖 Linux/macOS/Windows;aarch64(Jetson、树莓派)没有 wheel,需要按源码构建流程走 Bazel + OpenCV 编译。详见 Python 入门文档。
Android
用仓库脚本./setup_android_sdk_and_ndk.sh配置 SDK/NDK 与 Bazel,示例应用位于mediapipe/examples/android/。详见 Android 文档。
iOS
基于 CocoaPods 集成 MediaPipe 框架,示例工程在mediapipe/examples/ios/。详见 iOS 文档。
C++ 桌面端
Bazel 构建,依赖 OpenCV,可用./build_desktop_examples.sh一键编译桌面示例(如人脸检测、手部跟踪)。详见 C++ 文档。
Web
浏览器内通过 npm 包(如@mediapipe/hands)加载模型与 wasm 运行时,无需本地编译。详见 JavaScript 文档。
Coral 边缘设备
用 USB 加速器承接推理,仓库内自带人脸/目标检测示例与演示图。
高频问题与排查
- 检不出人或误检多:先确认输入已转 RGB(
cv2.COLOR_BGR2RGB),再在 0.3–0.7 区间试min_detection_confidence(默认 0.5)。 - 批量静态图结果互相串扰:处理多张无关图片必须
static_image_mode=True,否则方案沿用上一张的跟踪状态。 - 左右手标反:handedness 假设输入为镜像画面,后置摄像头输入需自行交换标签。
- aarch64 装不上:PyPI 无 aarch64 wheel,需按 Python 文档源码构建,或参考社区的 aarch64 打包。
- 帧率不足:
model_complexity降到 0、压缩输入分辨率、确认视频模式而非静态模式。
延伸方向
- 用 MediaPipe Framework 自建管道:Packets(数据包)、Graphs(有向图)、Calculators(处理节点)三层概念见 framework_concepts.md,适合需要自定义检测-跟踪链路的场景
- 用 Model Maker 用自己的数据重训模型:
mediapipe/model_maker/下含视觉任务(手势、目标检测等)的 Python 训练代码 - 用 Visualizer 调试图配置:把
.pbtxt图文件贴进可视化工具观察 Packet 流向与耗时,入口见 visualizer 文档
【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考