MediaPipe 是 Google 的机器学习「流水线」框架——它把【检测→追踪→渲染】这些步骤预先搭好成图,你只需要喂进一帧画面,它就还你一堆关键点坐标;上一章 YOLO 是【万物通用】的检测器,MediaPipe 是【为特定目标精调】的专家(手、脸、姿态)。
11-2 装好了 OpenCV、11-1 的 venv 在本章从【推荐】升级为【必需】(MediaPipe 不在 apt 仓库里,只能 pip 装);11-3 的【图就是数组】是所有视觉库共同的地基;11-5 的 YOLO 教会我们【模型+预训练】的思路——本章的 MediaPipe 是同一思路的另一个流派:Google 替你把特定任务(手部、人脸、姿态)训练到开箱即用。下一节 CVZone 则是站在 MediaPipe 肩膀上的【积木层】。
一、MediaPipe 是什么、解决什么问题
上一章用 YOLO 认出了 80 类物体,但你注意过吗——YOLO 只会画框,不会告诉你【这只手哪根手指伸直了】。
- 检测一张脸,YOLO 给你一个方框;MediaPipe 给你 468 个面部关键点,能做出 AR 特效
- 检测一只手,YOLO 给你一个方框;MediaPipe 给你 21 个手部关键点,能数手指、比手势
- 检测一个人,YOLO 给你一个方框;MediaPipe 给你 33 个身体姿态点,能做健身计数
MediaPipe 的本质:把【模型推理】与【前后处理】(缩放、坐标归一化、跨帧追踪、骨架连线)打包成一条现成的流水线,开发者只管喂帧、收结果。代价是任务固定——它只做 Google 精调过的那些任务,想认自家产品的零件,还是得回 YOLO 那条路(自己训练)。
二、两代 API:老 solutions 与新 Tasks(2026 现状)
MediaPipe 的 Python 接口经历过一次换代,网上的老教程大多还停在上一代:
| 老一代(legacy solutions) | 新一代(Tasks API) | |
|---|---|---|
| 导入写法 | mp.solutions.hands |
mediapipe.tasks.python.vision.HandLandmarker |
| 模型来源 | 内置打包在库里 | 单独下载 .task 文件 |
| 现状 | 官方已标弃用(deprecation 警告),但仍能运行 | 当下正路,新功能只加在这边 |
| 配置方式 | 函数参数 | Options 对象(更啰嗦但更清晰) |
本课的取态:12-2 的 CVZone 内部用的还是老一代接口(它封装好了,你无感知);本节 Demo 直接用新一代 Tasks API,让你两头都见过。跑老教程代码时看到 UserWarning: ... is deprecated 别慌,那是提醒、不是报错。
三、在树莓派上安装(venv 是硬前提)
MediaPipe 不在 apt 仓库里(apt 搜不到 python3-mediapipe),只能 pip 装——所以 11-1 建的 venv 从这一节起是硬前提:
cd ~/ai # 11-1 建的实验区
source venv/bin/activate
pip install mediapipe
装完立刻做版本体检——这里埋着本章第一大坑:
import mediapipe, numpy
print("mediapipe", mediapipe.__version__)
print("numpy ", numpy.__version__)
- NumPy 2 冲突:MediaPipe 的 ARM 版轮子还在按 NumPy 1.x 编译,系统里若装了 NumPy 2.x,
import mediapipe会抛_ARRAY_API/ 版本不匹配错误——解法:在 venv 里pip install "numpy<2"(如 1.26.4)。这是 ARM 平台特有且 2026 年仍高频出现的坑。 - 老教程手工编译 MediaPipe:2020 年前后的教程教你装 Bazel 源码编译几小时——现在官方直接提供树莓派 64 位(aarch64)的预编译轮子,
pip install几分钟搞定。 - 32 位系统装不上:官方轮子只发 64 位,还在跑 32 位老系统的要先换系统。
四、动手 Demo:用 Tasks API 找出一只手的 21 个关键点
不接摄像头也能跑:先下载官方 hand_landmarker.task 模型(约 7MB),再喂一张手部照片。
# demo12_1_hand.py —— MediaPipe Tasks API 版手部关键点检测
import mediapipe as mp
from mediapipe.tasks import python as mp_python
from mediapipe.tasks.python import vision
# 1. 创建检测器(模型文件首跑前先下载,命令见下方)
base = mp_python.BaseOptions(model_asset_path="hand_landmarker.task")
opts = vision.HandLandmarkerOptions(base_options=base, num_hands=2)
detector = vision.HandLandmarker.create_from_options(opts)
# 2. 用 OpenCV 读图(11-3:图就是 BGR 数组)
import cv2
img = cv2.imread("hand.jpg") # 换成任意一张有手的照片
h, w = img.shape[:2]
# 3. 喂给检测器
mp_img = mp.Image(image_format=mp.ImageFormat.SRGB,
data=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # MediaPipe 吃 RGB
result = detector.detect(mp_img)
# 4. 读结果:每只手 21 个关键点,坐标是 0~1 的比例值
for i, hand in enumerate(result.hand_landmarks):
print(f"手 {i}:{len(hand)} 个关键点")
print(" 手腕(点0):x=%.3f y=%.3f" % (hand[0].x, hand[0].y))
print(" 食指尖(点8):x=%.3f y=%.3f" % (hand[8].x, hand[8].y))
模型与照片的准备命令:
wget https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task
# hand.jpg 自备:拍一张你的手掌,或从手机传一张到树莓派
python demo12_1_hand.py
看到什么算成功:
手 0:21 个关键点
手腕(点0):x=0.412 y=0.833
食指尖(点8):x=0.298 y=0.421
读结果:关键点坐标是归一化的比例值(0~1),乘上图片宽高才是像素坐标——这是 MediaPipe 与 OpenCV 原生坐标最大的差异(11-3 里 img[y, x] 用的可是实打实的像素下标)。点 0 固定是手腕、点 4/8/12/16/20 是五根指尖,这套编号全世界统一,下一节 CVZone 的 fingersUp 就是靠判断【指尖在手腕上方还是下方】来数手指的。
五、30 秒实验:坐标系对一对
在 Demo 末尾追加两行,把比例坐标换算成像素坐标:
px, py = int(hand[8].x * w), int(hand[8].y * h)
print("食指尖像素坐标:", px, py)
print("图尺寸:", w, "x", h)
跑一遍:像素坐标必须同时满足 0 <= px < w、0 <= py < h——超出了就说明你乘反了(该乘 w 的乘了 h)。这个【比例 vs 像素】的错位,是 MediaPipe 新手画框画歪的头号原因。
六、常见误区
- 把 MediaPipe 当成【更厉害的 YOLO】——它俩是分工不是竞争:YOLO 通用检测(认 80 类、可自己训练),MediaPipe 特定任务(手/脸/姿态,精调到开箱即用但不能自定义目标)。
- 看到 deprecation 警告就以为代码坏了——老一代 solutions 接口弃用但能用;真正会坏的是 NumPy 2 冲突,报错信息完全不同。
- 喂 BGR 图给 MediaPipe——OpenCV 读图是 BGR(11-3 反复强调),MediaPipe 吃 RGB,中间必须
cvtColor一次;忘了这一步不会报错,但结果整体错乱。 - 在系统 Python 里直接 pip install mediapipe——PEP 668 会拒绝(6-5 的老朋友);而且 NumPy 冲突一旦装进系统层,会连累 apt 装的 OpenCV 一起坏。一律在 venv 里装。
自测三问(点开对答案)
1. MediaPipe 的手部检测一次给出多少个关键点?——**21 个**,点 0 是手腕、点 4/8/12/16/20 是五根指尖。 2. `import mediapipe` 报 `_ARRAY_API` 相关错误,最可能的原因是什么?——venv 里装了 NumPy 2.x 与 ARM 版 MediaPipe 冲突,解法 `pip install "numpy<2"`。 3. MediaPipe 输出的关键点坐标是什么单位?——0~1 的比例值(相对图宽/图高),用之前要乘上像素尺寸。- ☐ 下一节(12-2 CVZone 计算机视觉套件)
相关笔记
- AI 实验范例:OpenCV+YOLO 物体识别 —— 同为【预训练模型】流派,YOLO 管通用、MediaPipe 管专精
- 建立与管理 Python 虚拟环境 —— MediaPipe 不在 apt 仓库,venv 从本节起是硬前提
- OpenCV 的基本使用 —— BGR 与【图就是数组】:本节 cvColor 转换的出处
- 🍓 树莓派 · 索引 —— 全课路线图