opencv学习:使用dlib进行人脸检测和特征点定位及完整代码实现

dlib库

是一个适用于C++和Python的第三方库。包含机器学习、计算机视觉和图像处理的工具包,被广泛的应用于机器人、嵌入式设备、移动电话和大型高性能计算环境。是开源许可用户免费使用。

opencv优缺点:

优点:可以在CPU上实时工作,简单的架构,可以检测不同比例的人脸。

缺点:会出现大量的把非人脸预测为人脸的情况,不适用于非正面人脸图像,不抗遮挡。

dlib优缺点:

优点 :适用于正面和略微非正面的人脸,语法极简单,再小的遮挡下仍可工作,

缺点:不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,较小尺寸的人脸数据需自己训练检测器,边界框通常排除前额的一部分甚至下巴的一部分,不适用于侧面和极端非正面,如俯视或仰视。

dlib库中的get_frontal_face_detector()函数和shape_predictor("shape_predictor_68_face_landmarks.dat")算法是用于人脸检测和特征点定位的两个重要组件。

  1. get_frontal_face_detector()函数:

    • 这个函数是dlib库提供的一个用于人脸检测的工具。它基于 Histogram of Oriented Gradients(HOG)特征和级联分类器的方法来检测图像中的人脸。
    • HOG特征是一种用于物体检测的图像描述符,它通过统计图像中局部区域的梯度方向来捕捉形状信息。这种方法对光照变化和几何形变具有一定的鲁棒性。
    • 级联分类器由多个弱分类器组成,每个弱分类器都针对图像的不同特征进行训练。通过级联的方式,可以逐步排除非人脸区域,提高检测效率和准确性。
    • 该函数能够在不同尺度的图像中检测出人脸,通过滑动窗口技术在多个尺度上重复检测步骤,确保算法能够捕捉到不同大小的人脸。
  2. shape_predictor("shape_predictor_68_face_landmarks.dat")算法:

    • 这是一个人脸特征点定位算法,它基于深度学习的方法,使用了一个预训练的模型文件shape_predictor_68_face_landmarks.dat。这个模型能够识别人脸上的68个关键点,包括眼睛、鼻子、嘴巴等部位的位置。
    • 该算法使用的是“回归树”的概念,通过建立一个级联的残差回归树(Gradient Boosting Decision Trees, GBDT)来使人脸形状从初始形状逐步回归到真实形状。每个GBDT的叶子节点上都存储着一个残差回归量,当输入落到一个节点上时,就将残差加到该输入上,起到回归的目的。
    • 在训练时,使用标记有人脸特征点的图像来训练一个集成的回归树模型,这些回归树共同预测人脸特征点的位置。在测试时,无论给出怎样一幅图像,都通过这个模型来预测人脸特征点的位置。
    • 该算法能够用于实时的人脸特征点检测,并且预测质量高,是一个高效且鲁棒的特征点定位方法。

代码步骤

  1. 导入必要的库

    • 使用import语句导入OpenCV、dlib和NumPy库。
    • 使用cv2.imread()函数读取存储在本地的图像文件。
      # 导入cv2模块,这是一个用于图像处理的库。
      import cv2 
      # 导入dlib库,这是一个包含多种机器学习算法的库,特别适用于实时的面部识别。
      import dlib 
      # 导入numpy库,这是一个用于数值计算的库。
      import numpy as np 
      
      # 使用cv2库的imread函数读取名为'renlian1.jpg'的图片文件。
      img = cv2.imread('renlian1.jpg')
  2. 人脸检测

    • 使用dlib的get_frontal_face_detector()函数创建一个人脸检测器对象。
    • 调用检测器对象的函数,传入图像和检测参数,获取图像中的人脸区域。
      # 创建一个面部检测器对象,这里使用的是dlib库中的HOG(方向梯度直方图)特征检测器。
      detector = dlib.get_frontal_face_detector()
      # 使用detector对象检测图片中的面部,参数0表示在不同尺度上进行检测,0表示不进行金字塔层次的上采样。
      faces = detector(img, 0)
  3. 特征点预测

    • 使用dlib的shape_predictor函数和预训练的模型文件(shape_predictor_68_face_landmarks.dat)来创建一个特征点预测器对象。
      # 创建一个面部特征点预测器对象,使用预先训练好的模型文件"shape_predictor_68_face_landmarks.dat"。
      predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
    • 对于检测到的每个人脸区域,使用预测器对象来预测面部特征点。
      # 遍历检测到的每一个面部。
      for face in faces:
          # 使用predictor对象预测面部的特征点。
          shape = predictor(img, face)
          # 将预测的特征点坐标转换为numpy数组。
          landmarks = np.array([[p.x, p.y] for p in shape.parts()])
  4. 绘制特征点

    • 遍历每个预测的特征点,使用cv2.circle()在图像上绘制圆形标记。
    • 使用cv2.putText()在每个特征点旁边绘制该点的索引编号。
      # 遍历每一个特征点。
          for idx, point in enumerate(landmarks):
              # 将特征点的坐标保存到pos变量中。
              pos = [point[0], point[1]]
              # 在特征点的位置绘制一个绿色的圆圈,半径为2,厚度为-1(填充圆)。
              cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1)
              # 在特征点的位置上方绘制该点的索引编号,颜色为白色。
              cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
      # 显示标记了特征点的图片。
      cv2.imshow('img', img)
      # 等待按键,0表示无限等待直到有按键按下。
      cv2.waitKey(0)

运行结果

完整代码

# 导入cv2模块,这是一个用于图像处理的库。
import cv2 
# 导入dlib库,这是一个包含多种机器学习算法的库,特别适用于实时的面部识别。
import dlib 
# 导入numpy库,这是一个用于数值计算的库。
import numpy as np 

# 使用cv2库的imread函数读取名为'renlian1.jpg'的图片文件。
img = cv2.imread('renlian1.jpg')
# 创建一个面部检测器对象,这里使用的是dlib库中的HOG(方向梯度直方图)特征检测器。
detector = dlib.get_frontal_face_detector()
# 使用detector对象检测图片中的面部,参数0表示在不同尺度上进行检测,0表示不进行金字塔层次的上采样。
faces = detector(img, 0)
# 创建一个面部特征点预测器对象,使用预先训练好的模型文件"shape_predictor_68_face_landmarks.dat"。
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 遍历检测到的每一个面部。
for face in faces:
    # 使用predictor对象预测面部的特征点。
    shape = predictor(img, face)
    # 将预测的特征点坐标转换为numpy数组。
    landmarks = np.array([[p.x, p.y] for p in shape.parts()])
    # 遍历每一个特征点。
    for idx, point in enumerate(landmarks):
        # 将特征点的坐标保存到pos变量中。
        pos = [point[0], point[1]]
        # 在特征点的位置绘制一个绿色的圆圈,半径为2,厚度为-1(填充圆)。
        cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1)
        # 在特征点的位置上方绘制该点的索引编号,颜色为白色。
        cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
# 显示标记了特征点的图片。
cv2.imshow('img', img)
# 等待按键,0表示无限等待直到有按键按下。
cv2.waitKey(0)
# 销毁所有由cv2创建的窗口。
cv2.destroyAllWindows()

猜你喜欢

转载自blog.csdn.net/mohanyelong/article/details/143026718