在接下来的几篇文章中,我们将训练计算机视觉+深度学习模型来进行面部识别。在此之前,我们首先需要收集脸部数据集。
如果你已经在使用预先准备好的数据集,比如Labeled Faces in the Wild(LFW),那么你可以省略这步。但对于大多数人来说,我们会想要识别不属于当前数据集的面部,如,识别自己,朋友,家人和同事等。
为了实现这一点,我们需要收集我们想要识别的人脸实例,然后以某种方式对其进行量化。这个过程通常被称为面部识别注册(facial recognition enrollment)。我们简称为“注册”。
本文将重点介绍注册流程的第一步:创建示例人脸的自定义数据集。
在下篇文章中,你将学习如何利用这个数据集的示例图像,量化人脸,并创建你自己的面部识别+ OpenCV应用。
如何创建自定义人脸识别数据集
在本教程中,我们将介绍三种创建面部识别自定义数据集的方法。
第一种方法将使用OpenCV和网络摄像头
(1)检测视频流中的脸部
(2)将示例脸部图像或者说帧保存到磁盘。
第二种方法将讨论如何以编程方式下载人脸图像。
最后,我们将讨论手动收集图像的方法,以及该方法何时适用。
让我们开始构建一个人脸识别数据集!
方法#1:通过OpenCV和网络摄像头进行面部注册
创建自己的自定义人脸识别数据集的第一种方法适用于以下情况:
你正在构建“现场”人脸识别系统
你需要对某个特定的人进行物理接触来收集他们脸部的示例图像
这样的系统对于公司,学校或其他需要每天出勤的组织来说是典型的。
为了收集这些人的脸部图像,我们可能会带他们到一个特殊的房间,在那里安装了一个摄像机(1)在视频流中检测他们脸部的(x,y)坐标,(2)将包含他们脸的帧写到磁盘中。
我们甚至可能会在数天或数周内执行此过程,以收集他们的脸部示例:
不同的照明条件
一天不同的时间
不同的情绪
…创建一个代表特定人脸的多样的图像数据集。
让我们写一个简单的Python脚本来帮助构建我们的自定义人脸识别数据集。这个Python脚本包括:
访问我们的摄像头
检测人脸
将包含脸部的帧写入磁盘
下载代码访问:https://www.pyimagesearch.com/2018/06/11/how-to-build-a-custom-face-recognition-dataset/
下载完成后,打开 build_face_dataset.py 并分步理解它:
# import the necessary packages
from imutils.video import VideoStream
import argparse
import imutils
import time
import cv2
import os
在 第2-7行,我们导入我们所需的软件包。值得注意的是,我们需要OpenCV和imutils 。
可以通过pip非常轻松地安装或升级 imutils:
pip install --upgrade imutils
如果你正在使用Python虚拟环境,请不要忘记使用workon命令!
现在你的环境已经建立,我们来讨论两个必需的命令行参数:
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--cascade", required=True,
help = "path to where the face cascade resides")
ap.add_argument("-o", "--output", required=True,
help="path to output directory")
args = vars(ap.parse_args())
命令行参数在运行时由一个名为argparse的包进行分析 (它包含在Python的安装中)。
我们有两个必需的命令行参数:
–cascade :磁盘上Haar cascade文件的路径。
–output:输出目录的路径。人脸图像存储在此目录中,我建议你以人名的名字命名这个目录。如果名字是“John Smith”,你可以将所有图像放入dataset/john_smith。
让我们加载我们的人脸Haar cascade并初始化我们的视频流:
# load OpenCV's Haar cascade for face detection from disk
detector = cv2.CascadeClassifier(args["cascade"])
# initialize the video stream, allow the camera sensor to warm up,
# and initialize the total number of example faces written to disk
# thus far
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
# vs = VideoStream(usePiCamera=True).start()
time.sleep(2.0)
total = 0
第二行,我们加载了OpenCV的Haar人脸检测器(detector)。detector将在逐帧循环环节工作。
我们在8行上实例化并启动我们的VideoStream。
注意: 如果你使用Raspberry Pi,请注释第8行,并取消注释第九行。
为了让我们的相机启动,我们需停顿两秒(第10行)。
我们还初始化一个total计数器,以表示存储在磁盘上的人脸图像的数量(第11行)。
现在让我们逐帧循环视频流:
# loop over the frames from the video stream
while True:
# grab the frame from the threaded video stream, clone it, (just
# in case we want to write it to disk), and then resize the frame
# so we can apply face detection faster
frame = vs.read()
orig = frame.copy()
frame = imutils.resize(frame, width=400)
# detect faces in the grayscale frame
rects = detector.detectMultiScale(
cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), scaleFactor=1.1,
minNeighbors=5, minSize=(30, 30))
# loop over the face detections and draw them on the frame
for (x, y, w, h) in rects:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
在 第2行,我们开始循环(按下“q”键时此循环退出)。
然后,我们获取一个frame,创建一个副本,并调整它(第6-8行)。
现在可以进行人脸检测了!
使用 detectMultiScale 方法,可以检测帧中的人脸 。该函数需要许多参数:
image:灰度图
scaleFactor :指定图像各个比例中缩小程度
minNeighbor :指定每个候选边界框矩形应该有多少个邻近框以保留有效检测的参数
minSize :最小可能的脸部图像大小
不幸的是,有时这种方法需要进行调整才能消除误报或检测脸部,但对于“近距离”脸部检测,这些参数就可以了。
我们的人脸检测方法的结果是列表rects(矩形边框)。在 第16行和第17行,我们遍历rects并在frame上绘制矩形以用于显示。
我们将在循环中采取的最后一步是(1)在屏幕上显示框架,和(2)处理按键响应:
# show the output frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the `k` key was pressed, write the *original* frame to disk
# so we can later process it and use it for face recognition
if key == ord("k"):
p = os.path.sep.join([args["output"], "{}.png".format(
str(total).zfill(5))])
cv2.imwrite(p, orig)
total += 1
# if the `q` key was pressed, break from the loop
elif key == ord("q"):
break
在第2行,我们将框架显示在屏幕上,然后在第3行捕获按键。
根据是否按下“k”或“q”键,我们将:
将frame保存到磁盘(7-10行)。我们还添加了我们捕获的总帧数(total,第11行)。对于我们希望“保留”的每一帧,必须按下“k”键 。我建议你脸部的帧数有不同的角度,区域,带或者不带眼镜等。
退出循环并准备退出脚本(quit)。
如果没有按键被按下,我们从循环的顶部开始, 从流中抓取一个frame。
最后,我们将打印存储在终端中的图像数量并进行清理:
# print the total faces saved and do a bit of cleanup
print(“[INFO] {} face images stored”.format(total))
print(“[INFO] cleaning up…”)
cv2.destroyAllWindows()
vs.stop()
现在让我们运行脚本并收集面孔!
在你的终端执行以下命令:
$ python build_face_dataset.py --cascade haarcascade_frontalface_default.xml \
--output dataset/adrian
[INFO] starting video stream...
[INFO] 6 face images stored
[INFO] cleaning up...
在我们退出脚本后,我们会注意到6个图像已经保存到dataset的adrian子目录中:
$ ls dataset/adrian
00000.png00002.png00004.png
00001.png00003.png00005.png
我建议将面部人脸图像存储在与这个人名对应的子目录中。
完成此过程之后,你就成功建立了的自定义人脸识别数据集。
方法#2:以编程方式下载人脸图像
如果你无法物理访问目标人群或者他们是公众人物,则可以通过API在不同的平台上以编程方式下载其脸部的示例图像。
在这里选择的API取决于你想收集示例人脸图像的人。
举个例子,如果这人一直在Twitter或Instagram上发帖,则可能需要利用他们的社交媒体API中的一个来获取图像。
或者你可以利用搜索引擎,例如Google或Bing:
Google:https://www.pyimagesearch.com/2017/12/04/how-to-create-a-deep-learning-dataset-using-google-images/
bing(推荐):https://www.pyimagesearch.com/2018/04/09/how-to-quickly-build-a-deep-learning-image-dataset/
中文:http://www.atyun.com/18403.html
使用后一种方法,我能够从侏罗纪公园和侏罗纪世界的演员中下载218个示例脸部图像。
下面是通过Bing Image Search API为人物欧文·格雷迪(Owen Grady)下载人脸图像的示例命令:
$ mkdir dataset/owen_grady
$ python search_bing_api.py --query "owen grady" --output dataset/owen_grady
现在我们来看看整个数据集(删除不包含角色脸部的图像之后):
$ tree jp_dataset --filelimit 10
jp_dataset
├── alan_grant [22 entries]
├── claire_dearing [53 entries]
├── ellie_sattler [31 entries]
├── ian_malcolm [41 entries]
├── john_hammond [36 entries]
└── owen_grady [35 entries]
6 directories, 0 files
在短短20多分钟内(包括除错的时间),我就收集到了我的《侏罗纪公园》/《侏罗纪世界》的人脸数据集:
方法#3:手动收集人脸图像
创建自己的自定义人脸识别数据集的最后一种也是最不理想的一种方法,手动查找并保存示例人脸图像。
这种方法显然很无聊,需要最多的工作时间 – 通常我们更喜欢自动化的解决方案,但在某些情况下,你可能需要手动。
使用这种方法,你需要手动检查:
搜索引擎结果
社交媒体资料
照片分享服务
…然后手动将这些图像保存到磁盘。
总结
在这篇文章中,我们简要介绍了三种创建面部识别自定义数据集的方法。
你选择哪种方法完全取决于你自己的面部识别应用。