作者|Jordan Van Eetveldt
编译|Flin
来源|towardsdatascience
你在互联网上找到的大多数人脸识别算法和研究论文都遭受照片攻击。这些方法在检测和识别来自网络摄像头的图像、视频和视频流中的人脸方面非常有效。然而,他们无法区分现实生活中的面孔和照片上的面孔。这种无法识别人脸的现象是由于这些算法在二维帧上工作。
现在让我们想象一下我们想要实现一个人脸识别开门器。该系统可以很好地区分已知面孔和未知面孔,以便只有授权人员才能访问。尽管如此,一个心怀不轨的人只要出示授权人的照片。这个3D探测器,类似于苹果的FaceID,应运而生了。但如果我们没有3D探测器呢?
本文的目标是实现一种基于眨眼检测的人脸活体检测算法,以抵抗照片攻击。该算法通过网络摄像头实时工作,只有当人的名字闪烁时才会显示出来。通俗地说,程序运行如下:
在网络摄像头生成的每个帧中检测人脸。
对于每个检测到的脸,检测眼睛。
对于每个检测到的眼睛,检测眼睛是否睁开或关闭。
如果在某个时候检测到眼睛是睁开的,然后是闭着的,然后是睁开的,我们就断定此人已经眨了眼睛,并且程序显示了他的名字(如果是人脸识别开门器,我们将授权此人进入)。
对于人脸的检测和识别,你需要安装face_recognition库,它提供了非常有用的深度学习方法来查找和识别图像中的人脸。特别是,face_locations、face_encodings和compare_faces函数是最有用的3个函数。人脸定位方法可以用两种方法来检测人脸:方向梯度直方图(HoG)和卷积神经网络(CNN)。由于时间限制,选择了HoG方法。
face_encodings函数是一个预先训练的卷积神经网络,能够将图像编码成128个特征向量。这个嵌入向量应该表示足够的信息来区分两个不同的人。最后,compare_faces计算两个嵌入向量之间的距离。它将允许算法识别从摄像头帧中提取的人脸,并将其嵌入向量与我们数据集中所有编码的人脸进行比较。最近的向量应该对应于同一个人。
1. 已知人脸数据集编码
在我的例子中,算法能够识别我和奥巴马。我为每个人挑选了大约10张照片。下面是处理和编码已知人脸数据库的代码。
def process_and_encode(images):
known_encodings = []
known_names = []
print("[LOG] Encoding dataset ...")
for image_path in tqdm(images):
# 加载图片
image = cv2.imread(image_path)
# 将其从BGR转换为RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 检测图像中的脸并获取其位置(方框坐标)
boxes = face_recognition.face_locations(image, model='hog')
# 将人脸编码为128维嵌入向量
encoding = face_recognition.face_encodings(image, boxes)
# 人物名称是图像来源文件夹的名称
name = image_path.split(os.path.sep)[-2]
if len(encoding) > 0 :
known_encodings.ap