活体检测 使用OpenCV进行 运动检测

原文链接 活体检测 使用OpenCV进行 运动检测

在 2019年7月19日 上张贴 由 hotdog发表回复

活体检测 使用OpenCV进行 运动检测


在本教程中,您将学习如何使用OpenCV执行 活体检测。您将创建一个能够在面部识别系统中发现假面并执行反面部欺骗的 活体检测 器。
在过去的一年中,我撰写了许多人脸识别教程,包括:

但是,我通过电子邮件和面部识别帖子的评论部分提出的一个常见问题是:
我如何发现真假面孔?
考虑如果一个邪恶的用户试图故意绕过你的人脸识别系统会发生什么。
这样的用户可能试图拿起另一个人的照片。也许他们甚至在他们的智能手机上有一张照片或视频,他们可以拿起负责进行人脸识别的相机(例如在本文顶部的图像中)。
在这些情况下,完全有可能正确识别照相机的脸部……但最终会导致未经授权的用户绕过您的人脸识别系统!
你会如何发现这些“假”与“真实/合法”的面孔?你怎么能在你的面部识别应用程序中应用反面部欺骗算法?
答案是使用OpenCV 应用 活动检测 ,这正是我今天要介绍的内容。
要了解如何将OpenCV的活体检测结合到您自己的人脸识别系统中,请继续阅读!
寻找这篇文章的源代码?
跳到下载部分。
使用OpenCV进行 活动检测
在本教程的第一部分中,我们将讨论实时检测,包括它是什么以及为什么我们需要它来改进我们的面部识别系统。
从那里我们将审查我们将用于执行活动检测的数据集,包括:

  • 如何构建数据集以进行活动检测
  • 我们的示例真实与假面部图像

我们还将审查我们的活体探测器项目的项目结构。
为了创建活体检测器,我们将训练一个能够区分真实面部和假面部的深度神经网络。
因此,我们需要:

  1. 构建图像数据集本身。
  2. 实现能够执行活跃度检测器的CNN(我们称之为“LivenessNet”网络)。
  3. 训练活体探测器网络。
  4. 创建一个Python + OpenCV脚本,能够采用我们训练有素的实时检测器模型并将其应用于实时视频。

让我们继续吧!
什么是活体检测,为什么需要它?

活体检测 使用OpenCV进行 运动检测


人脸识别系统正变得比以往任何时候都更加普遍。从iPhone /智能手机上的人脸识别到中国大规模监控的人脸识别,人脸识别系统正在各地得到应用。
然而,面部识别系统很容易被“欺骗”和“非真实”面孔所欺骗。
仅通过将人的照片(无论是在智能手机上打印,等等)保持到面部识别相机,就可以规避面部识别系统。
为了使人脸识别系统更安全,我们需要能够检测到这样的假/非真实面部 – 活跃度检测是用于指代此类算法的术语。
有许多活体检测方法,包括:

  • 纹理分析,包括计算面部区域上的局部二进制模式(LBP)并使用SVM将面部分类为真实或欺骗。
  • 频率分析,例如检查面部的傅里叶域。
  • 可变聚焦分析,例如检查两个连续帧之间的像素值的变化。
  • 基于启发式的算法,包括眼球运动,嘴唇运动眨眼检测 这些算法试图跟踪眼睛运动和眨眼以确保用户没有拿起另一个人的照片(因为照片不会眨眼或移动它的嘴唇)。
  • 光流算法,即检查从3D对象和2D平面生成的光流的差异和属性。
  • 3D脸部形状,类似于Apple的iPhone脸部识别系统所使用的脸部形状,使脸部识别系统能够区分真人脸部和其他人的打印输出/照片/图像。
  • 上述的组合使得面部识别系统工程师能够挑选和选择适合于其特定应用的活体检测模型。

有关活体检测算法的完整评论可以在Chakraborty和Das的2014年论文“面部活体检测概述 ”中找到。。
出于今天教程的目的,我们将活体检测视为二元分类问题
给定一个输入图像,我们将训练一个卷积神经网络,能够区分真实面部伪造/欺骗面部
但在我们开始训练我们的活体检测模型之前,让我们首先检查一下我们的数据集。
我们的活动检测视频

为了让我们的例子简单明了,我们在这篇博客文章中构建的实时检测器将侧重于区分真实面部屏幕上的欺骗面部。
该算法可以很容易地扩展到其他类型的欺骗面,包括打印输出,高分辨率打印等。
为了构建活跃度检测数据集,我:

  1. 拿起我的iPhone并将其置于纵向/自拍模式。
  2. 录制了一段约25秒的自己在办公室里走来走去的视频
  3. 重播了同样的25秒视频,这次是我的iPhone面向我的桌面,我录制了视频重播。
  4. 这导致了两个示例视频,一个用于“真实”面部,另一个用于“假/欺骗”面部。
  5. 最后,我将面部检测应用于两组视频,以提取两个类的单个面部ROI。

我在下载”中为您提供了我的真假视频文件在帖子部分为。
您可以将这些视频用作数据集的起点,但我建议您收集更多数据,以帮助您的实时检测器更加健壮和准确。
通过测试,我确定模型略微偏向我自己的脸,这是有道理的,因为这是所有模型都经过训练。此外,由于我是白人/白人,我不希望这个相同的数据集与其他肤色一起工作。
理想情况下,你将培训与模型 的面孔的人,并包括面孔 多个民族。 请务必参考下面的 “限制和进一步工作”部分,了解有关改善实时检测模型的其他建议。
在本教程的其余部分中,您将学习如何获取我记录的数据集,并将其转换为具有OpenCV和深度学习的实际活动检测器。
项目结构
继续使用下载获取代码,数据集和活动模型 部分,然后解压缩存档。
导航到项目目录后,您会注意到以下结构

活体检测 使用OpenCV进行 运动检测

我们的项目中有四个主要目录:

  • dataset / :我们的数据集目录包含两类图像:
    • 在播放我的脸部视频时,我用相机瞄准我的屏幕拍摄的假像。
    • 我的真实图像从我的手机自拍视频中捕获。

 

  • face_detector / :由我们的预训练Caffe面部探测器组成, 用于定位面部ROI。
  • pyimagesearch / :这个模块包含我们的LivenessNet类。
  • videos / :我提供了两个用于培训LivenessNet分类器的输入视频。

今天我们将详细回顾三个Python脚本。在帖子结束时,您将能够在自己的数据上运行它们并输入视频源。按照本教程中的出现顺序,这三个脚本是:

  1. gather_examples .py :此脚本从输入视频文件中获取面对ROI,并帮助我们创建深度学习面部活动数据集。
  2. train_liveness .py :如文件名所示,此脚本将训练我们的LivenessNet分类器。我们将使用Keras和TensorFlow来训练模型。培训过程会产生一些文件:
  • le .pickle :我们的班级标签编码器。
  • liveness.model :我们的序列化Keras模型,可检测面部活力。
  • plot .png :训练历史图显示准确度和损失曲线,因此我们可以评估我们的模型(即过度/不足)。

 

  1. liveness_demo .py :我们的演示脚本将启动您的网络摄像头以抓取帧以实时进行面部活体检测。

从我们的训练(视频)数据集中检测和提取面部ROI

活体检测 使用OpenCV进行 运动检测


现在我们已经有机会审查我们的初始数据集和项目结构,让我们看看我们如何从输入视频中提取真实和假面部图像。
最终目标,如果此脚本将填充两个目录:

  1. dataset / fake /:包含假.mp4文件中的面部ROI
  2. dataset / real /:保存来自真实.mov文件的面部ROI 。

鉴于这些帧,我们稍后将在图像上训练基于深度学习的活动检测器。
打开 gather_examples .py

活体检测 使用OpenCV进行 运动检测

第2-5行导入我们所需的包。除了内置的Python模块之外,此脚本仅需要OpenCV和NumPy。
从那里 第8-19行 解析我们的命令行参数

  • – input :输入视频文件的路径。
  • – output :输出目录的路径,其中将存储每个裁剪的面。
  • – detector :人脸探测器的路径。我们将使用OpenCV的深度学习人脸检测器。为方便起见,此Caffe型号包含在今天的 下载中。
  • – confidence 置信度 :过滤弱脸检测的最小概率。默认情况下,此值为50%。
  • – skip :我们不需要检测和存储每个图像,因为相邻的帧会相似。相反,我们将在检测之间跳过 N帧。您可以使用此参数更改默认值16。

让我们继续加载面部检测器并初始化我们的视频流

活体检测 使用OpenCV进行 运动检测

第23-26行加载OpenCV的深度学习面部检测器
从那里我们在30行打开我们的视频流 。
我们还初始化了两个变量,用于读取的帧数以及循环执行时保存的帧数(第31和32行))。
让我们继续创建一个循环来处理帧

活体检测 使用OpenCV进行 运动检测

我们的 while 循环从第35行开始 。
从那里我们抓住并验证一个 框架 (第37-42行)。
此时,由于我们已经读取了一个 帧 ,我们将增加 读取 计数器(第48行)。如果我们正在跳过这个特定的框架,我们将继续进行无需进一步处理(第48和49行))。
让我们继续探测面孔

活体检测 使用OpenCV进行 运动检测

为了执行面部检测,我们需要从图像中创建一个斑点第53和54行)。这个 斑点 有300×300的宽度和高度,以适应我们的Caffe面部探测器。稍后需要缩放边界框,因此 第52行抓取框架尺寸。
线58和59 通过深度学习面部检测器执行斑点的 正向 通过 。
我们的脚本假设视频的每一帧只有一个面第62-65行)。这有助于防止误报。如果您正在处理包含多个脸部的视频,我建议您相应地调整逻辑。
因此, 第65行获得最高概率的面部检测指数。 第66行使用索引提取检测的置信度。
让我们过滤弱检测并将面部ROI写入磁盘

活体检测 使用OpenCV进行 运动检测

第71行确保我们的面部检测ROI满足最小阈值以减少误报。
从那里我们提取面部ROI边界 框 坐标并面对ROI本身(第74-76行))。
我们为面部ROI生成路径+文件名,并将其写入第79-81行的磁盘。此时,我们可以增加 保存的 面数。
处理完成后,我们将在第86和87行进行清理 。
构建我们的活动检测图像数据集

活体检测 使用OpenCV进行 运动检测

图4:我们的OpenCV面部活体检测数据集。我们将使用Keras和OpenCV来训练和演示实时模型。
现在我们已经实现了 gather_examples .py脚本,让我们把它付诸实践。
确保使用下载本教程部分来获取源代码和示例输入视频。
从那里,打开一个终端并执行以下命令来提取我们的“假/欺骗”类的面
$ python gather_examples.py --input videos/fake.mp4 --output dataset/fake \ --detector face_detector --skip 1同样,我们也可以为“真正的”类做同样的事
$ python gather_examples.py --input videos/real.mov --output dataset/real \ --detector face_detector --skip 4由于“真实”视频文件比“假”视频文件长,我们将使用更长的跳帧值来帮助平衡每个类的输出面ROI数。
执行脚本后,您应该具有以下图像计数:

  • 假: 150张图片
  • 真实: 161张图片
  • 总计: 311张图片

实施“LivenessNet”,我们的深度学习活力检测器

活体检测 使用OpenCV进行 运动检测

下一步是实施“LivenessNet”,这是我们基于深度学习的实时检测器。
在核心, LivenessNet 实际上只是一个简单的卷积神经网络。
我们将故意保持这个网络尽可能, 参数尽可能少,原因两个:

  1. 减少过度拟合我们的小数据集的可能性。
  2. 确保我们的活动检测器快速,能够实时运行(即使在资源受限的设备上,例如Raspberry Pi)。

让我们现在实现LivenessNet – 打开 livenessnet .py

活体检测 使用OpenCV进行 运动检测

我们所有的进口都来自Keras(2-10行)。要深入审查每个层和功能,请务必参考 使用Python进行计算机视觉的深度学习
我们的 LivenessNet 类在第12行定义 。它由一个静态方法 build (第14行)组成。该 构建 方法接受四个参数:

  • width :图像/体积的宽度。
  • height :图像的高度。
  • depth :图像的通道数(在本例中为3,因为我们将使用RGB图像)。
  • classes :类的数量。我们有两个类:“真实”和“虚假”。

我们的 模型 在第17行初始化 。
我们模型的 inputShape在第18行 定义, 而通道排序在第23-25行确定 
让我们开始为我们的CNN添加图层

活体检测 使用OpenCV进行 运动检测

我们的CNN展示了VGGNet特有的品质。只有少量学习过滤器,它非常浅。理想情况下,我们不需要深层网络来区分真实和欺骗的面孔。
第28-36行 指定了一个 CONV => RELU => CONV => RELU => POOL图层集 ,其中还添加了批量标准化和丢失。
另一个 CONV => RELU => CONV => RELU => POOL 图层集附加在 第39-46行
最后,我们将添加 FC => RELU 图层

活体检测 使用OpenCV进行 运动检测

49-57行由完全连接和ReLU**层组成,带有softmax分级头。
该模型返回到第60行的训练脚本 。
创建活体检测器培训脚本

活体检测 使用OpenCV进行 运动检测

鉴于我们的真实/欺骗图像数据集以及LivenessNet的实施,我们现在已准备好训练网络。
打开 train_liveness .py

活体检测 使用OpenCV进行 运动检测

我们的面部活体训练脚本包含许多进口(第2-19行)。我们现在回顾一下:

  • matplotlib :用于生成训练图。我们指定 “Agg” 后端,以便我们可以轻松地将我们的绘图保存到第3行的磁盘上 。
  • LivenessNet :我们在上一节中定义的CNN活跃度。
  • train_test_split :scikit-learn中的一个函数,用于构建用于训练和测试的数据拆分。
  • classification_report :同样来自scikit-learn,该工具将生成关于模型性能的简要统计报告。
  • ImageDataGenerator :用于执行数据扩充,为我们提供批量随机突变的图像。
  • Adam :一个适用于此模型的优化器。(替代方案包括SGD,RMSprop等)。
  • paths :从我的imutils包中,这个模块将帮助我们收集磁盘上所有图像文件的路径。
  • pyplot :用于生成一个很好的训练图。
  • numpy :Python的数字处理库。这也是OpenCV的要求。
  • argparse :用于处理命令行参数
  • pickle :用于将我们的标签编码器序列化为磁盘。
  • cv2 :我们的OpenCV绑定。
  • os :这个模块可以做很多事情,但我们只是将它用于它的操作系统路径分隔符。

现在您知道导入的内容,查看脚本的其余部分应该更直截了当。
此脚本接受四个命令行参数:

  • – dataset :输入数据集的路径。在帖子的前面,我们使用 gather_examples .py 脚本创建了数据集 。
  • – model :我们的脚本将生成一个输出模型文件 – 在这里你提供它的路径。
  • – le :还需要提供输出序列化标签编码器文件的路径。
  • – plot :训练脚本将生成一个图。如果要覆盖默认值 “plot.png” ,则应在命令行中指定此值。

下一个代码块将执行许多初始化并构建我们的数据

活体检测 使用OpenCV进行 运动检测

第35-37行上设置训练参数,包括初始学习率,批量大小和时期数 。
从那里,我们的 imagePaths 被抓住了。我们还初始化了两个列表来保存我们的 数据 和类标签 (第42-44行)。
第46-55行的循环 构建了我们的 数据 和 标签 列表。该 数据 由我们的被装载和大小调整为图像的32×32像素。每个图像都有一个存储在标签 列表中的相应标签 。
所有像素强度都缩放到范围 [0,1],而列表通过第59行被制作成NumPy数组 。
现在让我们对标签进行编码并对数据进行分区

活体检测 使用OpenCV进行 运动检测

第63-65行单热编码标签。
我们利用scikit-learn来划分数据 – 75%用于培训,25%用于测试(第69和70行)。
接下来,我们将初始化我们的数据扩充对象并编译+训练我们的面部活动模型

活体检测 使用OpenCV进行 运动检测

第73-75行构造了一个数据增强对象,它将生成具有随机旋转,缩放,移位,剪切和翻转的图像。要阅读有关数据扩充的更多信息,请阅读我以前的博文
我们的 LivenessNet 模型是在79-83线上构建和编译的 。
然后我们开始训练87-89号 线。考虑到我们的浅网络和小数据集,这个过程相对较快。
训练模型后,我们可以评估结果并生成训练图

活体检测 使用OpenCV进行 运动检测

预测在测试装置上进行(第93行)。从那里 生成classification_report并将其打印到终端(第94和95行)。
该 LivenessNet 模型与标签上的编码器一起被序列化到磁盘99-104行。
剩余的 第107-117行生成训练历史图以供以后检查。
训练我们的活力探测器
我们现在准备训练我们的活体探测器。
确保您已使用教程的下载部分下载源代码和数据集 – 从中​​执行以下命令
$ python train.py --dataset dataset --model liveness.model --le le.pickle

活体检测 使用OpenCV进行 运动检测

正如我们的结果所示,我们能够在验证集上获得99%的活跃度检测精度!
将各个部分组合在一起:使用OpenCV进行实时检测

活体检测 使用OpenCV进行 运动检测

图7:使用OpenCV和深度学习进行面部活跃度检测。
最后一步是将所有部分组合在一起:

  1. 我们将访问我们的网络摄像头/视频流
  2. 对每个帧应用面部检测
  3. 对于检测到的每个脸部,应用我们的活力检测器模型

打开 liveness_demo .py

活体检测 使用OpenCV进行 运动检测

第2-11行导入我们所需的包。值得注意的是,我们将使用

  • VideoStream 访问我们的相机Feed。
  • img_to_array 使我们的帧将采用兼容的数组格式。
  • load_model 加载我们的序列化 Keras模型。
  • imutils 为其便利功能。
  • cv2 用于我们的OpenCV绑定。

让我们通过第14-23行解析命令行参数 

  • – model :我们预先训练的Keras模型用于活体检测的路径。
  • – le :我们的标签编码器路径。
  • – detector 探测器 :OpenCV深度学习人脸探测器的路径,用于查找人脸ROI。
  • – confidence 置信度 :滤除弱检测的最小概率阈值。

现在让我们继续初始化人脸检测器,LivenessNet模型+标签编码器和我们的视频流

活体检测 使用OpenCV进行 运动检测

OpenCV人脸检测器通过27-30行加载 。
从那里我们加载我们的序列化,预训练模型( LivenessNet )和标签编码器(第34和35行)。
我们的 VideoStream 对象被实例化,我们的相机允许两秒钟预热(第39和40行)。
此时,是时候开始循环遍历帧以检测真实与虚假/欺骗的面部

活体检测 使用OpenCV进行 运动检测

线43将打开一个无限 循环块,其中我们开始通过拍摄+调整各个帧(线46和47)。
调整大小后,抓取框架的尺寸,以便稍后执行缩放(第50行)。
使用="https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/">OpenCV blobFromImage函数, 我们生成一个 blob (第51和52行),然后通过将其传递到面部检测器网络(第56和57行)继续进行推理。
现在我们已准备好迎接有趣的部分 – 使用OpenCV进行实时检测和深度学习

活体检测 使用OpenCV进行 运动检测

在 第60行,我们开始循环检测面部

  • 过滤掉弱检测(第63-66行))。
  • 提取面部边界 框 坐标并确保它们不会超出框架的尺寸(第69-77行)。
  • 提取面部ROI并以与我们的训练数据相同的方式对其进行预处理第81-85行)。
  • 使用我们的活动检测器模型来确定面部是“真实的”还是“假的/欺骗的” (第89-91行)。
  • 第91行是您插入自己的代码以执行人脸识别的地方, 但仅限于真实图像。伪代码类似于if = =“real”:run_face_reconition() 直接在第91行之后 )
  • 最后(对于本演示),我们绘制 标签 文本和 面部周围的矩形(第94-98行)。

让我们显示我们的结果并清理

活体检测 使用OpenCV进行 运动检测

在捕获按键的同时,在循环的每次迭代中显示输出帧(第101-102行)。每当用户按下“q”(“退出”)时,我们将跳出循环并释放指针并关闭窗口(第105-110行)。
将我们的活动检测器部署到实时视频
要关注我们的实时检测演示,请确保您已使用下载”博客文章部分下载源代码和预先训练的活动检测模型。
从那里,打开一个终端并执行以下命令
$ python liveness_demo.py --model liveness.model --le le.pickle \ --detector face_detector


在这里你可以看到我们的活体探测器成功地区分了真实和伪造的面孔。
限制,改进和进一步的工作
我们的活体检测器的主要限制实际上是我们有限的数据集 – 总共只有311个图像 (161个属于“真实”类,150个属于“假”类)。
这项工作的第一个扩展之一就是简单地收集额外的训练数据,更具体地说,是不仅仅是我或你自​​己的图像/帧
请记住,今天使用的示例数据集仅包含一个 人(我自己)的面孔 。我也是白人/白人 – 你应该为其他种族和肤色收集训练面孔 。
我们的活体探测器只是通过屏幕上的恶搞攻击进行训练- 它 没有经过打印的图像或照片的训练。因此,我的第三个建议是在简单的屏幕录制回放之外投入额外的图像/面部源
最后,我想提一下,活体检测没有完美的。
一些最好的活体检测器包含多种活体检测方法(请务必参考“什么是活体检测以及我们为什么需要它?”部分)。
花些时间考虑和评估您自己的项目,指南和要求 – 在某些情况下,您可能需要的只是基本的眨眼检测启发式方法。
在其他情况下,您需要将基于深度学习的活动检测与其他启发式检测相结合。
不要急于进行人脸识别和活体检测 – 花时间和纪律来考虑自己独特的项目要求。这样做可确保您获得 更好,更准确的 结果。
摘要
在本教程中,您学习了如何使用OpenCV执行活动检测。
使用此活体检测器,您现在可以在您自己的人脸识别系统中发现伪造的假货并进行反面部欺骗。
为了创建我们的活动检测器,我们使用了OpenCV,Deep Learning和Python。
第一步是收集我们的真假数据集。为完成此任务,我们:

  1. 首先使用我们的智能手机录制自己的视频(即“真实”面孔)。
  2. 将我们的智能手机放到我们的笔记本电脑/台式机上,重播相同的视频,然后使用我们的网络摄像头记录重播(即“假”面)。
  3. 对两组视频应用面部检测以形成我们的最终活动检测数据集。

在构建我们的数据集之后,我们实施了“LivenessNet”,一个Keras +深度学习CNN。
该网络故意浅为了确保:

  1. 我们减少了过度拟合小数据集的可能性。
  2. 该模型本身能够实时运行(包括在Raspberry Pi上)。

总的来说,我们的活性检测器能够在我们的验证集上获得99%的准确度
为了演示完整的活动检测管道,我们创建了一个Python + OpenCV脚本,它加载了我们的活动检测器并将其应用于实时视频流。
正如我们的演示所示,我们的活力检测器能够区分真假面部。
我希望你喜欢今天关于OpenCV活动检测的帖子。
代码下载
源代码下载


原文链接 活动检测 使用OpenCV进行 运动检测



文章转自 Adrian Rosebrock ,OpenCV Face Recognition,PyImageSearch,https://www.pyimagesearch.com/OpenCV OCR and text recognition with TesseractLiveness Detection with OpenCV/,2009年7月19日访问



相关文章

 

张贴在技术博客opencv标签:opencv深度学习活动检测运动检测编辑