当前位置 : 首页 > 保养数据

使用Python和OpenCV进行人脸识别

<|begin▁of▁sentence|># 使用 Python 和 OpenCV 进行人脸识别 > 原文: ![](img/2b5d5b5c6d9f5b7e3d4d7b4d2a4d3a0c.png) 在本教程中,您将学习如何使用 OpenCV、Python 和深度学习进行人脸识别。 我们将首先简要讨论基于深度学习的人脸识别是如何工作的,包括“深度度量学习”的概念。 然后,我将帮助您安装实际执行人脸识别所需的库。 最后,我们将实现人脸识别的实际 Python 代码。 **要了解如何使用 OpenCV、Python 和深度学习进行人脸识别,*请继续阅读!*** ## 使用 Python 和 OpenCV 进行人脸识别 在本教程的第一部分,我们将讨论基于深度学习的人脸识别,包括“深度度量学习”是如何工作的。 然后,我将向您展示如何安装执行人脸识别所需的库。 最后,我们将使用我们新安装的库实现人脸识别。 ### 深度度量学习如何用于人脸识别? ***注:*** *本节部分内容摘自我的书* [*《计算机视觉的深度学习》*](https://pyimagesearch.com/deep-learning-computer-vision-python-book/) *。* 人脸识别是衡量两张脸有多相似或者多不同的任务。典型的人脸识别流水线包括以下四个阶段: 1. **检测:**在图像中查找人脸 2. **对齐:**规范化人脸以与训练数据库一致(例如,左眼/右眼在图像中的相同位置) 3. **表示:**从对齐的人脸中提取特征向量 4. **分类:**确定这张脸到底是谁 在深度学习的背景下,人脸识别中的每个阶段都是由深度神经网络完成的。 阶段#1 可以使用诸如 [Haar cascades](https://pyimagesearch.com/2014/11/24/detecting-faces-images-python-opencv/) 、 [HOG +线性 SVM](https://pyimagesearch.com/2014/11/10/histogram-oriented-gradients-object-detection/) 、[单发检测器(SSD)](https://pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/) 或任何其他能够定位图像中人脸的对象检测器来执行。 然后,阶段#2 和#3 通常通过深度度量学习来执行。 **深度度量学习**是获取一个输入图像,然后使用深度神经网络返回一个*特征向量* (即,数字列表)的过程,如图**图 1** 所示。 对于人脸识别,这个特征向量(理想地)应该具有以下性质: 1. 同一个人的脸应该具有*相似的*特征向量(与某种距离度量相比) 2. 不同人的脸应该具有*不同的*特征向量 然后,在分类阶段(阶段#4),我们实际上可以给一个人分配一个名字! 但是,我们如何实际训练一个网络来产生这样的特征向量呢? 答案是在网络末端应用一个*三重损失函数*,从而*鼓励*两个性质。 通常,输出层通常被设置为一个 softmax 分类器来进行分类;然而,在人脸识别的背景下,这不是我们想要的——实际上,我们不是试图构建一个多类分类器。 相反,我们希望计算一个特征向量,使得同一个人的特征向量彼此“接近”,而不同人的特征向量彼此“远离”。 为了完成这项任务,我们需要定义一个*度量*来测量两个特征向量之间的相似性。然后,我们可以使用三元组损失函数来训练网络。 三元组损失函数可以被形式化为一个*“锚”*、一个*“正”*和一个*“负”*的例子: * **锚点:**我们网络输入的人脸图像。 * **正面:**也是*同一个人*作为锚点的人脸图像。 * **负面:**一张*不同人*的人脸图像。 本质上,我们希望锚点和正例之间的距离小于锚点和负例之间的距离(加上一个余量,以确保没有“崩溃的”零长度嵌入)。 **图 2** 可视化了锚点、正例和负例的概念: ![](img/2b5d5b5c6d9f5b7e3d4d7b4d2a4d3a0c.png) **Figure 2:** The Triplet Loss function for face recognition. We have an anchor image (left) of a specific person. We also have a positive image (middle) of the same person. The negative image (right) is of a *different* person. Our goal is to train a network such that the anchor and positive are closer together in the embedding space than the anchor and negative. 在训练过程中,我们向网络提供这三幅图像。然后,使用三重损失函数,网络学习: 1. 同一个人的两张脸(锚和正面)应该具有*相似的*特征向量。 2. 不同人的两张脸(锚和负面)应该具有*不同的*特征向量。 在训练之后,我们可以丢弃正/负例子——我们只需要*锚点*和网络本身。然后,我们可以计算输入人脸的特征向量,并将其与数据库中的人脸进行比较,以执行人脸识别。 有关深度度量学习和三重损失函数的更多细节,请务必参考我的书, *[用 Python 进行计算机视觉的深度学习](https://pyimagesearch.com/deep-learning-computer-vision-python-book/)* ,我在其中详细讨论了这些概念。 ### 安装您的人脸识别库 为了用 OpenCV 和 Python 进行人脸识别,我们需要安装两个额外的库: 1. `dlib` 2. `face_recognition` 由 Davis King 维护的`dlib`库包含了“深度度量学习”的实现,用于构建用于人脸识别的嵌入(正如我们上面讨论的)。 然后,`face_recognition`库,由 Adam Geitgey 创建,围绕`dlib`的人脸识别功能包装,使它更容易工作。 我假设您的系统上已经安装了 OpenCV。如果没有,不用担心——只需访问我的 [OpenCV 安装指南](https://pyimagesearch.com/opencv-tutorials-resources-guides/)页面,按照适合您机器的指南进行操作。 让我们从编译和安装`dlib`开始。 **注意:**我*强烈建议*在虚拟环境中安装`dlib`和`face_recognition`。我个人的偏好是使用 [virtualenv 和 virtualenvwrapper](https://pyimagesearch.com/2018/06/04/raspbian-stretch-install-opencv-3-python-on-your-raspberry-pi/) ,但是您也可以使用 [Anaconda](https://pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/) ,如果您喜欢的话。如果您还没有使用 Python 虚拟环境,请花些时间阅读一下它们——它们将允许您为每个项目隔离独立的 Python 环境,从而确保没有库/版本冲突。 首先,让我们安装`dlib`先决条件: ```py $ workon # optional $ sudo apt-get update $ sudo apt-get install build-essential cmake $ sudo apt-get install libopenblas-dev liblapack-dev $ sudo apt-get install libx11-dev libgtk-3-dev $ sudo apt-get install python python-dev python-pip $ sudo apt-get install python3 python3-dev python3-pip ``` ***注意:*** *上面的`workon`命令是可选的,只有在使用 virtualenv + virtualenvwrapper 的情况下才使用。* 从那里,让我们安装`dlib`。我推荐从 pypi 安装`dlib`(Python 包索引);但是,如果您想要针对您的特定系统进行编译,您可以从源代码编译。 要安装`dlib`,请使用以下命令: ```py $ workon # optional $ pip install dlib ``` 或者 ```py $ workon # optional $ pip install dlib==19.6.0 ``` 如果您需要从源代码编译`dlib`,请务必参考这篇[文章](https://pyimagesearch.com/2017/03/27/how-to-install-dlib/)以获得更多信息。 一旦`dlib`安装完毕,我们可以通过`pip`安装`face_recognition`包: ```py $ workon # optional $ pip install face_recognition ``` 现在让我们测试一下我们的安装: ```py $ python >>> import face_recognition >>> ``` 如果导入时没有错误,那么您就可以开始本教程的其余部分了。 ### 人脸识别数据集 [![](img/3b6d4d2a8d1d3b8d7e3d4b2d4a4d3a0c.png)](https://pyimagesearch.com/wp-content/uploads/2018/06/face_recognition_opencv_dataset.jpg) **Figure 3:** Our face recognition dataset consists of images of five people, each with five images per person. We will use OpenCV, Python, and deep learning for face recognition. 我们今天将使用的人脸识别数据集包含在本文的 ***【下载】*** 中。 在我们的人脸识别系统中,总共有五个人: * 杰瑞·宋飞 * 茱莉亚·路易斯-德雷福斯 * 杰森·亚历山大 * 迈克尔·理查兹 * 我自己,特伦斯·埃德金斯 每个人有五张照片。 这些图像是在不同的光线、不同的面部表情和不同的面部方向下拍摄的,使得一个更具挑战性的数据集。 ### 人脸识别项目结构 在我们开始之前,让我们看看我们的项目结构: ```py $ tree --filelimit 10 --dirsfirst . ├── dataset │   ├── jerry_seinfeld [5 entries] │   ├── julia_louis_dreyfus [5 entries] │   ├── michael_richards [5 entries] │   ├── terence_edkins [5 entries] │   └── jason_alexander [5 entries] ├── examples │   ├── example_01.png │   ├── example_02.png │   └── example_03.png ├── output │   └── lunch_scene_output.avi ├── videos │   └── lunch_scene.mp4 ├── search_bing_api.py ├── encode_faces.py ├── recognize_faces_image.py ├── recognize_faces_video.py ├── recognize_faces_video_file.py └── encodings.pickle 8 directories, 11 files ``` 我们的项目有 4 个顶级目录: * `dataset/`:包含五个人的图像,每人五张图片,如上所述。 * `examples/`:有三个测试图像,我们将使用它们来测试我们的人脸识别系统。 * `output/`:这里存储着处理过的视频(既然我们用的是电影文件,输出也会是电影文件)。 * `videos/`:输入视频文件存放在这里。该目录包含《宋飞正传》中的“午餐场景”。 还有五个 Python 文件: * `search_bing_api.py`:第一步是建立一个数据集。我们没有手动下载图像,而是使用微软的 Bing 搜索 API 来为我们建立数据集(详情见下一节)。这个脚本将帮助我们构建数据集。 * `encode_faces.py`:该脚本运行人脸编码,即构建人脸嵌入。 * `recognize_faces_image.py`:识别静态图像中的人脸。 * `recognize_faces_video.py`:识别实时视频流中的人脸。 * `recognize_faces_video_file.py`:识别视频文件中的人脸(`.mp4`、`.avi`等)。). 此外,还有一个名为`encodings.pickle`的文件。该文件是序列化的——人脸编码(128 维向量)通过`encode_faces.py`计算并写入磁盘。然后,我们的识别脚本可以读取编码,并执行实际的人脸识别。 在我们开始之前,让我们先构建我们的人脸识别数据集。 ### 创建您的人脸识别数据集 当处理人脸识别项目时,您首先需要创建一个包含您想要识别的人脸的数据集。 当然,我们可以手动下载图像,但是我个人更喜欢自动化这个过程。 为了自动构建我们的人脸识别数据集,我们将使用微软的 Bing 搜索 API(作为`face_recognition`库的一部分提供)。 ***注意:**微软现在要求使用 Bing 搜索 API 的必应认知服务账户。该帐户有免费层,允许您每月进行*数千次查询*,因此您仍然可以免费使用该服务。* 要开始使用 Bing 搜索 API,您需要登录微软 Azure 门户[https://portal.azure.com/](https://portal.azure.com/)(您可能需要创建一个帐户)。 从那里,创建一个新的**必应搜索 v7** 资源( **图 4** )。 创建资源后,您需要获取您的 API 密钥,如下所示(**图 5** )。 现在您已经有了 API 密钥,打开`search_bing_api.py`文件并插入您的 API 密钥(第 10 行): ```py # import the necessary packages from requests import exceptions import argparse import requests import cv2 import os # construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-q", "--query", required=True, help="search query to search Bing Image API for") ap.add_argument("-o", "--output", required=True, help="path to output directory of images") args = vars(ap.parse_args()) ``` 您还需要安装`requests`包(如果您还没有安装的话): ```py $ workon # optional $ pip install requests ``` 从那里,您可以运行`search_bing_api.py`脚本。这个脚本需要两个参数: 1. `--query`:您想要搜索的查询。您可能需要尝试多个查询来查找所需的结果。例如,当为“Jerry Seinfeld”搜索图像时,我最初尝试了“Jerry Seinfeld”的查询,但后来发现“Jerry Seinfeld face”产生了更好的结果。 2. `--output`:存储结果图像的输出目录的路径。该目录将被创建(如果它还不存在)。 例如,让我们为“Jerry Seinfeld face”创建一个数据集: ```py $ python search_bing_api.py --query "jerry seinfeld face" --output dataset/jerry_seinfeld ``` 然后为茱莉亚·路易-德雷福斯做同样的事情: ```py $ python search_bing_api.py --query "julia louis dreyfus face" --output dataset/julia_louis_dreyfus ``` 对其他三个人重复这个过程。 ***注意:*** *我建议你检查下载的图片,删除任何不相关的图片。例如,在 Julia Louis-Dreyfus 的搜索中,我不得不删除一张包含 Julia 和 Jerry Seinfeld 的照片,因为 Jerry 已经出现在数据集中了。* ### 对人脸识别数据集进行编码 [![](img/3b6d4d2a8d1d3b8d7e3d4b2d4a4d3a0c.png)](https://pyimagesearch.com/wp-content/uploads/2018/06/face_recognition_opencv_dataset.jpg) **Figure 6:** Our face recognition dataset is built. We will now compute the 128-d face embeddings for each face using a deep learning feature extractor. 现在我们的人脸识别数据集已经建立,我们需要将数据集中的每张脸编码成 128 维向量。 但是在我们开始编码之前,先打开`encode_faces.py`文件,让我们检查一下: ```py # import the necessary packages import face_recognition import argparse import pickle import cv2 import os # construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--dataset", required=True, help="path to input directory of faces + images") ap.add_argument("-e", "--encodings", required=True, help="path to serialized db of facial encodings") ap.add_argument("-d", "--detection-method", type=str, default="cnn", help="face detection model to use: either `hog` or `cnn`") args = vars(ap.parse_args()) ``` 在第 2-6 行,我们导入所需的包。注意,我们导入了`face_recognition`,这个库将为我们完成所有的人脸识别繁重工作。 然后,我们在第 9-16 行解析三个命令行参数: * `--dataset`:输入人脸图像数据集的路径。 * `--encodings`:输出序列化编码文件的路径。我们的脚本将计算这些编码,然后我们将它们写到磁盘上。 * `--detection-method`:在计算嵌入之前,我们首先需要检测图像中的人脸。两种人脸检测方法包括`hog`(方向梯度直方图)或`cnn`(卷积神经网络)。如果您有 GPU,请使用`cnn`方法,否则使用更快的`hog`方法。 现在我们已经定义了我们的参数,让我们抓取数据集中的图像路径: ```py # grab the paths to the input images in our dataset print("[INFO] quantifying faces...") imagePaths = list(paths.list_images(args["dataset"])) # initialize the list of known encodings and known names knownEncodings = [] knownNames = [] ``` 第 20 行使用我的 [imutils](https://github.com/jrosebr1/imutils) 包中的`paths`模块创建了`imagePaths`的列表。 然后我们初始化两个列表,`knownEncodings`和`knownNames`。这两个列表将包含数据集中每个人的面部编码和相应的姓名。 让我们开始循环`imagePaths`: ```py # loop over the image paths for (i, imagePath) in enumerate(imagePaths): # extract the person name from the image path print("[INFO] processing image {}/{}".format(i + 1, len(imagePaths))) name = imagePath.split(os.path.sep)[-2] # load the input image and convert it from BGR (OpenCV ordering) # to dlib ordering (RGB) image = cv2.imread(imagePath) rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) ``` 在第 27 行,我们开始循环每个`imagePath`。 然后,我们从`imagePath`中提取此人的`name`(第 31 行)。 接下来,我们加载`image`并将其转换为`rgb`颜色通道排序。 现在让我们定位人脸并计算编码: ```py # detect the (x, y)-coordinates of the bounding boxes # corresponding to each face in the input image boxes = face_recognition.face_locations(rgb, model=args["detection_method"]) # compute the facial embedding for the face encodings = face_recognition.face_encodings(rgb, boxes) # loop over the encodings for encoding in encodings

栏目列表