设为首页 - 加入收藏
广告 1000x90
您的当前位置:皮皮彩票app下载 > 测试生成 > 正文

史上最全 OpenCV 活体检测教程!

来源:未知 编辑:admin 时间:2019-04-19

  雷锋网 AI 科技评论按:本文来自著名的计算机视觉教学网站「pyimagesearch」,文章作者为

  雷锋网 AI 科技评论按:本文来自著名的计算机视觉教学网站「pyimagesearch」,文章作者为 Adrian Rosebrock。在本文中,Adrian 将就「如何鉴别图像/视频中的真实人脸和伪造人脸」这一问题进行深入的分析,并介绍使用基于 OpenCV 的模型进行活体检测的具体方法。雷锋网 AI 科技评论编译如下。雷锋网

  本教程将教授你如何使用 OpenCV 进行活性检测。通过学习,你将能够在人脸识别系统中创建一个可以发现伪造人脸并执行反人脸欺骗的活体检测器。

  然而,在我收到的一些邮件以及这些关于人脸识别的博文的评论中,我经常被问到的一个问题是:

  试想一下,如果一个居心叵测的用户有目的地试图骗过你的人脸识别系统,会发生什么?

  他们可能会尝试向执行人脸识别的摄像头展示一张照片或一段视频(例如在本文顶部的图像)。而这张照片和视频中的人并不是这些用户本人。

  在这种情况下,人脸识别系统完全有可能把展示到它们面前的图片识别为正确的人脸,这最终会导致未授权的用户躲过人脸识别系统!

  如何才能区分出这些「伪造的」与「真实的/合法的」人脸呢? 如何才能将反人脸欺骗算法应用到你的人脸识别应用中呢?

  那么,如何将基于 OpenCV 的活体检测功能结合到你自己的人脸识别系统中呢?本文接下来将给出答案。

  在本教程的第一部分,我们将对活体检测进行讨论,包括「活体检测是什么?」以及「为什么我们需要活体检测来改进人脸识别系统?」

  我们将训练一个能够区分真人脸和伪造人脸的深度神经网络,来创建活体检测器。

  2. 实现一个能够进行活体检测的卷积神经网络(我们称之为「LivenessNet」)

  4. 创建一个能够使用我们训练好的活体检测模型并将其应用于实时视频的 Python+OpenCV 的脚本

  图 1:基于 OpenCV 的活体检测。左图是一个我的活体(真人)的视频,而在右图中可以看到我正拿着我的 iPhone(屏幕上有伪造人脸/用来欺骗人脸识别系统的人脸图片)。

  人脸识别系统正变得越来越普及。从 iphone / 智能手机上的人脸识别系统,到中国用来进行大规模监控的人脸识别系统——人脸识别变得无处不在。

  通过将一个人的照片(无论是打印出来的,或者是显示在智能手机屏幕上的,等等)展示给用于人脸识别的摄像头,可以很容易地骗过人脸识别系统。

  为了使人脸识别系统变得更加安全,我们需要检测出这种伪造的/不真实的人脸——而「活体检测」就是被用来指代这种算法的术语。

  纹理分析,包括在人脸区域上计算局部二值模式(LBP,)和使用支持向量机(SVM)将人脸分类为真实的或伪造的。

  基于启发式的算法,包括眼球运动、嘴唇运动和眨眼检测()。这类算法试图跟踪眼球运动和眨眼,以确保用户展示的并非另一个人的照片(因为照片不会眨眼或移动嘴唇)。

  三维人脸形状,类似于苹果 iPhone 所使用的人脸识别系统,使人脸识别系统能够区分真实的人脸和打印出来 / 照片中的 / 图像中的另一个人的人脸。

  将上述方法结合起来,使人脸识别系统工程师能够选择适合其特定应用程序的活体检测模型。

  图 2:一个收集到的真实人脸和伪造/欺骗性人脸的例子。左边的视频是一个我的人脸的合法录像。右边是我的笔记本电脑将左边的这段视频录下来的视频。

  为了简化我们的例子,我们在本文中构建的活体检测器将重点关注区分屏幕上的真实人脸和欺骗性的人脸。

  该算法可以很被容易地扩展到其他类型的欺骗性人脸中,包括打印机或高分辨率打印出来的人脸等。

  3. 将我的 iPhone 朝向我的桌面重放这个 25 秒的视频,我从桌面的角度录制了这段重放的视频;

  4. 这会产生两个示例视频。一个被用作「真实」人脸,另一个被用作「伪造/欺骗性」人脸。

  5. 最终,我将人脸检测技术同时应用在了这两组视频上,以提取两类人脸各自的 ROI。

  你可以直接使用这些视频开始构建数据集,但是我建议你收集更多的数据,从而帮助提升你的活体检测器的鲁棒性和准确率。

  通过测试,我确认这个模型会偏向于检测出我自己的人脸——因为所有的模型都是使用我自己的视频训练的,因此这个模型依旧是有意义的。此外,由于我是白种人,我并不奢望该数据集被用于检测其它肤色的人脸时有同样出色的表现。

  理想情况下,你可以使用包含多个种族的人脸的数据来训练一个模型。如果读者想要获得更多关于改进活体检测模型的建议,请务必参考下面的「局限性和进一步工作」章节。

  在接下来的教程中,你将学习到如何利用我记录下来的数据集,并使用 OpenCV 和深度学习技术得到一个真正的活体检测器。

  在继续阅读的过程中,读者可以使用「下载」部分提供的链接获取代码、数据集以及活体检测模型,并解压存档。

  「videos/」:我提供了两个用来训练 LivenessNet 分类器的输入视频。

  现在,我们将仔细回顾三个 Python 脚本。在本文的最后,你可以在自己的数据和输入视频上运行这些脚本。按照在本教程中出现的顺序,这三个脚本依次是:

  1. 「gather_examples.py」:该脚本从输入的视频文件中抓取人脸的 ROI,并帮助我们创建一个深度学习人脸活体检测数据集。

  (2)liveness.model:我们用来训练人脸活体检测器的一系列 Keras 模型。

  (3)plot.png:训练历史示意图显示出了模型的准确率和损失曲线,我们可以根据它评估我们的模型(即过拟合 / 欠拟合)。

  3.「liveness_demo.py」:我们的演示脚本将启动你的网络摄像头拍下视频帧,来进行实时人脸活体检测。

  图 3:为了建立一个活体检测数据集,首先需要检测出视频中的人脸 ROI 区域

  现在我们可以回顾一下我们初始化的数据集和项目架构,让我们看看如何从输入的视频中提取真实和伪造的人脸图像。

  第 2-5 行引入了我们需要的安装包。除了内置的 Python 模块,该脚本仅仅需要用到 OpenCV 和 NumPy 。

  「--detector」:人脸检测器的路径。我们将使用 OpenCV 的深度学习人脸检测器()。为了方便读者使用,Caffe 模型可在本文的「下载」部分获得。

  「--confidence」:过滤弱人脸检测结果的最小概率。默认情况下,该值为 50%。

  「--skip」:我们不需要检测并存储每个图像,因为相邻的帧是相似的。相反我们会在两次人脸检测任务之间跳过 N 个帧。你可以使用此参数修改默认的 N 值(16)。

  第 23-26 行加载了 OpenCV 的深度学习人脸检测器(相关阅读:)。

  我们还在循环执行时,为读取到的帧数以及保存下来的帧数初始化了两个变量(第 31 和第 32 行)。

  这时,由于我们已经读取了一个帧,我们将增加「read」计数器的计数(第 48 行)。如果需要跳过这个特定的帧,我们将不做任何操作继续进入下一轮循环(第 48 和 49 行)。

  为了执行人脸检测,我们需要根据图像创建一个二进制大对象数据(blob)(第 53 和 54 行)。为了适应于 Caffe 人脸检测器,这个「blob」的宽、高为 300*300。稍后还需要对边界框进行放缩,因此在第 52 行中,我们会抓取到帧的维度。

  我们的脚本假设在视频的每一帧中只出现了一张人脸(第 62-65 行),这有助于防止假正例的产生。如果你正在处理包含多个面孔的视频,我建议你相应地调整逻辑。

  因此,第 65 行获取到了最高的人脸检测索引的概率。第 66 行使用该索引提取出检测的置信度(confidence)。

  第 71 行保证了我们的人脸检测 ROI 能够满足减少假正例所需要的最小阈值。

  在此基础上,我们提取出了人脸的 ROI 边界框「box」坐标以及相应的人脸 ROI 数值(第 74-76 行)。

  我们为人脸 ROI 生成了一个「路径+文件名」,并在第 79-81 行中将其写入了磁盘。在这里,我们可以增加「saved」人的数量。

  处理完成后,我们将在第 86 和 87 行中清空 OpenCV 的工作内存。

  图 4:我们的 OpenCV 人脸活体检测数据集。我们将使用 Keras 和 OpenCV 训练一个活体检测模型的演示样例。

  请确保你使用了本教程「下载」部分的链接获取到了源代码以及输入视频的示例。

  在此基础上,请打开一个终端并执行下面的命令,从而提取出我们的「伪造/欺骗性」的类别所需要的人脸图像:

  由于「真实」的人脸视频比「伪造」的人脸视频文件要更长一些,我们将使用更长的跳帧值来平衡每一类输出的人脸 ROI 的数量。

  图 5:LivenessNet 的深度学习架构,这是一个被设计用来在图像和视频中检测出活体人脸的卷积神经网络(CNN)。

  接下来,我们将实现基于深度学习技术的活体检测器「LivenessNet」。

  出于以下两点原因,我们将刻意让该网络保持尽可能浅的层数和尽可能少的参数:

  2. 为了确保我们的活体检测器能够快速、实时运行(即使在诸如树莓派等计算资源受限的设备上)。

  现在,我们将开始实现「LivenessNet」,请打开「livenessnet.py」文件并插入下列代码:

  我们在第 12 行开始定义「LivenessNet」类。它包含一个静态的构造方法「build」(第 14 行)。「build」方法将接受四个输入参数:

  「depth」:图像的通道数(由于我们将使用 RGB 图像,本例中 depth 为 3)。

  「classes」:检测类别的数目。我们共有两类输出人脸:「真实」人脸和「伪造」人脸。

  第 18 行定义了模型的「inputShape」,而第 23-25 行指定了通道的顺序。

  我们的卷积神经网路表现出了 VGGNet 的一些特性。它非常浅,只有少许几个学习到的卷积核。理想情况下,我们并不需要用通过一个深度网络来区分真实人脸和伪造人脸。

  第 49-57 行由全连接层和 ReLU 激活函数层以及一个 softmax 分类器的头组成。

  图 6:训练 LivenessNet 的处理流程。同时使用「真实」人脸和「欺骗性/伪造」人脸图像作为我们的数据集,我们可以使用 OpenCV、Keras 框架以及深度学习技术训练一个活体检测模型。

  给定我们的真实/欺骗性人脸图像数据集以及对 LivenessNet 实现,我们现在已经做好了训练该网络的准备:

  我们的人脸活体检测脚本引入了大量的输入(第 2-19 行)。它们分别是:

  「LivenessNet」:我们在前面的章节定义过的活体检测卷积神经网络。

  「ImageDataGenerator」:用于进行数据增强,向我们提供批量的随机突变增强的图像。

  「Adam」:一个非常适用于该模型的优化器(可选方案包括随机梯度下降算法(SGD)、RMSprop 等)。

  「paths」:从我的「imutils」包中引入,该模块可以帮助我们收集磁盘上所有图像文件的路径。

  「numpy」:一个用于 Python 的数字处理开发库,它也是 OpenCV 的所需要的。

  「os」:该模块有很多功能,但在这里我们仅使用它来创建操作系统路径分隔符。

  输入似乎有点多,但是在了解这些输入的目的后,检查脚本的其余部分就应该更加直观了。

  「--model」:我们的脚本会生成一个输出模型文件,通过该参数指定其路径。

  「--plot」:训练脚本将生成一个训练过程示意图。如果你想重写「plot.png」的缺省值,你应该在命令行中指定该值。

  在第 35-37 行设置的训练参数包括学习率、批处理规模以及迭代的次数。

  到这里,我们就获取到了「iamgePaths」中的路径,同时也初始化了两个用来存放「data」和类「labels」的列表(第 42-44 行)。

  第 46-55 行的循环创建好了「data」和「labels」列表。「data」列表由我们加载并重新调整尺寸到 32*32 像素的图像组成。而每张图像则都有一个对应的标签被存储在「labels」列表中。

  每个像素的亮度都被放缩到了 [0,1] 区间内,我们在第 59 行将列表转换成了 NumPy array 的形式。

  我们使用 scikit-learn 对数据进行划分——将 75% 的数据用来做训练,其余 25% 的数据则被留作测试之用(第 69 和 70 行)。

  接下来,我们将初始化我们的数据增强对象,并编译、训练我们的人脸活体检测模型:

  第 73-75 行构造了一个数据增强对象,它将通过随机的旋转,缩放、平移、剪切和翻转生成新的图像。想要了解更多关于数据增强的知识,请参阅下面这篇博文:

  接着,我们在第 87-89 行开始训练模型。由于我们使用了浅层网络和小型数据集,这个过程相对会比较快。

  第 93 行给出了在测试集上得到的预测结果。以此为基础,生成了分类结果报告「classification_report」并显示在终端中(第 94 和 95 行)。

  「LivenessNet」模型和标签编码器在第 99-104 行被序列化并写入磁盘。

  请确保你通过本教程「下载」部分的链接下载了源代码和数据集。接着,请执行下面你的命令:

  图 6:使用 OpenCV、Keras 以及深度学习技术训练一个人脸活体检测模型的训练过程示意图。

  「img_to_array」:令我们的视频帧存储在一个兼容的数组格式中。

  「--detector」:用于计算出人脸 ROI 的 OpenCV 的深度学习人脸检测器的路径。

  接下来,我们将初始化人脸检测器、LivenessNet 模型 + 标签编码器,以及我们的视频流:

  在此基础上,我们加载了序列化、预训练的 LivenessNet 模型以及标签编码器(第 34-35 行)。

  在第 39 和 40 行中,我们的「VideoStream」对象被实例化,并且允许摄像头预热 2 秒。

  至此,是时候开始循环输入视频帧来检测「真实」人脸和「伪造/欺骗性」人脸了:

  第 43 行开启了一个无限的「while」循环代码块,我们首先读取某一帧然后对其进行放缩(第46 和 47 行)。

  使用 OpenCV 的「blobFromImage」函数()生成一个「blob」(第 51 行和 52 行),然后让其通过人脸检测网络,完成推理过程(第 56 和 57 行)。

  现在,让我们进入有趣的部分——使用 OpenCV 和深度学习进行活体检测。

  抽取出人脸边界「box」的坐标,并确保它们不会超出检测框的尺寸范围(第 69-77 行)。

  抽取出人脸 ROI,并使用训练数据所采取的同样方式对其进行预处理。(第 81-85 行)

  使用活体检测模型来判别输入的人脸是「真实的」还是「伪造/欺骗性」的(第 89-91 行)。

  在第 91 行中,你可以插入自己的代码执行人脸识别任务,但是只能在真实图像上进行。伪代码与「if label == real: run_face_reconition()」类似,可以直接添加到第 91 行之后。

  最后(在这个演示样例中),我们会绘制出「label」文本和一个包围人脸的「rectangle」(第 94-98 行)。

  当捕获到键盘按键时,循环过程中的每一轮迭代都会显示出输出帧(第 101-102 行)。只要用户按下「q」(quit)键,检测器就停止循环、开启指示器并关闭窗口(第 105-110 行)。

  如果读者想跟着我们的活体检测演示完成整个执行过程,请确保你已经通过本文「下载」部分的链接下载到了源代码和预训练好的活体检测模型。

  在这里,你可以看到我们的活体检测器成功地将真实人脸和伪造人脸区分了开来。

  我们的活性检测器的主要限制实际上是数据集比较有限——总共只有 311 张图像(包含「线 张图像和「伪造」类的 150 张图像)。

  这项工作的一项扩展,就是收集额外的训练数据,更具体地说,可以收集来自于你、我之外的人的图像/视频帧数据。

  请记住,这里使用的示例数据集只包含一个人(我自己)的人脸。我是白人/白种人,而你应该收集其他种族和肤色的人脸训练数据。

  我们的活体检测器只在屏幕上具有欺骗性攻击的人脸进行训练,而没有对打印出来的图像或照片进行训练。因此,我的第三个建议是,除了简单的屏幕录制回放之外,还要收集其它种类的图像/人脸资源。

  最好的活体检测器应该包含多种活体检测方法(请参阅上面的「什么是活体检测, 我们为什么需要它?」一节)。

  你需要花点时间来考虑和评估你自己的项目、指导方针和需求。在某些情况下,你可能只需要用到基本的眨眼检测启发方法。

  不要急于进行人脸识别和活体检测。你克制一下自己,花点时间考虑自己独特的项目需求。这样的话将确保你获得更好、更准确的结果。

  现在通过使用活体检测器,你就可以检测出伪造的人脸,并在你自己的人脸识别系统中执行反人脸欺骗过程。

  在活体检测器的创建过程中,我们用到了 OpenCV、深度学习技术以及 Python 语言。

  首先,我们需要收集自己的「真实 vs 伪造」人脸数据集。为了完成该任务,我们要做到:

  3. 将人脸检测技术同时应用到上面两个视频集合中,以构建最终的活体检测数据集。

  在构建好数据集后,我们实现了「LivenessNet」——它是一个用 Keras 和深度学习技术实现的卷积神经网络。

  为了演示完整的活体检测工作流程,我们创建了一个 Python + OpenCV 的脚本,该脚本加载了我们的活体检测程序并将其应用在了实时视频流上。

本文链接:http://thacba.net/ceshishengcheng/320.html

相关推荐:

网友评论:

栏目分类

现金彩票 联系QQ:24498872301 邮箱:24498872301@qq.com

Copyright © 2002-2011 DEDECMS. 现金彩票 版权所有 Power by DedeCms

Top