首页 微博热点正文

雷锋网 AI 科技谈论按:本文来自闻名的核算机视觉教育网站「pyimagesearch」,文章作者为 Adrian Rosebrock。在本文中,Adrian 迁就「怎么辨别图画/视频中的实在人脸和假造人脸」这一问题进行深化的剖析,并介绍运用依据 OpenCV 的模型进行活体检测的具体办法。雷锋网 AI 科技谈论编译如下。雷锋网

本教程将教授你怎么运用 OpenCV 进行活性检测。经过学习,你将可以在人脸辨认系统中创立一个可以发现假造人脸并履行反人脸诈骗的活体检测器。

在曩昔一年中,本文作者现已写过了多篇人脸辨认教程,包含:

可是,在我收到的一些邮件以及这些关于人脸辨认的博文的谈论中,我经常被问到的一个问题是:

我怎么才干区别真人脸和假造人脸?

试想一下,假如一个别有用心的用户有意图地企图骗过你的人脸辨认系统,会发作什么?

他们或许会测验向履行人脸辨认的摄像头展现一张相片或一段视频(例如在本文顶部的图画)。而这张相片和视频中的人并不是这些用户自己。

在这种情况下,人脸辨认系统彻底有或许把展现到它们面前的图片辨认为正确的人脸,这终究会导致未授权的用户躲过人脸辨认系统!

怎么才干区别出这些「假造的」与「实在的/合法的」人脸呢? 怎么才干将反人脸诈骗算法运用到你的人脸辨认运用中呢?

答案是运用 OpenCV 进行活体检测,这正是本文要评论的内容。

那么,怎么将依据 OpenCV 的活体检50岁妇女测功用结合到你自己的人脸辨认系统中呢?本文接下来将给出答案。

依据 OpenCV 的活体检测

在本教程的榜首部分,咱们将对活体检测进行评论,包含「活体检测是什么?」以及「为什么咱们需求活体检测来改善人脸辨认系统?」

在这儿,咱们首要回忆一下接下来将用来进行活体检测的数据集,内容包含:

咱们还将回忆针对活体检测器项意图项目结构。

咱们将练习一个可以区别真人脸和假造人脸的深度神经网络,来创立活体检测器。

因而,咱们需求:

1. 构建图画数据集

2. 完结一个可以进行活体检测的卷积神经网络(咱们称之为「LivenessNet」)

3. 练习活体检测网络

4. 创立一个可以运用咱们练习好的活体检测模型并将其运用于实时视频的 Python+OpenCV 的脚本

接下来,让咱们进入正题吧!

什么是活体检测, 咱们为什么需求它?

图 1:依据 OpenCV 的活体检测。左图是一个我的活体(真人)的视频,而在右图中可以看到我正拿着我的 iPhone(屏幕上有假造人脸/用来诈骗人脸辨认系统的人脸图片)。

人脸辨认系统正变得越来越遍及。从 iphone / 智能手机上的人脸辨认系统,到我国用来进行大规划监控的人脸辨认系统——人脸辨认变得无处不在。

可是,人脸辨认系统却很简略被「具有诈骗性的」和「不实在」的人脸所捉弄。

经过将一个人的相片(无论是打印出来的,或者是显现在智能手机屏幕上的,等等)展现给用于人脸辨认的摄像头,可以很简略地骗过人脸辨认系统。

为了使人脸辨认系统变得愈加安全,咱们需求检测出这种假造的/不实在的人脸——而「活体检测」便是被用来指代这种算法的术语。

活体检测的办法有许多,包含:

在 Chakraborty 和 Das 于 2014 年宣布的论文「An Overview of Face liveness Detection」(论文阅览地址:)中,对活体检测算法进行了全面的回忆。

在本文的教程中,咱们将活体检测作为一个二分类问题来看待。

给定一张输入图画,咱们将练习一个可以辨认出真假人脸的卷积神经网络。

在开端练习咱们的活体检测模型前, 咱们先检查一下运用的数据集。

咱们的活体检测视频

图 2:一个搜集到的实在人脸和假造/诈骗性人脸的比如。左面的视频是一个我的人脸的合法录像。右边是我的笔记本电脑将左面的这段视频录下来的视频。

为了简化咱们的比如,咱们在本文中构建的活体检测器将要点重视区别屏幕上的实在人脸和诈骗性的人脸。

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

为了构建活体检测数据集,我将:

1夏凌兮. 运用我的 iPhone,把它调成人像 / 自拍方式。

2. 录制一段大约 25 秒的我自己在办公室内走来走去的视频。

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

4. 这会发生两个示例视频。一个被用作「实在」人脸,另一个被用作「假造/诈骗性」人脸。

5. 终究,我将人脸检测技能一起运用在了这两组视频上,以提取两类人脸各自的 ROI。

我在本文的「下载」部分为咱们供给了实在人脸视频和假造人脸视频。

你可以直接运用这些视频开端构建数据集,可是我主张你搜集更多的数据,然后协助提高你的活体检测器的鲁棒性和精确率。

经过测验,我承认这个模型会倾向于检测出我自己的人脸——因为一切的模型都是运用我自己的视频练习的,因而这个模型依旧是有意义的。此外,因为我是碧眼儿,我并不奢求该数据集被用于检测其它肤色的人脸时有相同超卓的体现。

抱负情况下,你可以运用包含多个种族的人脸的数据来练习一个模型。假如读者想要取得更多关于改善活体检测模型的主张,请必须参阅下面的「局限性和进一步作业」章节。

在接下来的教程中,你将学习到怎么运用我记录下来的数据集,并运用 OpenCV 和深度学习技能得到一个实在的活体检测器。

项目架构

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

当你导航到项意图目录时,你会留意到如下所示的架构:

$ tree --dirsfirst --filelimit 10

├石井优希── dataset

│ ├── fake [150 entries]

│ └── real [161 entries]

├── face_detector

│ ├── deploy.prototxt

│ └── res10_300x300_ssd_iter_140000.caffemodel

├── pyimagesearch

│ ├── __init__.py

│ └── livenessnet.py

├── videos

│ ├── fake.mp4

│ └── real.mov

├── gather_examples.py

├── train_liv逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌eness.py

├── liveness_demo.py

├── le.pickle

├── liveness.model

└── plot.png

6 directories, 12 files

在咱们的项目中有四个首要的目录:

(1)摄像头对着正在播映我的人脸视频的手机屏幕所拍下的假造图画。

(2)我用手机自拍的视频中的实在图画。

现在,咱们将细心回忆三个 Python 脚本。在本文的终究,你可以在自己的数据和输入视频上运转这些脚本。按照在本教程中呈现的次序,这三个脚本依次是:

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

2.「train_liveness.py」: 如文件名所示,该脚本将练习咱们的 LivenessNet 分类器。 咱们将运用 Keras 和 TensorFlow 来练习模型。练习的进程会发生以下几个文件:

(1)le.pickle:咱们的类标签编码器。

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

(3)plot.png:练习前史示意图显现出了模型的精确率和丢失曲线,咱们可以依据它评价咱们的模型(即过拟合 / 欠拟合)。

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

从咱们的练习(视频)数据会集检测并提取人脸的 ROI

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

现在咱们可以回忆一下咱们初始化的数据集和项目架构,让咱们看看怎么从输入的视频中提取实在和假造的人脸图画。

这个脚本的终究目标是向两个目录中填充数据:

1. 「dataset/fake/」:包含「fake.mp4」文件中的人脸 ROI 区域。

2. 「dataset/real/」:包含「real.mov」文件中的人脸 ROI 区域。

依据这些帧,咱们接下来将在图画上练习一个依据深度学习的活体检测器。

翻开「gather_examples.py」文件并刺进下列代码:

# import the necessary packages

import numpy as np

import argparse

import cv2

import os

# construct the argument parse and parse the arguments

ap = argparse.ArgumentParser

ap.add_argument("-i", "--input", type=str, required=True,

help="path to input video")

ap.add_argument("-o", "--output", type=str, required=True,

help="path to output directory of cropped faces")

ap.add_argument("-d", "--detector", type=str, required=True,

help="path to OpenCV's deep learning face detector")

ap.add_argument("-c", "--confidence", type=float, default=0.5,

help="minimum probability to filter一级黄 weak detections")

ap.add_argument("-s", "--skip", type=int, def逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌ault=16,

help="# of frames to skip before applying face detection")

args = vars(ap.parse_args)

第 2-5 行引进了咱们需求的安装包。除了内置的 Python 模块,该脚本只是需求用到 OpenCV 和 NumPy 。

第 8-19 行代码将解析咱们的指令行参数:

让咱们持续加载人脸检测器并初始化咱们的视频流:

# load our serialized face detector from disk

print("[INFO] loading face detector...")

protoPath = os.path.sep.join([args["detector"], "deploy.prototxt"])

modelPath = os.path.sep.join([args["detector"],

"res10_300x300_s逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌sd_iter_140000.caffemodel"])

net = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

# open a point血清康er to the video file stream and initialize the total

# number of frames read and saved thus far

vs = cv2.VideoCapture(args["input"])

read = 0

saved = 0

第 23-26 行加载了 OpenCV 的深度学习人脸检测器(相关阅览:https://www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/)。

之后,咱们在第 30 行翻开了咱们的视频流。

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

接下来,咱们将创立一个循环来处理这些帧:

# loop over frames from the video file stream

while True:

# grab the frame from the file

(grabbed, frame) = vs.read

# if the frame was not grabbed, then we have reached the end

# of the stream

if not grabbed:

break

# increment the total number of frames read thus far

read += 1

# check to see if we should process this frame

if read % args["skip"] != 0:

continue

咱们在第 35 行开端「while」循环。

接着,咱们抓取到了一个帧并对其进行验证(第 37-42 行)。

这时,因为咱们现已读取了一个帧,咱们将添加「read」计数器的计数(第 48 行)。假如需求越过这个特定的帧,咱们将不做任何操作持续进入下一轮循环(第 48 和 49 行)。

让咱们持续检测人脸:

# grab the frame dimensions and construct a blob from the frame

(h, w) = frame.shape[:2]

blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,

(300, 300), (104.0, 177.0, 123.0))

# pass the blob through the network and obtain the detections and

# predictions

net.setInput(blob)

detections = net.forward

# ensure at least one face was found

if len(detections) > 0:

# we're making the assumption that each image has only ONE

# face, so find the bounding box with the largest probability

i = np.argmax(detections[0, 0, :, 2])

confidence = detections[0, 0, i, 2]

为了履行人脸检测,咱们需求依据图画创立一个二进制大目标数据(blob)(第 53 和 54 行)。为了适应于 Caffe 人脸检测器,这个「blob」的宽、高为 300*300。稍后还需求对鸿沟框进行放缩,因而在第 52 行中,咱们会抓取到帧的维度。

第 58 和 59 行经过深度学习人脸检测器前馈传递这个「blob」。

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

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

接下来,让咱们过滤掉弱人脸检测成果并将人脸的 ROI 写入磁盘:

# ensure that the detection with the largest probability also

# means our minimum probability test (thus helping filter out

# weak detections)

if confidence > args["confidence"]:

# compute the (x, y)-coordinates of the bounding box for

# the face and extract the face ROI

box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])

(startX, startY, endX, endY) = box.astype("int")

face = frame[startY:endY, startX:endX]

# write the frame to disk

p = os.path.sep.join([args["output"],

"{}.png".format(saved)])

cv2.imwrite(p, face)

saved += 1

print("[INFO] saved {} to disk".format(p))

# do a bit of cleanup

vs.release

cv2.destroyAllWindows

第 71 行保证了咱们的人脸检测 ROI 可以满意削减假正例所需求的最小阈值。

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

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

处理完结后,咱们将在第 86 和 87 行中清空 OpenCV 的作业内存。

构建咱们的活体检测图片数据集

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

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

在此基础上,请翻开一个终端并履行下面的指令,然后提取出咱们的「假造/诈骗性」的类别所需求的人脸图画:

$ python gather_examples.py --input videos/real.mov --output dataset/real \

--detector face_detector --skip 1

[INFO] loading face detector...

[INFO] saved datasets/fake/0.png to disk

[INFO] saved datasets/fake/1.png to disk

[INFO] saved datasets/fake/2.png to disk

[INFO] saved datasets/fake/3.png to disk

[INFO] saved datasets/fake/4.png to disk

[INFO] saved datasets/fake/5.png to disk

...

[INFO] saved datasets/fake/145.png to disk

[INFO] saved datasets/fake/146.png to disk

[INFO] saved datasets/fake/147.png to disk

[INFO] saved datasets/fake/148.png to disk

[INFO] saved datasets/fake/149.png to disk

类似地,咱们可以为获取「实在」类别的人脸图画进行相同的操作:

$ python gather_examples.py --input videos/fake.mov --output dataset/fake \

--detector face_detector --skip 4

[INFO] loading face detector...

[INFO] saved datasets/real/0.png to disk

[INFO] saved datasets/real/1.png to disk

[INFO] saved datasets/real/2.png to disk

[INFO] saved datasets/real/3.png to disk

[INFO] saved datasets/real/4.png to disk

...

[INFO] saved datasets/real/156.png to disk

[INFO] saved datasets/real/157.png to disk

[INFO] saved datasets/real/158.png to disk

[INFO] saved datasets/real/159.png to disk

[INFO] saved datasets/real/160.豪门长媳17岁png to disk

因为「实在」的人脸视频比「假造」的人脸视频文件要更长一些,咱们将运用更长的跳帧值来平衡每一类输出的人脸 ROI 的数量。

在履行了上面的脚本后,你应该现已取得了如下所示的图画数据:

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

接下来,咱们将完结依据深度学习技能的活体检测器「LivenessNet」。

实质上,「LivenessNet」便是一个简略的卷积神经网络。

出于以下两点原因,咱们将故意让该网络坚持尽或许浅的层数和尽或许少的参数:

1. 为了下降在咱们的小型数据集上发作过拟合现象的或许性。

2. 为了保证咱们的活体检测器可以快速、实时运转(即便在比如树莓派等核算资源受限的设备上)。

现在,咱们将开端完结「LivenessNet」,请翻开「livenessnet.py」文件并刺进下列代码:

# import the necessary packages

from keras.models import Sequential

from keras.layers.normalization import BatchNormalization

from keras.layers.convolutional import Conv2D

from keras.layers.convolutional import MaxPooling2D

from keras.layers.core import Activation

from keras.layers.core import Flatten

from keras.layers.core import Dropout

from keras.layers.core import Dense

from keras import backend as K

class LivenessNet:

@staticmethod

def build(width, height, depth, classes):

# initialize the model along with the input shape to be

# "channels last" and the channels dimension itself

model = Sequential

inputShape = (height, width, depth)

chanDim = -1

# if we are using "channels first", update the input shape

# and channels dimension

if K.image_data_format == "channels_first":

inputShape = (depth, height, width)

chanDim = 1

咱们将从 Keras 包中引进一切需求的办法(第 2-10 行)。假如你想要进一步了解每一个网络层和函数,请参阅「 Deep Learning for Computer Vision with Python」(网址为:https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/)。

咱们在第 12 行开端界说「LivenessNet」类。它包含一个静态的结构办法「build」(第 14 行)。「build」办法将承受四个输入参数:

咱们在第 17 即将「model」初始化。

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

下面咱们将向卷积神经网络中参加一些网络层组件:

# first CONV => RELU => CONV => RELU => POOL layer set

model.add(Conv2D(16, (3, 3), padding="same",

input_shape=inputShape))

model.add(Activation("relu"))

model.add(BatchNormalization(axis=chanDim))

model.add(Conv2D(16, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(BatchNormalization(axis=chanDim))

model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Dropout(0.25))

# second CONV => RELU => CONV => RELU => POOL layer set

model.add(Conv2D(32, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(BatchNormalization(axis=chanDim))

model.add(Conv2D(32, (3, 3), padding="same"))

model.add(Activation("relu"))

model.add(BatchNormalization(axis=chanDim))

model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Dropout(0.25))

咱们的卷积神经网路体现出了 VGGNet 的一些特性。它十分浅,只需少量几个学习到的卷积核。抱负情况下,咱们并不需求用经过一个深度网络来区别实在人脸和假造人脸。

第 28-36 行指定了榜首个「CONV => RELU => CONV => RELU => POOL」(卷积层=> RELU 激活函数层=>卷积层=>RELU 激活函数层=>池化层)网络层调集,其间也参加了批量归一化层和 dropout 层。

第 39-46 行加上了另一个「CONV => RELU => CONV => RELU => POOL」(卷积层=>RELU 激活函数层=>卷积层=>RELU 激活函数层=>池化层)网络层调集。

终究参加咱们的「FC => RELU」(全衔接=>RELU 激活函数层)层:

# first (and only) set of FC => RELU layers

model.add(Flatten)

model.add(Dense(64))

model.add(Activation("relu"))

model.add(BatchNormalization)

model.add(Dropout(0.5))

# softmax classifier

model.add(Dense(classes))

model.add(Activation("softmax"))

# return the constructed network architecture

return model

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

在第 60 行中将该模型回来给练习脚本。

创立活体检测器的练习脚本

图 6:练习 LivenessNet 的处理流程。一起运用「实在」人脸和「诈骗性/假造」人脸图画作为咱们的数据集,咱们可以运用 OpenCV、Keras 结构以及深度学习技能练习一个活体检测模型。

给定咱们的实在/诈骗性人脸图画数据集以及对 LivenessNet 完结,咱们现在现已做好了练习该网络的预备:

请翻开「train_liveness.py」文件并刺进下列代码:

# set the matplotlib backend so figures can be saved in the background

import matplotlib

matplotlib.use("Agg")

# import the necessary packages

from pyimagesearch.livenessnet import LivenessNet

from sklearn.preprocessing import LabelEncoder

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from keras.preprocessing.image import ImageDataGenerator

from keras.optimizers import Adam

from keras.utils import np_utils

from imutils import paths

import matplotlib.pyplot as plt

import numpy as np

import argparse

import pickle

import cv2

import os

# construct the argument parser and parse the arguments

ap = argparse.ArgumentParser

ap.add_argument("-d", "--dataset", required=True,

help="path to input dataset")

ap.add_argument("-m", "--model", type=str, r火柴人逝世办公室equired=True,

help="path to trained model")

ap.add_argument("-l", "--le", type=str, required=True,

help="path to label encode逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌r")

ap.add_argument("-p", "--plot", type=str, default="plot.png",

help="path to output loss/accuracy plot")

args = vars(ap.parse_args)

咱们的人脸活体检测脚本引进了很多的输入(第 2-19 行)。它们分别是:

输入好像有点多,可是在了解这些输入的意图后,检查脚本的其他部分就应该愈加直观了。

该脚本承受四个指令行参数:

下面的代码块将履行一系列初始化作业,并创立咱们的数据:

# initialize the initial learning rate, batch size, and number of

# epochs to train for

INIT_LR = 1e-4

BS = 8

EPOCHS = 50

# grab the list of images in our dataset directory, then initialize

# the list of data (i.e., images) and class images

print("[INFO] loading images...")

imagePaths = list(paths.list_images(args["dataset"]))

data = []

labels = []

for imagePath in imagePaths:

# extract the class label from the filename, load the image and

# resize it to be a fixed 32x32 pixels, ignoring aspect ratio

label = imagePath.split(os.path.sep)[-2]

image = cv2.imread(imagePath)成慧琳

image = cv2.resize(image, (32, 32))

# update the data and labels lists, respectively

data.append(image)

labels.append(label)

# convert the data into a NumPy array, then preprocess it by scaling

# all pixel intensities to the range [0, 1]

data = np.array(data, dtype="float") / 255.0

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

到这儿,咱们就获取到了「iamgePaths」中的途径,一起也初始化了两个用来寄存「data」和类「labels」的列表(第 42-44 行)。

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

每个像素的亮度都被放缩练素梅到了 [0,1] 区间内,咱们在第 59 即将列表转化成了 NumPy array 的方式。

接下来,咱们将对标签进行编码并对数据进行区别:

# encode the labels (which are currently strings) as integers and then

# one-hot encode them

le = LabelEncoder

labels = le.fit_transform(labels)

labels = np_utils.to_categorical(labels, 2)

# partition the data into training and testing splits using 75% of

# the data for training and the remaining 25% for testing

(trainX, testX, trainY, testY) = train_test_split(data, labels,

test_size=0.25, random_state=42)

第 63-65 即将标签编码成了独热向量。

咱们运用 scikit-learn 对数据进行区别——将 75% 的数据用来做练习,其他 25% 的数据则被留作测验之用(第 69 和 70 行)。

接下来,咱们将初始化咱们的数据增强目标,并编译、练习咱们的人脸活体检测模型:

# construct the training image generator for data augmentation

aug = ImageDataGenerator(rotation_range=20, zoom_range=0.15,

width_shift_range=0.2, height_shift_range=0.2, shear_range=0.15,

horizontal_flip=True, fill_mode="nearest")

# initialize the optimizer and model

print("[INFO] compiling model...")

opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)

model = LivenessNet.build(width=32, height=32, depth=3,

classes=len(le.classes_))

model.compile(loss="binary_crossentropy", optimizer=opt,

metrics=["accuracy"])

# train the network

print("[INFO] training network for {} epochs...".format(EPOCHS))

H = model.fit_generator(aug.flow(trainX, trainY, batch_size=BS),

validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,

epochs=EPOCHS)

第 73-75 行结构鲤组词了一个数据增强目标,它将经过随机的旋转,缩放、平移、剪切和翻转生成新的图画。想要了解更多关于数据增强的常识,请参阅下面这篇博文:https://www.pyimagesearch.com/2018/12/24/how-to-use-keras-fit-and-fit_generator-a-hands-on-tutorial/

咱们在第 79-83 行构建并编译了「LivenessNet」模型。

接着,咱们在第 87-89 行开端练习模型。因为咱们运用了浅层网络和小型数据集,这个进程相对会比较快。

当模型练习完结后,咱们可以评价练习成果,并生成一个练习进程示意图:

# evaluate the network

print("[INFO] evaluating network...")

predictions = model.predict(testX, batch_size=BS)

print(classification_report(testY.argmax(axis=1),

predictions.argmax(axis=1), target_names=le.classes_))

# save the network to disk

print("[INFO] serializing network to '{}'...".format(args["model"]))

model.save(args["model"])

# save the label encoder to disk

f = open(args["le"], "wb")

f.write(pickle.dumps(le))

f.close

# plot the training loss and accuracy

plt.style.use("ggplot")

plt.figure

plt.plot(np.arange(0, EPOCHS), H.history["loss"], label="train_loss")

plt.plot(np萧靖彤.arange(0, EPOCHS), H.history["val_loss"], label="val_loss")

plt.plot(np.arange(0, EPOCHS), H.history["acc"], label="train_acc")

plt.plot(np.arange(0, EPOCHS), H.history["val_acc"], label="val_acc")

plt.title("Training Loss and Accuracy on Dataset")

plt.xlabel("Epoch #")

plt.ylabel(爱拍老曹"Loss/Accuracy")

plt.legend(loc="lower left")

plt.savefig(args["plot"])

第 93 行给出了在测验集上得到的猜测成果。以此为基础,生成了分类成果陈述「classification_report」并显现在终端中(第 94 和 9凶恶哥5 行)。

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

剩下的第 107-117 行生成了一钳花小包个练习进程示意图,以待检查。

练习咱们的活体检测器

现在,咱们现已为练习活体检测器做好了预备。

请保证你经过本教程「下载」部分的链接下载了源代码和数据集。接着,请履行下面你的指令:

$ python train.py --dataset dataset --model liveness.model --le le.pickle

[INFO] loading images...

[INFO] compiling model...

[INFO] training network for 50 epochs...

Epoch 1/50

29/29 [==============================] - 2s 58ms/step - loss: 1.0113 - acc: 0.5862 - val_loss: 0.4749 - val_acc: 0.7436

Epoch 2/50

29/29 [==============================] - 1s 21ms/step - loss: 0.9418 - acc: 0.6127 - val_loss: 0.4436 - val_acc: 0.7949

Epoch 3/50

29/29 [==============================] - 1s 21ms/step - loss: 0.8926 - acc: 0.6472 - val_loss: 0.3837 - val_acc: 0.8077

...

Epoch 48/50

29/29 [==============================] - 1s 21ms/step - loss: 0.2796 - acc: 0.9094 - val_loss: 0.0299 - val_acc: 1.0000

Epoch 49/50

29/29 [==============================] - 1s 21ms/step - loss: 0.3733 - acc: 0.8792 - val_loss: 0.0346 - val_acc: 0.9872

Epoch 50/50

29/29 [==============================] - 1s 21ms/step - loss: 0.2660 - acc: 0.9008 - val_loss: 0.0322 - val_acc: 0.9872

[INFO] evaluating network...

precision recall f1-score support

fake 0.97 还愿游戏1.00 0.99 35

real 1.00 0.98 0.99 43

micro avg 0.99 0.99 0.99 78

macro avg 0.99 0.99 0.99 78

weighted avg 0.99 0.99 0.99 78

[INFO] serializing network to 'liveness.model'...

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

如成果所示,咱们在验证集上完结 99% 的活体检测精确率。

整合一下:经过 OpenCV 完结活体检测

图 7:运用 OpenCV 和深度学习技能完结人脸活体检测

终究,咱们需求做的是将以上内容整合起来:

1. 衔接到咱们的网络摄像头/视频流

2. 将人脸检测运用到每一帧上

3. 对每一个检测到的人脸运用咱们的活体检测模型

请翻开「liveness_demo.py」文件并刺进下列代码:

# import the necessary packages

from imutils.video import VideoStream

from keras.preprocessing逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌.image import img_to_array

from keras.models import load_model

import numpy as np

import argparse

import imutils

import pickle

import time

import cv2

import os

# construct the argument parse 姜仁卿and parse the arguments

ap = argparse.ArgumentParser

ap.add_argument("-m", "--model", type=str, required=True,

help="path to trained model")

ap.add_argument("-l", "--le", type=str, required=True,

help="path to label encoder")

ap.add_argument包公出巡之神鬼传奇("-d", "--detector", type=str, required=True,

help="path to OpenCV's deep learning face detector")

ap.add_argument("-c", "--confidence", type=float, default=0.5,

help="minimum probability to filter weak detections")

args = vars(ap.parse_args)

第 2-11 行输入了咱们需求的安装包。 留意,咱们将运用:

在第 14-23 行中,咱们将解析指令行参数:

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

# load our serialized face detector from disk

print("[INFO] loading face detector...")

protoPath = os.path.sep.join([args["detector"], "deploy.prototxt"])

modelPath = os.path.sep.join([args["detector"],

"res10_300x300_ssd_iter_140000.caffemodel"])

net = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

# load the liveness detector model and label encoder from disk

print("[INFO] loading liveness detector...")

model = load_model(args["model"])

le = pickle.loads(open(args["le"], "rb").read)逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌

# initialize the video stream and allow the camera sensor to warmup

print("[INFO] starting video stream...")

vs = VideoStream(src=0).start

time.sleep(2.0)

在第 27-30 行加载 OpenCV 的人脸检测器。

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

在第 39 和 40 行中,咱们的「VideoStream」目标被实例化,而且答应摄像头预热 2 秒。

至此,是时分开端循环输入视频帧来检测「实在」人脸和「假造/诈骗性」人脸了:

# loop over the frames from the video stream

while True:

# grab the frame from the threaded video stream and resize it

# to have a maximum width of 600 pixels

frame = vs.read

frame = imutils.resize(frame, width=600)

# grab the frame dimensions and convert it to a blob

(h, w) = frame.shape[:2]

blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,

(300, 300), (104.0, 177.0, 123.0))

# pass the blob through the network and ob逆袭之爱上情敌,史上最全 OpenCV 活体检测教程!,文昌tain the detections and

# predictions

net.setInput(blob)

detections = net.forward

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

从头界说图画尺度后,获取帧的尺度,以便稍后履行缩放(第 50 行)。

运用 尉氏气候OpenCV 的「blobFromImage」函数(https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/)生成一个「blob」(第 51 行和 52 行),然后让其经过人脸检测网络,完结推理进程(第 56 和 57 行)。

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

# loop over the detections

for i in range(0, detections.shape[2]):

# extract the confidence (i.e., probability) associated with the

# prediction

confidence = detections[0, 0, i, 2]

# filter out weak detections

if confidence > args["confidence"]:

# compute the (x, y)-coordinates of the bounding box for

# the face and extract the face ROI

box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])

(startX, startY, endX, endY) = box.astype("int")

# ensure the detected bounding box does fall outside the

# dimensions of the frame

startX = max(0, startX)

startY = max(0, startY)

endX = min(w, endX)

endY = min(h, endY)

# extract the face ROI and then preproces it in the exact

# same manner as our training data

face = frame[startY:endY, startX:endX]

face = cv2.resize(face, (32, 32))

face = face.astype("float") / 255.0

face = img_to_array(face)

face = np.expand_dims(face, axis=0)

# pass the face ROI through the trained liveness detector

# model to determine if the face is "real" or "fake"

preds = model.predict(face)[0]

j = np.argmax(preds)

label = le.classes_[j]

# draw the label and bounding box on the frame

label = "{}: {:.4f}".format(label, preds[j])

cv2.putText(frame, label, (startX, startY - 10),

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

cv2.rectangle(frame, (startX, startY), (endX, endY),

(0, 0, 255), 2)

在第 60 行中,咱们开端循环进行人脸检测。在循环进程中,咱们做到了:

接下来,咱们将展现检测成果并整理内存:

# show the output frame and wait for a key press

cv2.imshow("Frame", frame)

key = cv2.waitKey(1) & 0xFF

# if the `q` key was pressed, break from the loop

if key == ord("q"):

break

# do a bit of cleanup

cv2.destroyAllWindows

vs.stop

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

将咱们的活体检测器运用到实时视频上

假如读者想跟着咱们的活体检测演示完结整个履行进程,请保证你现现已过本文「下载」部分的链接下载到了源代码和预练习好的活体检测模型。

接着,请翻开一个终端并履行下面的指令:

$ python liveness_demo.py --model liveness.model --le le.pickle \

--detector face_detector

Using TensorFlow backend.

[INFO] loading face detector...

[INFO] loading liveness detector...

[INFO] starting video stream...

在这儿,你可以看到咱们的活体检测器成功地将实在人脸和假造人脸区别了开来。

我鄙人面的视频汇中展现了一段更长的演示样例。

视频观看地址:https://youtu.be/MPedzm6uOMA

咱们的活性检测器的首要约束实际上是数据集比较有限——一共只需 311 张图画(包含「实在」类的 161 张图画和「假造」类的 150 张图画)。

这项作业的一项扩展,便是搜集额定的练习数据,更具体地说,可以搜集来自于你、我之外的人的图画/视频帧数据。

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

咱们的活体检测器只在屏幕上具有诈骗性进犯的人脸进行练习,而没有对打印出来的图画或相片进行练习。因而,我的第三个主张是,除了简略的屏幕录制回放之外,还要搜集其它品种的图画/人脸资源。

终究,我想说:想完结活体检测并没有什么捷径。

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

你需求花点时刻来考虑和评价你自己的项目、指导方针和需求。在某些情况下,你或许只需求用到根本的眨眼检测启示办法。

而在其他情况下,你需求将依据深度学习的活体检测与其它启示式办法相结合。

不要急于进行人脸辨认和活体检测。你抑制一下自己,花点时刻考虑自己共同的项目需求。这样的话将保证你取得更好、更精确的成果。

总结

经过学习本教程,你就可以把握怎么运用 OpenCV 进行活体检测。

现在经过运用活体检测器,你就可以检测出假造的人脸,并在你自己的人脸辨认系统中履行反人脸诈骗进程。

在活体检测器的创立进程中,咱们用到了 OpenCV、深度学习技能以及 Python 言语。

首要,咱们需求搜集自己的「实在 vs 假造」人脸数据集。为了完结该使命,咱们要做到:

1. 用智能手机录制一段咱们自己的视频(即「实在」人脸)。

2. 将咱们的智能手机屏幕展现给笔记本电脑/桌面电脑的摄像头,重放在上一步中录制的同一个视频,然后运用你的网络摄像头录下视频回放(即「假造」人脸)。

3. 将人脸检测技能一起运用到上面两个视频调集中,以构建终究的活体检测数据集。

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

咱们特意将网络规划得很浅,这是为了保证:

1. 在咱们的小型数据集上削减过拟合现象。

2. 模型可以实时运转(包含在树莓派等硬件上)。

总的来说,该活体检测器在咱们的验证集上的体现,精确率高达 99% 。

为了演示完好的活体检测作业流程,咱们创立了一个 Python + OpenCV 的脚本,该脚本加载了咱们的活体检测程序并将其运用在了实时视频流上。

正如咱们的演示样例所示,咱们的活体检测器可以区别真假人脸。

期望你喜爱这篇运用 OpenCV 进行活体检测的文章!

开发 视频 人脸辨认
声明:该文观念仅代表作者自己,搜狐号系信息发布渠道,搜狐仅供给信息存储空间效劳。
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。