前言 :前面我们学习了 MediaPipe 的手部关键点检测、手势数字识别和人体姿态检测。本篇我们将进入 MediaPipe 的另一个强大模块------Face Mesh(人脸网格) 。它能识别人脸上的 478 个关键点,比 dlib 的 68 个关键点更精细,能覆盖五官轮廓、眼部细节、嘴唇边缘、甚至眼球等部位。这个技术可以用于虚拟试妆、面部表情分析、人脸驱动虚拟形象等场景。
目录
- 一、Face Mesh 简介
- 二、核心参数详解
- 三、478 个人脸关键点
- 四、完整代码
- 五、结果说明
- 六、总结
一、Face Mesh 简介
1.1 什么是 Face Mesh?
Face Mesh(人脸网格) 是 MediaPipe 提供的人脸关键点检测模块,能从一张人脸图片中提取 478 个 3D 关键点,并以网格(Mesh)的方式绘制出来。
1.2 与 dlib 68 点的对比
| 对比维度 |
dlib 68 点 |
MediaPipe Face Mesh |
| 关键点数量 |
68 个 |
478 个 |
| 是否有眼球 |
否 |
有(虹膜) |
| 是否有 3D 坐标 |
否 |
有(x/y/z) |
| 处理速度 |
快 |
较快 |
| 精度 |
一般 |
高 |
| 安装依赖 |
需要编译 |
pip 直接安装 |
MediaPipe Face Mesh 在关键点数量、精度、易用性上都优于 dlib 68 点。
1.3 应用场景
| 场景 |
说明 |
| 虚拟试妆 |
精确定位嘴唇、眼影、腮红位置 |
| 表情分析 |
通过面部关键点分析情绪 |
| 人脸驱动虚拟形象 |
用真人面部动作驱动虚拟角色 |
| AR 滤镜 |
在脸上叠加面具、贴纸等 |
| 面部按摩 |
定位穴位,指导按摩位置 |
| 面部识别辅助 |
提取面部特征进行身份识别 |
二、核心参数详解
2.1 FaceMesh() 核心参数
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False,
max_num_faces=2,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5)
| 参数 |
说明 |
static_image_mode |
静态图像还是连续帧视频 |
max_num_faces |
最多检测几个人脸 |
refine_landmarks |
是否精细检测嘴唇和眼球 |
min_detection_confidence |
最小检测置信度 |
min_tracking_confidence |
最小跟踪置信度 |
2.2 static_image_mode
| 取值 |
说明 |
| True |
适用于静态图片,每帧独立检测 |
| False |
适用于视频流,利用前一帧信息追踪(推荐) |
2.3 max_num_faces
| 取值 |
说明 |
| int |
最多检测的人脸数量,默认为 1 |
提示:数量越大,计算量越大。一般设为 1~5 即可。
2.4 refine_landmarks
| 取值 |
说明 |
| True |
精细检测嘴唇和眼球,关键点从 468 增至 478 |
| False |
只检测 468 个基础关键点 |
开启后的效果:
- 嘴唇边缘更精细
- 增加虹膜(眼球)关键点
- 更精确的眼部追踪
注意 :refine_landmarks=True 时关键点数量是 478,否则是 468。
2.5 置信度参数
| 参数 |
说明 |
取值范围 |
min_detection_confidence |
最小检测置信度 |
0.0 ~ 1.0 |
min_tracking_confidence |
最小跟踪置信度 |
0.0 ~ 1.0 |
影响:值越大检测越精准,但响应时间越长;值越小越容易检出,但误检也更多。
三、478 个人脸关键点
3.1 关键点分布
MediaPipe Face Mesh 的 478 个关键点覆盖了面部的各个部位:
| 部位 |
关键点范围 |
说明 |
| 脸部轮廓 |
0~16 |
脸部外轮廓 |
| 左眉 |
17~21 |
左眼上方 |
| 右眉 |
22~26 |
右眼上方 |
| 鼻子 |
27~35 |
鼻梁、鼻翼 |
| 左眼 |
36~41 |
左眼周围 |
| 右眼 |
42~47 |
右眼周围 |
| 嘴巴外轮廓 |
48~59 |
嘴唇外边缘 |
| 嘴巴内轮廓 |
60~67 |
嘴唇内边缘 |
| 虹膜 |
468~477 |
左右眼球(需开启 refine_landmarks) |
3.2 关键点数量说明
| refine_landmarks |
关键点总数 |
| False |
468 个 |
| True |
478 个(增加虹膜关键点) |
3.3 关键点连接关系
MediaPipe 提供了多种连接方式,用于绘制不同风格的人脸网格:
| 连接 |
说明 |
FACEMESH_TESSELATION |
完整网格,最密集 |
FACEMESH_CONTOURS |
五官轮廓 |
FACEMESH_IRISES |
虹膜轮廓 |
FACEMESH_LEFT_EYE |
左眼轮廓 |
FACEMESH_RIGHT_EYE |
右眼轮廓 |
四、完整代码
import cv2
import mediapipe as mp
# ==================== 初始化 MediaPipe 模块 ====================
mp_face_mesh = mp.solutions.face_mesh # 人脸网格模块
mp_drawing = mp.solutions.drawing_utils # 绘图工具
mp_drawing_styles = mp.solutions.drawing_styles # 绘图风格
# 设置 Face Mesh 参数
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False, # False 适用于视频流
max_num_faces=2, # 最多检测 2 张人脸
refine_landmarks=True, # 精细检测嘴唇和眼球(478 个关键点)
min_detection_confidence=0.5, # 最小检测置信度
min_tracking_confidence=0.5) # 最小跟踪置信度
# ==================== 打开摄像头 ====================
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
while cap.isOpened():
success, frame = cap.read()
if not success:
print("无法读取摄像头画面")
break
h, w = frame.shape[:2] # 获取图像高度和宽度
# ==================== 人脸网格检测 ====================
# MediaPipe 需要 RGB 输入,OpenCV 默认是 BGR
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 执行检测
results = face_mesh.process(frame_rgb)
# ==================== 绘制关键点 ====================
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
# print(len(face_landmarks.landmark)) # 478
# 遍历所有关键点,绘制编号
for i in range(len(face_landmarks.landmark)):
x = face_landmarks.landmark[i].x # 归一化 x 坐标(0~1)
y = face_landmarks.landmark[i].y # 归一化 y 坐标(0~1)
# z = face_landmarks.landmark[i].z # 深度信息
# 将归一化坐标乘以图像宽高,转为像素坐标
cv2.putText(frame, str(i),
(int(x * w), int(y * h)),
cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 255, 0), 2)
# 绘制人脸网格连接线(TESSELATION:完整三角网格)
mp_drawing.draw_landmarks(
image=frame,
landmark_list=face_landmarks,
connections=mp_face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=None,
connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_tesselation_style()
)
# ==================== 显示结果 ====================
cv2.imshow('Face Mesh', frame)
# 按 ESC 键退出
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
五、结果说明
5.1 关键步骤
| 步骤 |
说明 |
| 1. 初始化模型 |
用 mp_face_mesh.FaceMesh() 创建人脸网格检测器 |
| 2. 打开摄像头 |
用 cv2.VideoCapture() 读取视频流 |
| 3. 转换格式 |
BGR → RGB(MediaPipe 要求) |
| 4. 执行检测 |
face_mesh.process() 返回关键点结果 |
| 5. 绘制关键点 |
遍历 478 个关键点,绘制编号 |
| 6. 绘制网格 |
用 draw_landmarks() 绘制三角网格 |
5.2 三种绘制风格
mp_drawing_styles 提供了三种绘制风格:
| 风格 |
说明 |
视觉效果 |
| TESSELATION |
完整三角网格 |
最密集,视觉效果最好 |
| CONTOURS |
五官轮廓 |
简洁,突出面部轮廓 |
| IRISES |
虹膜轮廓 |
突出眼球位置 |
5.3 关键点数量说明
| 参数 |
关键点数量 |
refine_landmarks=False |
468 个 |
refine_landmarks=True |
478 个(增加眼球关键点) |
5.4 应用场景
| 场景 |
说明 |
| 虚拟试妆 |
精确定位嘴唇、眼影、腮红位置 |
| 表情分析 |
通过面部关键点分析情绪 |
| 人脸驱动虚拟形象 |
用真人面部动作驱动虚拟角色 |
| AR 滤镜 |
在脸上叠加面具、贴纸等 |
| 眼球追踪 |
通过虹膜关键点分析视线方向 |
六、总结
核心函数速查
| 函数 |
用途 |
mp.solutions.face_mesh.FaceMesh(...) |
初始化人脸网格检测器 |
face_mesh.process(frame) |
处理图像,返回关键点结果 |
results.multi_face_landmarks |
获取多张人脸的关键点 |
mp_drawing.draw_landmarks() |
绘制关键点和网格连接线 |
mp_drawing_styles.get_default_face_mesh_tesselation_style() |
获取网格绘制风格 |
核心参数速查
| 参数 |
默认值 |
说明 |
static_image_mode |
False |
True 适合图片,False 适合视频 |
max_num_faces |
1 |
最大检测人脸数 |
refine_landmarks |
False |
True 时关键点从 468 增至 478 |
min_detection_confidence |
0.5 |
最小检测置信度 |
min_tracking_confidence |
0.5 |
最小跟踪置信度 |
关键点连接类型速查
| 连接类型 |
说明 |
FACEMESH_TESSELATION |
完整三角网格 |
FACEMESH_CONTOURS |
五官轮廓 |
FACEMESH_IRISES |
虹膜轮廓 |
FACEMESH_LEFT_EYE |
左眼轮廓 |
FACEMESH_RIGHT_EYE |
右眼轮廓 |
注意事项
| 要点 |
说明 |
| 图像格式 |
MediaPipe 需要 RGB 输入,OpenCV 默认 BGR,需要转换 |
| 坐标归一化 |
关键点坐标是 0~1 的归一化值,需乘以图像宽高 |
| 关键点数量 |
refine_landmarks=True 时是 478,否则是 468 |
| 处理速度 |
478 个关键点计算量较大,可考虑降低分辨率 |
| 绘制风格 |
不同连接类型对应不同绘制风格,注意匹配 |
系列直达