文章要求:1:清晰、2:容易理解、3:不含糊其词、4:反复修改
deepface分为4个部分:
1:人脸检测
2:人脸对齐
3:特征提取
4:特征匹配
1:人脸检测,就是给定一张包含人脸的图片,给定的图片很大,但其中的人脸只占一小部分,例如,一个人的上半身的照片,人脸只有一小部分,
目标就是把图中的人脸的那一小部分区域截取出来,如果有多个人脸,那就截取多个人脸区域,如果只有一个人脸,那么返回一个边界框(bounding box,边界框由四个坐标组成:左上角的 x 和 y 坐标,以及右下角的 x 和 y 坐标),如果有多个人脸,那就返回一个列表,列表每个元素表示一个边界框,就像下图中5个红框一样,图中5个人脸,所以检测到5个红框,
通常用MTCNN或者haar-cascade进行人脸检测
这一步骤涉及从图像或视频中检测到人脸区域。deepface 支持多种人脸检测器,包括:
dlib:使用 HOG(Histogram of Oriented Gradients)和深度学习模型进行检测。
OpenCV:基于 Haar 级联分类器进行检测。
MTCNN:Multi-task Cascaded Convolutional Networks,用于人脸检测。
RetinaFace:使用 RetinaFace 模型进行检测。
在这里是人脸检测的代码
import cv2
import dlib
# 加载图像
image_path = 'image.jpg'
image = cv2.imread(image_path)
# 转换为灰度图像,为什么要转为灰度图像,因为这样更有利于人脸检测
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 初始化 dlib 的人脸检测器
detector = dlib.get_frontal_face_detector()
# 执行人脸检测
faces = detector(gray)
# 绘制边界框
for face in faces:
x, y, w, h = (face.left(), face.top(), face.width(), face.height())
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示检测结果
cv2.imshow('Detected Faces', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
2:人脸对齐,就是根据上一步检测到的人脸,通过变换得到一个更加标准化的人脸,这样可以消除人脸变形、倾斜、转头、抬头、光影变化等乱七八糟的不利影响,可以把人脸调整到更标准的姿态,目的是提升面部特征提取的准确性和特征提取的一致性,
(可以粗略的理解为:把不标准的人脸,把各种不利于特征提取的因素去掉,把人脸调整到标准的证件照式的人脸)
原理:从截取到的小块人脸图片中提取68个关键点(136维特征向量),选中三个点(通常是左眼角、右眼角、鼻尖或者嘴角)作为输入,在从预定义的标准姿态的模板图像中也找到这三个关键点作为输出,这样有输入,有输出,计算出仿射矩阵,,然后把小块人脸区域经过这个放射矩阵得到对齐后的人脸,
deepface用2d人脸对齐,没有用3d人脸对齐
PS:我自己测试过一个不标准的人脸,经过对齐后,显示,我发现并没有改善多少,可能有些不利因素的改善用人眼看不出来吧,
在这里插入代码片
import cv2
import dlib
import numpy as np
# 加载图像
image_path = 'path_to_your_image.jpg'
image = cv2.imread(image_path)
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 初始化 dlib 的人脸检测器和关键点检测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 执行人脸检测
faces = detector(gray)
for face in faces:
# 检测关键点
landmarks = predictor(gray, face)
landmarks = np.array([[p.x, p.y] for p in landmarks.parts()])
# 选择关键点:左眼角、右眼角、鼻尖
src_points = landmarks[[36, 45, 30]] # 左眼角、右眼角、鼻尖
dst_points = np.array([[30, 30], [70, 30], [50, 60]], dtype=np.float32) # 标准位置
# 计算仿射变换矩阵
matrix, _ = cv2.estimateAffine2D(src_points, dst_points)
# 应用仿射变换
aligned_face = cv2.warpAffine(image, matrix, (image.shape[1], image.shape[0]))
# 显示对齐后的图像
cv2.imshow('Aligned Face', aligned_face)
cv2.waitKey(0)
cv2.destroyAllWindows()
3:特征提取
这步就是把对齐后的人脸resize到112 x 112 或者224 x 224的标准尺寸,然后输入到神经网络中区,输出就是一个高维特征向量( 128 维或 512 维),这步在deepface中都是有下载的模型处理的,
在这里插入代码片
from deepface import DeepFace
# 加载图像
image_path = 'path_to_your_aligned_image.jpg'
# 特征提取
result = DeepFace.represent(img_path=image_path, model_name='VGG-Face')
# 输出特征向量
features = result['embedding']
print(features)
4:特征匹配
这步就是把上一步提取到的特征向量和数据库中图片的特征向量(对数据库中所有的图片也进行之前1,2,3步骤,假设数据库中有100个图片,对应100个特征向量)进行计算,得到100个距离,然后排序,距离最小的就是数据库中和给定图片最相似的图片
在这里插入代码片
from deepface import DeepFace
import numpy as np
from scipy.spatial.distance import cosine
# 提取待识别图像的特征向量
input_image_path = 'path_to_input_image.jpg'
input_features = DeepFace.represent(img_path=input_image_path, model_name='VGG-Face')['embedding']
# 假设有一个数据库中的特征向量列表
database_features = {
'image1.jpg': DeepFace.represent(img_path='path_to_image1.jpg', model_name='VGG-Face')['embedding'],
'image2.jpg': DeepFace.represent(img_path='path_to_image2.jpg', model_name='VGG-Face')['embedding'],
# 其他图像
}
# 计算距离并进行排序
distances = {}
for image, features in database_features.items():
distance = cosine(input_features, features) # 计算余弦距离
distances[image] = distance
# 排序距离
sorted_images = sorted(distances.items(), key=lambda item: item[1])
# 输出最相似的图像
print("最相似的图像:", sorted_images[0])