dlib库
是一个适用于C++和Python的第三方库。包含机器学习、计算机视觉和图像处理的工具包,被广泛的应用于机器人、嵌入式设备、移动电话和大型高性能计算环境。是开源许可用户免费使用。
opencv优缺点:
优点:可以在CPU上实时工作,简单的架构,可以检测不同比例的人脸。
缺点:会出现大量的把非人脸预测为人脸的情况,不适用于非正面人脸图像,不抗遮挡。
dlib优缺点:
优点 :适用于正面和略微非正面的人脸,语法极简单,再小的遮挡下仍可工作,
缺点:不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,较小尺寸的人脸数据需自己训练检测器,边界框通常排除前额的一部分甚至下巴的一部分,不适用于侧面和极端非正面,如俯视或仰视。
dlib库中的get_frontal_face_detector()
函数和shape_predictor("shape_predictor_68_face_landmarks.dat")
算法是用于人脸检测和特征点定位的两个重要组件。
-
get_frontal_face_detector()
函数:- 这个函数是dlib库提供的一个用于人脸检测的工具。它基于 Histogram of Oriented Gradients(HOG)特征和级联分类器的方法来检测图像中的人脸。
- HOG特征是一种用于物体检测的图像描述符,它通过统计图像中局部区域的梯度方向来捕捉形状信息。这种方法对光照变化和几何形变具有一定的鲁棒性。
- 级联分类器由多个弱分类器组成,每个弱分类器都针对图像的不同特征进行训练。通过级联的方式,可以逐步排除非人脸区域,提高检测效率和准确性。
- 该函数能够在不同尺度的图像中检测出人脸,通过滑动窗口技术在多个尺度上重复检测步骤,确保算法能够捕捉到不同大小的人脸。
-
shape_predictor("shape_predictor_68_face_landmarks.dat")
算法:- 这是一个人脸特征点定位算法,它基于深度学习的方法,使用了一个预训练的模型文件
shape_predictor_68_face_landmarks.dat
。这个模型能够识别人脸上的68个关键点,包括眼睛、鼻子、嘴巴等部位的位置。 - 该算法使用的是“回归树”的概念,通过建立一个级联的残差回归树(Gradient Boosting Decision Trees, GBDT)来使人脸形状从初始形状逐步回归到真实形状。每个GBDT的叶子节点上都存储着一个残差回归量,当输入落到一个节点上时,就将残差加到该输入上,起到回归的目的。
- 在训练时,使用标记有人脸特征点的图像来训练一个集成的回归树模型,这些回归树共同预测人脸特征点的位置。在测试时,无论给出怎样一幅图像,都通过这个模型来预测人脸特征点的位置。
- 该算法能够用于实时的人脸特征点检测,并且预测质量高,是一个高效且鲁棒的特征点定位方法。
- 这是一个人脸特征点定位算法,它基于深度学习的方法,使用了一个预训练的模型文件
代码步骤
-
导入必要的库:
- 使用
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')
- 使用
-
人脸检测:
- 使用dlib的
get_frontal_face_detector()
函数创建一个人脸检测器对象。 - 调用检测器对象的函数,传入图像和检测参数,获取图像中的人脸区域。
# 创建一个面部检测器对象,这里使用的是dlib库中的HOG(方向梯度直方图)特征检测器。 detector = dlib.get_frontal_face_detector() # 使用detector对象检测图片中的面部,参数0表示在不同尺度上进行检测,0表示不进行金字塔层次的上采样。 faces = detector(img, 0)
- 使用dlib的
-
特征点预测:
- 使用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()])
- 使用dlib的
-
绘制特征点:
- 遍历每个预测的特征点,使用
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()