MediaPipe

技术栈
AI 框架
computer-visionon-devicereal-timegooglepose-estimationface-detection

概览

MediaPipe

MediaPipe 是 Google Research 开源的端侧实时 AI 推理框架,专为移动设备、浏览器和边缘设备设计。它用 Pipeline 图连接多个 ML 模型和预处理节点,实现了人脸检测、手势识别、姿态估计等任务在手机上 30 FPS 实时运行。

核心价值:

  • 端侧优先:模型针对 ARM / Edge TPU / WebAssembly 深度优化
  • 实时性能:人脸检测 ~2ms、姿态估计 ~4ms(移动端 GPU)
  • 跨平台:Android / iOS / Python / JavaScript / C++ 原生支持
  • 预置方案:33 个即插即用 Task API(手势/人脸/物体分割/3D 重建)
  • Pipline 架构:Calculator 图设计,灵活组合模型+预处理

适用场景: AR 特效、视频会议背景虚化、健身姿态纠正、手语识别。

安装

环境准备

  • Python:>= 3.8(推荐 3.10)
  • 系统:Linux / macOS / Windows
  • 摄像头(可选):做实时检测需要

安装命令

Python SDK

pip install mediapipe

验证安装

import mediapipe as mp

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=2)

import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
if ret:
    results = hands.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    print("检测到手:", results.multi_hand_landmarks is not None)
cap.release()
print("MediaPipe 安装成功!")

移动端/Web

# Android: 添加依赖 build.gradle
implementation 'com.google.mediapipe:tasks-vision:0.10.9'

# Web: CDN 引入
<;script src="https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/vision_bundle.js"></script>

常见安装问题

Q1: cv2.error: (-215:Assertion failed) 摄像头错误

摄像头被占用或索引错误。尝试 cv2.VideoCapture(1)cv2.VideoCapture(-1)

Q2: macOS 上 mediapipe 安装慢

包体积大(~200 MB),含所有模型。耐心等待或使用镜像源。

Q3: 模型下载超时

首次运行 MediaPipe Tasks 时会自动下载模型,可通过 model_asset_path 指定本地路径跳过下载。

示例

MediaPipe 实时手势关键点追踪

目标

用 MediaPipe Hands 实时检测手掌 21 个关键点,在摄像头画面上绘制骨架连线。

完整代码

import cv2
import mediapipe as mp

# ─── 1. 初始化 ───
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles

hands = mp_hands.Hands(
    static_image_mode=False,   # 视频流模式
    max_num_hands=2,           # 最多 2 只手
    min_detection_confidence=0.7,
    min_tracking_confidence=0.7,
)

cap = cv2.VideoCapture(0)

while cap.isOpened():
    success, frame = cap.read()
    if not success:
        break

    # BGR → RGB
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(rgb)

    # ─── 2. 绘制关键点 ───
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            # 画骨架连线
            mp_drawing.draw_landmarks(
                frame,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing_styles.get_default_hand_landmarks_style(),
                mp_drawing_styles.get_default_hand_connections_style(),
            )

            # ─── 3. 识别手势 ───
            landmarks = hand_landmarks.landmark
            # 拇指尖 (4) 高于食指尖 (8) = 竖拇指
            if landmarks[4].y < landmarks[8].y and landmarks[4].y < landmarks[12].y:
                cv2.putText(frame, "Thumbs Up!", (50, 50),
                            cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 0), 3)

    # FPS 显示
    cv2.putText(frame, "Press 'q' to quit", (10, frame.shape[0] - 10),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)

    cv2.imshow("MediaPipe Hands - Real-time", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

运行步骤

pip install mediapipe opencv-python
python hand_tracking.py
# 对着摄像头比手势,按 'q' 退出

预期效果

  • 实时显示手掌 21 个关键点(指尖、关节、手腕)
  • 各手指骨架连线以不同颜色显示
  • 竖大拇指时画面显示 "Thumbs Up!"
  • 稳定 30 FPS(取决于硬件)

教程

MediaPipe 入门教程:Task API 全家桶

1. MediaPipe 的架构哲学

MediaPipe 核心理念:ML 推理是一个 Pipeline 图

摄像头 → [人脸检测] → [关键点] → [表情分类] → UI 渲染
                ↘ [背景虚化] ↗

每个节点叫 Calculator,图结构叫 Graph。MediaPipe 自带了 200+ Calculators。

2. Task API 全家桶

Task API 功能 延迟(移动端)
Face Detector 人脸检测 ~2ms
Face Mesh 468 个面部关键点 ~3ms
Hand Landmarker 21 个手掌关键点 ~3ms
Pose Landmarker 33 个人体关键点 ~4ms
Object Detector 目标检测 ~5ms
Image Segmenter 人像分割 ~5ms
Gesture Recognizer 手势分类 ~2ms

3. 人脸 468 点 Mesh

import mediapipe as mp

mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
    max_num_faces=1,
    refine_landmarks=True,  # 眼部和嘴唇精细关键点
    min_detection_confidence=0.5,
)

results = face_mesh.process(rgb)
if results.multi_face_landmarks:
    for landmark in results.multi_face_landmarks[0].landmark:
        # 468 个点 (x, y, z)
        pass

应用场景:AR 滤镜、虚拟化妆、3D 头像驱动。

4. 姿态 33 点 Landmark

mp_pose = mp.solutions.pose
pose = mp_pose.Pose(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5,
    model_complexity=2,  # 0=轻量, 1=中等, 2=高精度
)

results = pose.process(rgb)
if results.pose_landmarks:
    left_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST]
    right_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]

33 个关键点覆盖全身,可做俯卧撑计数、瑜伽姿势纠正等。

5. 实时人像分割(背景虚化)

mp_selfie_seg = mp.solutions.selfie_segmentation
segmenter = mp_selfie_seg.SelfieSegmentation(model_selection=1)  # 0=通用, 1=风景

results = segmenter.process(rgb)
mask = results.segmentation_mask > 0.5  # 二值化

# 替换背景
blurred_bg = cv2.GaussianBlur(frame, (55, 55), 0)
output = np.where(mask[..., None], frame, blurred_bg)

只需 5ms,视频会议级别实时虚化。

6. Web 端使用(无需后端!)

import { HandLandmarker, FilesetResolver } from "@mediapipe/tasks-vision";

const vision = await FilesetResolver.forVisionTasks(
    "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.9/wasm"
);
const handLandmarker = await HandLandmarker.createFromOptions(vision, {
    baseOptions: {
        modelAssetPath: "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/latest/hand_landmarker.task",
    },
    runningMode: "VIDEO",
});

const results = handLandmarker.detectForVideo(videoElement, timestamp);

浏览器里跑!无需 GPU 服务器,隐私数据不出设备。

7. MediaPipe vs OpenCV vs YOLO 端侧

维度 MediaPipe OpenCV DNN YOLOv8-ncnn
安装难度 ⭐⭐⭐ 极简 ⭐⭐
预置模型 ⭐⭐⭐ 33 个 ⭐ 有限
自定义模型 ⭐⭐ ⭐⭐ ⭐⭐⭐
Web/移动端 ⭐⭐⭐ ⭐⭐ ⭐⭐
实时性 ⭐⭐⭐ ⭐⭐ ⭐⭐⭐

思考题

  1. MediaPipe 在手机上跑得快的秘诀是什么?与普通 TF Lite 推理有何不同?
  2. Hands 检测 21 个关键点和 Pose 检测 33 个关键点的模型架构有何区别?
  3. 为什么 MediaPipe 选择 Calculator 图架构而不是简单的顺序 Pipeline?

参考资料

暂无参考文献