云计算百科
云计算领域专业知识百科平台

OpenCV学习:MediaPipe 手部关键点检测

OpenCV学习:MediaPipe 手部关键点检测

前言:前面我们学习了基于 dlib 的人脸检测、关键点检测、换脸等技术。本篇我们将引入另一个强大的计算机视觉库——MediaPipe,学习它在手部关键点检测方面的应用。MediaPipe 是 Google 开发的多媒体机器学习框架,提供了开箱即用的手部、人脸、姿态等检测模型,使用非常简单,检测精度也很高。

目录

  • 一、MediaPipe 简介
  • 二、手部识别模块
  • 三、核心参数详解
  • 四、完整代码
  • 五、关键点说明
  • 六、总结

一、MediaPipe 简介

1.1 什么是 MediaPipe?

MediaPipe 是 Google 开发并开源的一个跨平台机器学习框架,提供了多种预训练模型,可以直接用于:

模块功能
Hands 手部关键点检测
Face Detection 人脸检测
Face Mesh 人脸网格(468 个关键点)
Pose 人体姿态检测
Holistic 全身关键点检测

1.2 MediaPipe 的优势

优势说明
开箱即用 内置预训练模型,无需自己训练
速度快 专为实时应用优化,手机端也能流畅运行
精度高 手部检测能识别 21 个关键点
跨平台 支持 Windows、Linux、macOS、Android、iOS

1.3 安装

pip install mediapipe==0.10.21

版本说明:MediaPipe 版本迭代较快,不同版本 API 略有差异。本案例使用 0.10.21,建议保持一致。

二、手部识别模块

2.1 模块导入

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils # 绘图模块
mp_hands = mp.solutions.hands # 手部识别模块

模块说明
mp.solutions.drawing_utils 绘图工具,将关键点绘制到图像中
mp.solutions.drawing_styles 绘图风格(颜色、粗细等)
mp.solutions.hands 手部识别模块,提供 API

2.2 初始化手部识别类

hands = mp_hands.Hands(
static_image_mode=False,
max_num_hands=2,
min_detection_confidence=0.75,
min_tracking_confidence=0.75)

2.3 处理图像

results = hands.process(frame)

process() 返回的 results 包含手部检测结果,关键属性是:

属性说明
multi_hand_landmarks 检测到的所有手的关键点
multi_handedness 每只手的左右手信息

三、核心参数详解

3.1 static_image_mode

取值说明
True 适用于静态图片的手势识别
False 适用于视频等动态识别(默认)

区别:True 模式下,每帧图片独立检测;False 模式下,会利用前一帧的信息进行追踪。

注意:若识别的手的数量超过 max_num_hands,True 模式下识别的手会在多个手之间不停闪烁;False 模式下超出的手不会识别,系统会自动跟踪之前已经识别过的手。

3.2 max_num_hands

取值说明
int 识别手的最大数量,默认为 2

3.3 min_detection_confidence

取值说明
0.0 ~ 1.0 最小检测置信度,默认为 0.5

影响:值越小越容易识别出手,用时越短,但准确度越低;值越大识别越精准,但响应时间增加。

3.4 min_tracking_confidence

取值说明
0.0 ~ 1.0 最小追踪置信度,默认为 0.5

影响:值越大手部追踪越准确,响应时间也越长。

3.5 参数调优建议

场景参数建议
实时性要求高 min_detection_confidence=0.5、min_tracking_confidence=0.5
精度要求高 min_detection_confidence=0.8、min_tracking_confidence=0.8
处理单张图片 static_image_mode=True
处理视频流 static_image_mode=False

四、完整代码

import cv2
import mediapipe as mp

# pip install mediapipe==0.10.21

# ==================== 模块初始化 ====================
# drawing_utils:绘图模块,将关键点绘制到图像上
# hands:手部识别模块,提供 API
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands

# 初始化手部识别类
hands = mp_hands.Hands(
static_image_mode=False, # False 适用于视频动态识别
max_num_hands=2, # 最多识别 2 只手
min_detection_confidence=0.75, # 最小检测置信度
min_tracking_confidence=0.75) # 最小追踪置信度

# ==================== 打开摄像头 ====================
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

while True:
ret, frame = cap.read()
if not ret:
break

h, w = frame.shape[:2] # 获取图像高度和宽度

# MediaPipe 需要 RGB 格式输入,OpenCV 默认是 BGR,所以先转换
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

# 摄像头是镜像的,水平翻转让画面更自然
frame = cv2.flip(frame, 1)

# 手部检测
results = hands.process(frame)

# 转回 BGR 格式,方便 OpenCV 显示
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

# ==================== 绘制关键点 ====================
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
# 遍历 21 个手部关键点,绘制编号
for i in range(len(hand_landmarks.landmark)):
x = hand_landmarks.landmark[i].x # 归一化的 x 坐标(0~1)
y = hand_landmarks.landmark[i].y # 归一化的 y 坐标(0~1)
z = hand_landmarks.landmark[i].z # 深度信息
print(f'关键点{i}:', x, y, z)
# 将归一化坐标乘以图像宽高,转为像素坐标
cv2.putText(frame, str(i),
(int(x * w), int(y * h)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

# 绘制手部关键点连接线
mp_drawing.draw_landmarks(frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS)

cv2.imshow('MediaPipe Hands', frame)

# 按 ESC 键退出
if cv2.waitKey(1) & 0xFF == 27:
break

cap.release()
cv2.destroyAllWindows()

五、关键点说明

5.1 手部 21 个关键点

MediaPipe 手部检测会返回 21 个关键点,分布如下:

编号对应部位编号对应部位
0 手腕 11 中指根部
1 拇指根部 12 中指第一关节
2 拇指第一关节 13 中指第二关节
3 拇指第二关节 14 中指指尖
4 拇指指尖 15 无名指根部
5 食指根部 16 无名指第一关节
6 食指第一关节 17 无名指第二关节
7 食指第二关节 18 无名指指尖
8 食指指尖 19 小指根部
9 中指根部 20 小指指尖
10 中指第一关节 — —

5.2 坐标说明

坐标说明
x 归一化坐标,0~1 之间,需要乘以图像宽度
y 归一化坐标,0~1 之间,需要乘以图像高度
z 深度信息,以手腕为原点,数值越小越靠近摄像头

5.3 HAND_CONNECTIONS

mp_hands.HAND_CONNECTIONS 定义了关键点之间的连接关系,用于绘制骨架连线。

5.4 应用场景

场景说明
手势控制 通过手势控制设备或游戏
手语翻译 识别手语动作并翻译
虚拟试戴 手部关键点定位,用于戒指、手表试戴
动作分析 分析手部动作,如弹钢琴、打字
AR/VR 交互 手部追踪实现自然交互

六、总结

核心函数速查

函数用途
mp.solutions.hands.Hands(…) 初始化手部识别类
hands.process(frame) 处理图像,返回检测结果
results.multi_hand_landmarks 获取检测到的手部关键点
mp_drawing.draw_landmarks() 绘制关键点和连接线
hand_landmarks.landmark[i].x/y/z 获取第 i 个关键点的坐标

核心参数速查

参数默认值说明
static_image_mode False True 适合静态图片,False 适合视频
max_num_hands 2 最大识别手数
min_detection_confidence 0.5 最小检测置信度
min_tracking_confidence 0.5 最小追踪置信度

注意事项

要点说明
图像格式 MediaPipe 需要 RGB 输入,OpenCV 默认 BGR,需要转换
坐标归一化 关键点坐标是 0~1 的归一化值,需乘以图像宽高
镜像翻转 摄像头建议水平翻转,画面更自然
实时性能 视频模式下,min_detection_confidence 不宜过高
退出方式 按 ESC 键退出循环

系列直达

  • 上篇:OpenCV学习:仿射变换与换脸术
  • 本篇:OpenCV学习:MediaPipe 手部关键点检测(本文)
  • 下篇:敬请期待
赞(0)
未经允许不得转载:网硕互联帮助中心 » OpenCV学习:MediaPipe 手部关键点检测
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!