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

基于dlib与OpenCV的人脸检测与特征点标定技术实践

文章目录

    • dlib库安装方法
      • 1. 使用pip安装(Windows/macOS/Linux)
    • 一、基础人脸检测:静态图像处理
    • 二、实时视频人脸检测:双检测器对比
    • 三、面部关键点检测:68点定位
    • 四、实时面部轮廓绘制:凸包与连线

在开始之前,我们需要确保环境配置正确。dlib是一个强大的C++机器学习库,提供了高效的人脸检测和特征点标定算法。下面首先介绍如何安装dlib库。

dlib库安装方法

在Python环境中安装dlib,推荐使用以下方式:

1. 使用pip安装(Windows/macOS/Linux)

pip install dlib

安装注意事项:

  • dlib需要CMake和C++编译器支持
  • Windows用户可能需要安装Visual Studio Build Tools
  • 建议使用Python 3.6及以上版本
  • 安装成功后可以通过import dlib验证

一、基础人脸检测:静态图像处理

现在开始我们的第一个示例,展示如何使用dlib库检测图像中的人脸位置。

import cv2
import dlib

# 初始化dlib的人脸检测器
detector = dlib.get_frontal_face_detector()
# 读取待检测的图像文件
img = cv2.imread("people1.png")
# 使用检测器在图像中查找人脸,参数1表示图像金字塔的放大倍数
faces = detector(img, 1)

# 遍历所有检测到的人脸区域
for face in faces:
# 获取人脸边界框的坐标:左上角(x1, y1)和右下角(x2, y2)
x1 = face.left()
y1 = face.top()
x2 = face.right()
y2 = face.bottom()
# 在图像上绘制绿色矩形框标记人脸区域,线宽为2像素
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

# 将图像缩小一半显示,便于观察
cv2.imshow("Face Detection Result", cv2.resize(img, None, fx=0.5, fy=0.5))
# 等待任意按键按下
cv2.waitKey(0)
# 关闭所有OpenCV创建的窗口
cv2.destroyAllWindows()

在这里插入图片描述

关键技术点分析:

  • 人脸检测器初始化:dlib.get_frontal_face_detector()创建基于HOG特征和线性SVM分类器的人脸检测器,对正面人脸检测效果良好。

  • 检测参数说明:detector(img, 1)中的第二个参数为upsample_num_times,表示对图像进行上采样的次数。适当的上采样可以帮助检测更小的人脸,但会增加计算时间。

  • 坐标系统:OpenCV使用左上角为原点(0,0),x轴向右,y轴向下的坐标系。face.left()、face.top()分别返回边界框左上角的x和y坐标。

  • 二、实时视频人脸检测:双检测器对比

    在实际应用中,我们经常需要处理视频流。这个示例同时使用了OpenCV的Haar级联分类器和dlib检测器,方便对比两种方法的检测效果。

    import cv2
    import dlib

    # 初始化摄像头,参数0表示使用默认摄像头
    cap = cv2.VideoCapture(0)
    # 初始化dlib人脸检测器
    detector = dlib.get_frontal_face_detector()
    # 加载OpenCV的Haar级联分类器文件
    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

    while True:
    # 从摄像头读取一帧图像,ret表示读取是否成功
    ret, img = cap.read()
    if ret is None:
    break

    # 将彩色图像转换为灰度图像,大多数检测算法需要灰度输入
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 使用dlib检测灰度图像中的人脸
    faces = detector(gray, 1)

    # 使用OpenCV的Haar级联分类器检测人脸
    face = faceCascade.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=15, minSize=(8, 8))

    # 绘制OpenCV检测到的人脸矩形框
    for (x, y, w, h) in face:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

    cv2.imshow("OpenCV Face Detection", cv2.resize(img,None,fx=0.5,fy=0.5))

    # 绘制dlib检测到的人脸矩形框
    for face in faces:
    x1 = face.left()
    y1 = face.top()
    x2 = face.right()
    y2 = face.bottom()
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    cv2.imshow("Dlib Face Detection", cv2.resize(img,None,fx=0.5,fy=0.5))

    # 检测ESC键是否被按下(ASCII码为27),如果是则退出循环
    if cv2.waitKey(1) == 27:
    break

    # 释放摄像头资源
    cap.release()
    # 关闭所有OpenCV窗口
    cv2.destroyAllWindows()

    在这里插入图片描述

    参数深入解析:

  • VideoCapture参数:cv2.VideoCapture(0)中的0代表系统默认摄像头,可以替换为视频文件路径处理已录制的视频。

  • Haar级联分类器参数:

    • scaleFactor=1.05:图像金字塔的缩放比例,决定搜索窗口的放大步长
    • minNeighbors=15:候选框周围需要有多少个邻居框才能被保留,值越大检测越严格
    • minSize=(8, 8):检测目标的最小尺寸,忽略更小的区域
  • waitKey参数:cv2.waitKey(1)中的1表示等待1毫秒,这是视频流畅播放的关键。返回值为按键的ASCII码。

  • 三、面部关键点检测:68点定位

    人脸特征点检测是人脸分析的重要步骤,可以精确定位眼睛、鼻子、嘴巴等关键部位。

    import numpy as np
    import cv2
    import dlib

    # 读取待处理的图像
    img = cv2.imread("lian.jpeg")
    # 初始化dlib人脸检测器
    detector = dlib.get_frontal_face_detector()
    # 检测图像中的人脸
    faces = detector(img, 0)
    # 加载预训练的面部特征点预测器
    predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

    # 遍历所有检测到的人脸
    for face in faces:
    # 对每个人脸预测68个特征点的位置
    shape = predictor(img, face)
    # 将特征点转换为numpy数组格式,便于处理
    landmarks = np.array([[p.x, p.y] for p in shape.parts()])

    # 遍历所有特征点,绘制并标记序号
    for idx, point in enumerate(landmarks):
    # 获取特征点的坐标位置
    pos = (point[0], point[1])
    # 在特征点位置绘制实心圆点,半径为2像素,绿色
    cv2.circle(img, pos, 2, (0, 255, 0), 1)
    # 在特征点旁边标记序号
    cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)

    # 显示处理结果,图像缩放为原来的80%
    cv2.imshow("Facial Landmarks", cv2.resize(img, None, fx=0.8, fy=0.8))
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    在这里插入图片描述

    特征点分布说明:

    68个特征点按照以下方式分布:

    • 0-16点:下巴轮廓
    • 17-21点:右眉毛
    • 22-26点:左眉毛
    • 27-35点:鼻梁和鼻尖
    • 36-41点:右眼轮廓
    • 42-47点:左眼轮廓
    • 48-67点:嘴唇外轮廓和内轮廓

    关键技术细节:

  • shape_predictor初始化:需要预训练的模型文件,该模型基于iBUG 300-W数据集训练,能够准确预测68个人脸关键点。

  • 特征点可视化:使用cv2.circle()绘制实心圆点,-1参数表示填充整个圆。cv2.putText()用于添加文本标签,参数依次为:图像、文本内容、位置、字体、字号、颜色、线宽、线型。

  • 四、实时面部轮廓绘制:凸包与连线

    这个示例将特征点检测应用于实时视频,并绘制出面部的主要轮廓线,形成更直观的视觉效果。

    import numpy as np
    import dlib
    import cv2

    def drawLine(start, end):
    """绘制两点之间的连线"""
    # 获取起始点到结束点之间的所有特征点
    pts = shape[start:end]
    # 遍历相邻点对,绘制连接线
    for l in range(1, len(pts)):
    ptA = tuple(pts[l 1])
    ptB = tuple(pts[l])
    cv2.line(image, ptA, ptB, (0, 255, 0), 2)

    def drawConvexHull(start, end):
    """绘制特征点的凸包轮廓"""
    # 获取指定范围内的特征点
    Facial = shape[start:end + 1]
    # 计算凸包(最小凸多边形)
    mouthHull = cv2.convexHull(Facial)
    # 绘制凸包轮廓
    cv2.drawContours(image, [mouthHull], 1, (0, 255, 0), 2)

    # 初始化摄像头
    cap = cv2.VideoCapture(0)
    # 初始化dlib人脸检测器
    detector = dlib.get_frontal_face_detector()

    while True:
    # 读取一帧图像
    ret, image = cap.read()
    if ret is None:
    break

    # 检测人脸
    faces = detector(image, 0)
    # 加载特征点预测器
    predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

    # 处理每个检测到的人脸
    for face in faces:
    # 预测特征点
    shape = predictor(image, face)
    # 转换为numpy数组
    shape = np.array([[p.x, p.y] for p in shape.parts()])

    # 绘制眼睛和嘴巴的凸包轮廓
    drawConvexHull(36, 41) # 右眼
    drawConvexHull(42, 47) # 左眼
    drawConvexHull(48, 59) # 外嘴唇
    drawConvexHull(60, 67) # 内嘴唇

    # 绘制面部轮廓连线
    drawLine(0, 17) # 下巴左侧
    drawLine(17, 22) # 眉毛之间
    drawLine(22, 27) # 眉毛到鼻梁
    drawLine(27, 36) # 鼻梁到右眼

    # 显示处理结果
    cv2.imshow("Face Contours", image)

    # 检测ESC键退出
    if cv2.waitKey(1) == 27:
    break

    # 释放资源
    cap.release()
    cv2.destroyAllWindows()

    在这里插入图片描述

    凸包算法原理:

    cv2.convexHull()函数计算给定点集的最小凸多边形。凸包是多边形的一种,其内部任意两点连线都在多边形内部。在人脸特征点应用中:

    • 眼睛轮廓:点36-41和42-47分别形成左右眼的凸包
    • 嘴唇轮廓:点48-59形成外嘴唇凸包,点60-67形成内嘴唇凸包
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 基于dlib与OpenCV的人脸检测与特征点标定技术实践
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!