当前位置: 首页 > news >正文

实用指南:计算机视觉:人脸关键点定位与轮廓绘制

实用指南:计算机视觉:人脸关键点定位与轮廓绘制

目录

一、关键模型准备

二、实战 1:人脸 68 个关键点定位

2.1 核心原理

2.2 完整代码实现

2.3 结果说明

三、实战 2:基于关键点的面部轮廓绘制

3.1 核心原理

3.2 完整代码实现

3.3 运行效果

四、常见问题与解决方案

1.模型路径错误

2.未检测到人脸

3.关键点绘制错位

五、技术扩展:关键点的应用场景


在计算机视觉领域,人脸关键点检测是表情识别、人脸编辑、疲劳监测等高级应用的核心基础。本文将跳过环境搭建环节,直接从核心原理出发,结合 OpenCV 与 dlib 库,详细讲解人脸 68 个关键点的定位与面部轮廓绘制的完整实现过程。


一、关键模型准备

dlib 的人脸关键点预测依赖预训练模型shape_predictor_68_face_landmarks.dat,该模型可精准检测人脸的 68 个关键点(涵盖眼睛、眉毛、鼻子、嘴巴、面部轮廓)。

  • 下载地址:https://github.com/davisking/dlib-models
  • 使用说明:下载后将模型文件与代码放在同一目录,避免后续路径调用错误。

二、实战 1:人脸 68 个关键点定位

2.1 核心原理

dlib 的关键点检测基于级联回归树算法,整体流程分为三步:

  • 人脸检测:通过dlib.get_frontal_face_detector()识别图像中的人脸区域,输出人脸边界框;
  • 关键点预测:利用预训练的shape_predictor模型,在人脸边界框内定位 68 个关键点的坐标;
  • 可视化展示:将关键点坐标转换为 NumPy 数组,通过 OpenCV 绘制关键点及编号,直观呈现检测结果。

2.2 完整代码实现

'''
功能:检测人脸68个关键点,并绘制关键点及编号
依赖库:numpy, cv2, dlib
模型:shape_predictor_68_face_landmarks.dat(需与代码同目录)
'''
import numpy as np
import cv2
import dlib
# 1. 读取图像(替换为你的图像路径,支持png/jpg格式)
img = cv2.imread("man.png")
# 读取失败判断
if img is None:raise ValueError("图像读取失败,请检查文件路径是否正确!")
# 2. 初始化人脸检测器(正面人脸检测)
detector = dlib.get_frontal_face_detector()
# 3. 检测图像中的人脸(参数0:不放大图像,平衡速度与精度)
faces = detector(img, 0)
if len(faces) == 0:print("未检测到人脸,请更换清晰正面人脸图像重试!")
else:print(f"共检测到 {len(faces)} 张人脸")
# 4. 加载关键点预测模型
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 5. 遍历人脸,获取并绘制关键点
for face in faces:# 5.1 预测当前人脸的68个关键点shape = predictor(img, face)  # shape包含68个关键点对象# 5.2 转换关键点为(x, y)坐标数组(便于后续处理)landmarks = np.array([[p.x, p.y] for p in shape.parts()])# 5.3 绘制关键点(绿色实心圆)与编号(白色文字)for idx, point in enumerate(landmarks):pos = (point[0], point[1])  # 关键点坐标# 绘制实心圆:图像、坐标、半径2、颜色(0,255,0)(BGR)、厚度-1(填充)cv2.circle(img, pos, radius=2, color=(0, 255, 0), thickness=-1)# 绘制编号:字体SIMPLEX、字号0.4、颜色(255,255,255)、厚度1、抗锯齿cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.4, color=(255, 255, 255), thickness=1, lineType=cv2.LINE_AA)
# 6. 显示结果与释放资源
cv2.imshow("Face 68 Landmarks", img)
cv2.waitKey(0)  # 按任意键关闭窗口
cv2.destroyAllWindows()

2.3 结果说明

关键点编号规则:68 个关键点按区域划分,具体对应关系如下:

  • 0-16:面部轮廓(从下巴到额头两侧)
  • 17-21:左眉,22-26:右眉
  • 27-35:鼻子(含鼻梁、鼻尖、鼻翼)
  • 36-41:右眼,42-47:左眼
  • 48-67:嘴巴(48-59 为外轮廓,60-67 为内轮廓)

可视化效果:图像中每个关键点以绿色实心圆标记,旁边标注白色编号,可清晰区分不同面部区域的关键点位置。


三、实战 2:基于关键点的面部轮廓绘制

在获取 68 个关键点后,通过凸包算法线段绘制,可进一步勾勒面部轮廓,让检测结果更直观。

3.1 核心原理

  • 凸包算法(cv2.convexHull):对于眼睛、嘴巴等闭合区域,通过关键点生成凸多边形,准确包裹区域边界,避免轮廓断裂;
  • 线段绘制(cv2.line):对于面部轮廓、眉毛、鼻子等非闭合区域,将连续关键点用线段连接,形成完整的线性轮廓。

3.2 完整代码实现

'''
功能:基于68个关键点绘制面部轮廓(眉毛、眼睛、鼻子、嘴巴、面部轮廓)
依赖库:numpy, cv2, dlib
'''
import numpy as np
import dlib
import cv2
# 1. 定义轮廓绘制工具函数
def draw_line(start, end):'''绘制线段:连接从start到end的连续关键点(左闭右开区间)'''pts = shape[start:end]  # 获取关键点区间for i in range(1, len(pts)):pt_a = tuple(pts[i-1])  # 前一个关键点pt_b = tuple(pts[i])    # 当前关键点# 绘制绿色线段,厚度2cv2.line(image, pt_a, pt_b, color=(0, 255, 0), thickness=2)
def draw_convex_hull(start, end):'''绘制凸包轮廓:用于眼睛、嘴巴等闭合区域(包含end的闭区间)'''facial_pts = shape[start:end+1]  # 获取关键点区间hull = cv2.convexHull(facial_pts)  # 生成凸包# 绘制绿色凸包轮廓,厚度2(-1表示填充,此处用2保留轮廓线)cv2.drawContours(image, [hull], -1, (0, 255, 0), thickness=2)
# 2. 读取图像
image = cv2.imread("man.png")
if image is None:raise ValueError("图像读取失败,请检查文件路径!")
# 3. 人脸检测与关键点预测(与实战1逻辑一致)
detector = dlib.get_frontal_face_detector()
faces = detector(image, 0)
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
if len(faces) == 0:print("未检测到人脸!")
else:for face in faces:# 获取关键点并转换为数组shape = predictor(image, face)shape = np.array([[p.x, p.y] for p in shape.parts()])# 4. 按区域绘制轮廓(关键:对应68个关键点的正确区间)draw_convex_hull(36, 41)   # 右眼轮廓(36-41号关键点)draw_convex_hull(42, 47)   # 左眼轮廓(42-47号关键点)draw_convex_hull(48, 59)   # 嘴巴外部轮廓(48-59号关键点)draw_convex_hull(60, 67)   # 嘴巴内部轮廓(60-67号关键点)draw_line(0, 17)           # 面部轮廓(0-16号,左闭右开需到17)draw_line(17, 22)          # 左眉轮廓(17-21号关键点)draw_line(22, 27)          # 右眉轮廓(22-26号关键点)draw_line(27, 36)          # 鼻子轮廓(27-35号关键点)
# 5. 结果展示与保存(可选)
cv2.imshow("Face Contours", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存结果图像到当前目录
cv2.imwrite("face_contours_result.png", image)
print("结果图像已保存为 face_contours_result.png")

3.3 运行效果

代码运行后,图像将呈现以下绿色轮廓:

  • 闭合轮廓:左右眼(凸包形状,完整包裹眼球区域)、嘴巴内外侧(区分嘴唇与牙齿边界);
  • 线性轮廓:面部轮廓(从下巴尖沿脸颊到额头两侧)、左右眉毛(沿眉形连接关键点)、鼻子(从鼻梁到鼻尖的中线)。


四、常见问题与解决方案

1.模型路径错误

报错信息:Unable to open shape_predictor_68_face_landmarks.dat

解决:确认模型文件与代码在同一目录,或在shape_predictor中传入完整路径(如"D:/cv_project/shape_predictor_68_face_landmarks.dat")。

2.未检测到人脸

原因:图像中无正面人脸、人脸尺寸过小(小于 80×80 像素,dlib 默认最小检测尺寸)或光线过暗。

解决:更换清晰正面人脸图像,或调整detector参数(如detector(img, 1),1 表示放大图像 1 倍后检测,提升小人脸识别率)。

3.关键点绘制错位

原因:图像读取时通道顺序错误(OpenCV 默认 BGR,若误转为 RGB 会导致坐标偏移)。

解决:确保直接使用cv2.imread()读取图像,不额外转换通道顺序(除非后续有特殊处理需求)。


五、技术扩展:关键点的应用场景

人脸 68 个关键点是计算机视觉中极具价值的基础数据,基于本文技术可进一步扩展以下应用:

表情识别:通过嘴巴关键点(48-67)的开合程度、眼睛关键点(36-47)的眯眼状态,判断微笑、愤怒、惊讶等表情;

疲劳监测:计算眼睛纵横比(如 “眼高 / 眼宽”,当比值 < 0.3 时判定为闭眼),统计单位时间内闭眼次数与时长,预警疲劳状态;

人脸编辑:结合仿射变换(cv2.warpAffine),基于关键点实现人脸对齐、换脸、妆容迁移(如将 A 的眉毛轮廓复制到 B 的脸上)。

http://www.hskmm.com/?act=detail&tid=20200

相关文章:

  • JVM调优工具详解及调优实战
  • 双链表
  • ubuntu系统挂载硬盘
  • 代码之美-代码整洁之道
  • Chrome for Testing availability
  • RAG实践:一文掌握大模型RAG过程
  • 递归算法实践--到仓合单助力京东物流提效增收
  • 计算机视觉(opencv)练习——抠图(图像裁剪与轮廓提取) - 详解
  • 深入解析:@scqilin/phone-ui 手机外观组件库
  • Tita项目与绩效一体化管理:驱动企业效能跃升的数字化引擎
  • 第七篇
  • labview打包应用
  • Day23抽象类
  • ES 是否有类似mysql explain的语句诊断用法
  • 让每次语音唤醒都可靠,公牛沐光重构可观测体系
  • 【2025-09-27】连岳摘抄
  • Python 爬虫 HTTPS 实战,requests httpx aiohttp 抓取技巧、证书问题与抓包调试全流程 - 教程
  • Codeforces 补题笔记
  • 使用 Python 基于Ollama构建个人私有知识库(AI生成)
  • Codeforces Round 1048 (Div. 2) 补题笔记
  • 【RabbitMQ】消息可靠性保障
  • React学习笔记(一)
  • Day23static详解
  • 11.prometheus监控之黑盒(blackbox)监控
  • Python虚拟环境及创建和使用虚拟环境(Python3)
  • 团队协作必备:16款在线协同编辑文档方案对比
  • 变电站、开闭所、环网柜、配电站
  • 为AI注入灵魂:一种面向人机黑箱的元人文治理新范
  • clickhouse
  • 2025.9.28——1黄