使用Python和OpenCV进行人脸识别
<|begin▁of▁sentence|># 使用 Python 和 OpenCV 进行人脸识别
> 原文:

在本教程中,您将学习如何使用 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** 可视化了锚点、正例和负例的概念:

**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
>>>
```
如果导入时没有错误,那么您就可以开始本教程的其余部分了。
### 人脸识别数据集
[](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 已经出现在数据集中了。*
### 对人脸识别数据集进行编码
[](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
最新文章
- 汽车与未来出行的革新之路
- 发动机温度过高需立即停车检查
- 自动驾驶技术发展:从传感器融合到车路协同的未来趋势
- 自动驾驶技术突破:激光雷达与5G-V2X引领未来出行变革
- 雾灯使用全指南:避免误区,安全行车18-30字
- 2023汽车产业三大变革:固态电池突破、自动驾驶升级、车联网生态崛起
- 宝马全新电动SUV续航里程突破600公里
- 传感器融合:智能汽车“最强大脑”的炼成与保障
- 安全驾驶指南:跟车距离、刹车系统与轮胎检查要点
- 自动刹车系统提升汽车安全性能
- 电动化与智能化双轮驱动:固态电池、激光雷达、AR-HUD引领汽车产业变革
- 智能驾驶与固态电池革新:未来汽车三大技术趋势解析
- 智能座舱与自动驾驶:车联网重塑未来出行新生态
- 汽车变速箱技术进化史:从手动到智能的全面解析
- 智能座舱与车路协同:未来出行的四大技术变革
- 混合动力汽车核心技术解析:动力系统、能量回收与电池管理
- 800V高压平台引领电动汽车技术革命:电池与电驱系统全面升级
- 冷却液保养与方向盘握法:行车安全的两大关键细节
- 新手必学:5大安全驾驶技巧与雨天夜间行车指南
- 车载摄像头实时监测车道偏离预警
