照片、视频中的人脸有时也能骗过一些不成熟的人脸识别系统,让人们对人脸解锁的安全性产生很大怀疑。在这篇 4 千多字的教程中,作者介绍了如何用 OpenCV 进行活体检测(liveness detection)。跟随作者给出的代码和讲解,你可以在人脸识别系统中创建一个活体检测器,用于检测伪造人脸并执行反人脸欺骗。
我在过去的一年里写了不少人脸识别的教程,包括:
- penCV 人脸识别
- 用 dlib、Python 和深度学习进行人脸识别
- 用树莓派实现人脸识别
- https://www.pyimagesearch.com/2018/09/24/opencv-face-recognition/
- https://www.pyimagesearch.com/2018/06/18/face-recognition-with-opencv-python-and-deep-learning/
- https://www.pyimagesearch.com/2018/06/25/raspberry-pi-face-recognition/
但在我的邮件和人脸识别相关帖子下面的评论中经常会出现以下问题:
我该如何识别真假人脸呢?
想想如果有坏人试图攻破你的人脸识别系统会发生什么?
这样的用户可能会拿到另一个人的照片。甚至可能他们的手机上就有其他人的照片或视频,他们可以用这样的照片或视频来欺骗识别人脸的相机(就像本文开头的图片那样)。
在这种情况下,照相机完全有可能将其识别为正确的人脸,从而让未经授权的用户骗过人脸识别系统!
如何识别这些真假人脸呢?如何在人脸识别应用中使用反人脸欺骗算法?
答案是用 OpenCV 实现活体检测——这也是我今天要介绍的内容。
要了解如何用 OpenCV 将活体检测结合到你自己的人脸识别系统中,请继续往下读。
你可以在文末的下载部分下载源代码:
https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv/#
用 OpenCV 实现活体检测
本教程第一部分将讨论什么是活体检测以及为什么要借助活体检测提升我们的人脸识别系统。
从这里开始要先研究一下用于活体检测的数据集,包括:
- 如何构建活体检测的数据集?
- 真假面部图像的样例。
我们还将回顾用于活体检测器项目的项目结构。
为了创建活体检测器,我们要训练一个能分辨真假人脸的深度神经网络。
因此,我们还需要:
- 构建图像数据集;
- 实现可以执行活体检测的 CNN(我们将这个网络称为「LivenessNet」);
- 训练活体检测器网络;
- 创建一个 Python+OpenCV 的脚本,可以通过该脚本使用我们训练好的活体检测器模型,并将其应用于实时视频。
那我们就开始吧!
什么是活体检测?我们为什么需要活体检测?
图 1:用 OpenCV 进行活体检测。左图是我的实时(真实)视频,而右图中我拿着自己的 iPhone(欺骗)。
人脸识别系统与以往任何时候相比都更加普遍。从 iPhone(智能手机)中的人脸识别,到中国大规模监控中的人脸识别,人脸识别系统的应用无处不在。
但人脸识别系统也很容易被「伪造」和「不真实」的面部所欺骗。
在面部识别相机前拿着一个人的照片(无论是印出来的还是手机上的)可以轻而易举地骗过人脸识别系统。
为了让人脸识别系统更加安全,我们需要检测出这样伪造的面部——活体检测(术语)指的就是这样的算法。
活体检测的方法有很多,包括:
- 纹理分析(Texture analysis),该方法计算了面部区域的局部二值模式(Local Binary Patterns,LBP),用 SVM 将面部分为真实面部和伪造面部;
- 频率分析(Frequency analysis),比如检查面部的傅立叶域;
- 可变聚焦分析(Variable focusing analysis),例如检查连续两帧间像素值的变化;
- 启发式算法(Heuristic-Based algorithms),包括眼球运动、嘴唇运动和眨眼检测。这些算法试图追踪眼球运动和眨眼行为,来确保用户不是拿着谁的照片(因为照片不会眨眼也不会动嘴唇);
- 光流算法(Optical Flow algorithm),即检测 3D 对象和 2D 平面产生的光流的属性和差异;
- 3D 面部形状(3D face shape),类似于 iPhone 上的面部识别系统,这种算法可以让面部识别系统区分真实面部和其他人的照片或打印出来的图像;
结合以上算法,这种方法可以让面部识别系统工程师挑选适用于自己应用的活体检测模型。
Chakraborty 和 Das 2014 年的论文(《An Overview of Face liveness Detection》)对活体检测算法做了全面的综述。
我们在本教程中将活体检测视为一个二分类问题。
给定输入图像,我们要训练一个能区分真实面部和伪造面部的卷积神经网络(Convolutional Neural Network)。
但在训练活体检测模型之前,我们要先检查一下数据集。
我们的活体检测视频
图 2:真实面部和伪造面部的样例。左边的视频是我的面部的真实视频,右边是在播放同样的视频时笔记本录制的视频。
为了让例子更直观,本文建立的活体检测器侧重于区分真实面部和屏幕上的伪造面部。
这一算法可以轻易扩展到其他类型的伪造面部上,比如打印输出的伪造面部和高分辨率输出的伪造面部等。
为了建立活体检测数据集,我做了下列工作:
- 拿着我的 iPhone,将它设置为人像或自拍模式;
- 录制约 25 秒我在办公室里来回走的视频;
- 重播这段 25 秒的视频,这次用我的 iPhone 对着录制了重播视频的电脑;
- 这样就产生了两段样例视频,一段用于「真实」面部,一段用于「伪造」面部;
- 最后,我在这两段视频上都用了人脸检测,为这两类提取出单独的面部 ROI(Reign of Interest)。
我在本文的「下载」部分提供了真实面部和伪造面部的视频文件