📜  Python|使用 dlib 进行人脸识别(1)

📅  最后修改于: 2023-12-03 15:04:23.909000             🧑  作者: Mango

Python|使用 dlib 进行人脸识别

简介

dlib 是一个强大的 C++ 库,包含各种机器学习算法和计算机视觉算法。在计算机视觉方面,dlib 支持人脸检测、人脸对齐、人脸识别等任务。本文主要介绍在 Python 中使用 dlib 进行人脸识别的方法。

准备工作

在开始之前,需要先安装 dlib 库。可以在命令行中使用以下命令来安装:

pip install dlib

同时,由于 dlib 是一个 C++ 库,需要在其上运行 Python 扩展程序。因此还需要安装 CMake 和编译工具链。在 Ubuntu 上,可以使用以下命令来安装:

sudo apt-get install cmake
sudo apt-get install build-essential

如果你正在使用 Windows,则需要先安装 Visual Studio 或者编译工具链。

人脸检测

人脸检测是人脸识别过程的第一步,它的目的是从图像中检测并定位出人脸。Dlib 提供了基于 HOG 特征的人脸检测器,该检测器可以通过以下代码来使用:

import dlib
import cv2

detector = dlib.get_frontal_face_detector()

img = cv2.imread('input.jpg')
dets = detector(img, 1)

for i, d in enumerate(dets):
    cv2.rectangle(img, (d.left(), d.top()), (d.right(), d.bottom()), (0, 255, 0), 2)

cv2.imwrite('output.jpg', img)

在上述代码中,我们首先导入了 dlib 和 OpenCV 库。然后创建了一个人脸检测器 detector。然后我们通过 OpenCV 读取了一张名为 input.jpg 的图片,并进行了人脸检测。最后,我们将检测结果绘制在图片上,并将其保存到了 output.jpg。

人脸对齐

在进行人脸识别时,为了提取更加准确的特征,需要对图像中的人脸进行对齐。Dlib 提供了一个基于 5 个关键点的人脸对齐器,该对齐器可以通过以下代码来使用:

import dlib
import cv2
import numpy as np

predictor = dlib.shape_predictor('shape_predictor_5_face_landmarks.dat')

img = cv2.imread('input.jpg')
dets = detector(img, 1)

for i, d in enumerate(dets):
    shape = predictor(img, d)
    shape = np.array([(p.x, p.y) for p in shape.parts()])
    shape = shape[[1, 2, 0, 4, 3]]
    M = cv2.getAffineTransform(shape[:3], 96 * np.array([(0.3, 0.3), (0.7, 0.3), (0.5, 0.7)]))
    img = cv2.warpAffine(img, M, (96, 96))
    cv2.imwrite(f'output_{i}.jpg', img)

在上述代码中,我们首先创建了一个人脸关键点检测器 predictor。然后我们通过 OpenCV 读取了一张名为 input.jpg 的图片,并进行了人脸检测。接着,我们使用 predictor 得到了图像中人脸的 5 个关键点,并对这些关键点进行了一定的处理。最后,我们使用 cv2.getAffineTransform 和 cv2.warpAffine 对图片进行了人脸对齐,并将结果保存为 output_0.jpg、output_1.jpg 等。

需要注意的是,在上述代码中,我们将人脸对齐后的图片大小设置为 96x96。可以根据具体场景调整这个参数。

人脸识别

在进行人脸识别时,首先需要从人脸图像中提取特征。Dlib 提供了一个基于深度网络的人脸特征提取器,该特征提取器可以通过以下代码来使用:

import dlib
import numpy as np
import cv2

detector = dlib.get_frontal_face_detector()
sp = dlib.shape_predictor('shape_predictor_5_face_landmarks.dat')
facerec = dlib.face_recognition_model_v1('dlib_face_recognition_resnet_model_v1.dat')

def get_face_embedding(img):
    dets = detector(img, 1)
    if len(dets) == 0:
        return np.zeros((1, 128))
    face_descriptors = []
    for det in dets:
        shape = sp(img, det)
        face_descriptor = facerec.compute_face_descriptor(img, shape)
        face_descriptors.append(face_descriptor)
    return np.array(face_descriptors)

在上述代码中,我们首先创建了一个人脸检测器 detector、一个人脸关键点检测器 sp 和一个人脸特征提取器 facerec。然后我们定义了一个函数 get_face_embedding,该函数接受一张图像,并返回该图像中检测到的人脸的特征向量。

需要注意的是,在上述代码中,我们只提取了第一张检测到的人脸的特征向量。如果需要提取多张人脸的特征向量,可以进行一定的修改。

有了人脸特征向量后,我们可以使用欧氏距离来计算两个人脸特征向量之间的相似度。下面是一个比较简单的示例代码:

import numpy as np

def calc_dist(emb1, emb2):
    return np.sqrt(np.sum(np.square(emb1 - emb2)))

# 加载两张图片并提取特征
img1 = cv2.imread('img1.jpg')
emb1 = get_face_embedding(img1)
img2 = cv2.imread('img2.jpg')
emb2 = get_face_embedding(img2)

# 计算两者的距离
dist = calc_dist(emb1, emb2)
总结

本文介绍了如何使用 dlib 在 Python 中进行人脸识别。首先我们介绍了人脸检测、人脸对齐和人脸特征提取等基本概念。然后我们展示了如何使用 dlib 提供的各种算法实现这些功能。最后,我们给出了一个简单的示例来说明如何计算两张人脸图像之间的相似度。