敢问路在何方,用手制作系列:用python实现面部检测,绿色直播

点击上方重视,All in AI我国

在本教程中,咱们将了解怎么运用OpenCV和Dlib在Python中创立和发动面部检测算法。咱们还将增加一些功用,以一起检测多个脸部的眼睛和嘴巴。本文将介绍人脸检测的最基本完成,包括级联分类器、HOG和深度学习CNN。

咱们将运用以下内容掩盖面部检测:

  • 运用OpenCV的Haar级联分类器
  • 运用Dlib的定向梯度直方图
  • 运用Dlib的卷积神经网络

本文开端发布在我的个人博客上:https://maelfabien.github.io/tuto蹉跎rials/face-detection/#

能够在此处找到本文的Github存储库(以及我博客中的一切其他存储库):

https://github.com/maelfabien/Machine_Learning_Tutorials

介绍

咱们将运用OpenCV,一个用C / C ++编写的核算机视觉开源库,它有C ++、P首尔气候ython和Java接口。支撑Windows、Linux、MacOS、iOS和Android。咱们的一些作业还需求运用Dlib,这是一个现代C ++东西包,包括用于创立杂乱软件的机器学习算法和东西。

要求

榜首步是装置OpenCV和Dlib。运转以下指令:

依据您的版别,该文件将装置在此处:

进口和模型途径

咱们将创立一个新的Jupyter笔记本/ python文件,从以下开端:

I.级联分类器

咱们将首要探究级联分类器。

I.1.理论

级联分类器,或者是相似于相似哈尔特征的级联增强分类器,是集成学习的一种特别情况,称为增强。它一般依赖于Adaboost分类器(以及其他模型,如Real Adaboost、Gentle Adaboost或Logitboost)。

级联分类器在包括咱们想要检测的方针的几百个图画样本图画以及不包括这些图画的其他图画上进行练习。

咱们怎么检测面部是否存在?有一种名为Viola-Jones方针检测结构的算法,包括实时面部检测所需的一切进程:

  • Haar特征挑选,源自Haar小波的特征
  • 创立积分图画
  • Adaboost练习
  • 级联分类器

原始论文于2001年出书。英文版传送门:https://www.cs.cmu.edu/~efros/c怎样做爱ourses/LBMV07/Papers/viola-cvpr-01.pdf

I.1.a.哈尔特征挑选

咱们在最常见的人脸上发现了一些一起特征:

  • 一个黑眼圈区域与上颊比较
  • 与眼睛比较,亮堂的鼻梁区域
  • 眼睛,嘴巴,鼻子的一些特定方位......

这些特征称为哈尔特征。特征提取进程如下敢问路在何方,用手制造系列:用python完成面部检测,绿色直播所示:

Haar Features

在该示例中,榜首特征丈量的是眼睛区域和横跨上脸颊的区域之间的强度差异。特征值的核算办法很简略,将黑色区域的像素相加,然后减去白色区域的像素。

然后,咱们将这个矩形作为卷积内核运用于整个图画上。为了翔实无遗,咱们应该运用每个内核的一切或许的维度和方位。简略的24 * 24图画一般会发生超越160'000个特征,每个特征由像素值的和/减法组成。实时面部检测在核算上是不或许的。那么,咱们怎么加速这个进程呢?

  • 一旦经过矩形辨认好区域,在彻底不同的图画区域上运转窗口是没有用的,这能够经过Adaboost完成。
  • 运用积分图画原理核算矩形特征,这种办法会更快。咱们将在下一节中介绍这一点。

有几种类型的矩形可用于Haar特征提取。依据原始论文:

  • 两个矩形特征是两个矩形区域内像素之和的差异,首要用于检测边际(a,b)
  • 三矩形特征核算从中心矩形中的和减去两个外部矩形内的和,首要用于检测直线(c,d)
  • 四矩形特征核算矩形对角线对之间的差异(e)

矩形哈尔

现在现已挑选了这些特征,咱们运用Adaboost分类将它们运用于练习图画集,该分类结合了一组弱分类器来创立精确的调集模型。具有200个功用(开端不是160'000),完成了95%的精度。该论文的作者挑选了6,000个特征。

I.1.b.积分图画

用卷积内核款式核算矩形特征或许很长很长。出于这个原因,作者Viola和Jones提出了一种图画的中心表明:积分图画。积分图画的作用是答应仅运用四个值简略地核算任何矩形和。咱们能够看看它是怎么作业的!

假定咱们想要确认一个给定像踩射素上坐标(x,y)的矩形特征。然后,像素的积分图画在给定像素的上方和左边的像素之和中。

其间ii(x,y)是积分图画,i(x,y)是原始图画。

当您核算整个积分图画时,有一种办法是重复,只需求在原始图画上递归一次。实践上,咱们能够界说以下两组递归:

其间s(x,y)是累积行和,而且s(x-1)= 0,ii(-1,y)= 0。

这有什么用?考虑一个咱们想要预算像素总和的区域D。咱们还界说了3个其他区域:A、B和C。

  • 点1处的积分图画的值是矩形A中的像素的总和
  • 第2点的值是A+ B.
  • 第3点的值是A+ C.
  • 第4点的值是A + B + C + D.

因而,区域D中的像素之和能够简略地核算为:4 + 1-(2 + 3)。

在一次传递中,咱们仅运用4个数组引证核算了矩形内的值。

人们应该简略地意识到矩形在实践中是十分简略的特征,但足以用于面部检测。当触及杂乱问题时,可操纵滤波器往往更灵敏。

可操纵的过滤器

I.1c.运用Adaboost学习分类函数

给定一组敢问路在何方,用手制造系列:用python完成面部检测,绿色直播符号的练习图画(正面或负面),Adaboost用于:

  • 挑选一小组特征
  • 并练习分类器

由于160'000中的大多数特征应该是十分不相关的,因而咱们构建增强模型的弱学习算法建立了一个增强模型。该算法的意图是挑选单个矩形特征,将最好的正、负样本进行切割。

I.1.d.级联分类器

尽管上述进程十分有用,但仍存在一个重大问题。在图画中,大部分图画对错面部区域。对每个区域都根据平等的重要性是没有意义的,由于我我的楼兰们应该首要重视最有或许包括图片的区域。Viola和Jones在运用级联分类器削减核算时刻的一起进步了检测率。

要害的主意是在辨认区域时回绝不包括人脸的子窗口。由于使命是正确辨认面部,咱们期望最小化假阴性率,即包括面部而且尚未被辨认的子窗口。

一系列分类器应手机进水怎么办用于每个子窗口。这些分类器是简略的决策树:

  • 假如第康奈尔大学一个分类器是正数,咱们持续到第二个
  • 假如第二个分类器是正数,咱们持续第三个
  • ...

在某些时分任何负面成果都会导致子窗口被回绝为或许包括面部。初始分类器以较低的核算成本消除了大多数否定示例,而且以下分类器消除了额定的负面示例,但需求更多的核算作业量。

运用Adaboost练习分类器并调整阈值以最小化错误率。在练习这样的模型时,变量如下:

  • 分类器级数
  • 每个阶段的特征数量
  • 每个阶段的阀值

走运的是,在OpenCV中,整个模型现已过预先练习,韦文学广西乞丐简历可用于人脸检测。

I.2.输入

下一步仅仅找到预先练习的权重。咱们将运用默许的预练习模型来检测面部、眼睛和嘴巴。依据您的Python版别,文件应放在这儿的某个当地:

/usr/local/lib/python3.7/site-packages/cv2/data

一旦确认,咱们将以这种办法声明Cascade分类器:

cascPath = "/usr/local/lib/python3.7/site-packages/cv2/data/haarcascade_frontalface_default.xml"
eyePath = "/usr/local/lib/python3.7/site-packages/cv2/data/haarcascade_eye.xml"
smilePath = "/usr/local/lib/python3.7/site-packages/cv2/data/haarcascade_s夕mile.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
eyeCascade = cv2.CascadeClassifier(eyePath)
smileCascade = cv2.CascadeClassifier(smilePath)

I.3.检测图画上的脸部

在完成实时人脸检测算法之前,咱们先在图画上测验一个简略的版别。咱们能够从加载测验图画开端:

# Load the image
gray = cv2.imread('face_detect_test.jpeg', 0)
plt.figure(figsize=(12,8))
plt.imshow(gray, cmap='gray')
plt.show()

测验图画

然后,咱们检测到脸部并在其周围增加一个矩形:

# Detect faces
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
flags=cv2.CASCADE_SCALE_IMAGE
)
# For each face
for (x, y, w, h) in faces:
# Draw rectangle around the face
cv2.rectangle(gray, (x, y), (x+w, y+h), (255, 255, 255), 3)

以下是detect Multi Scale函数最常见参数的列表:

  • scaleFactor:指定在每个图画份额下图画巨细削减多少的参数。
  • minNeighbors:参数指定每个候选矩形应保存多少个街坊。
  • minSize:最小或许的方针巨细。小于该值的方针将被疏忽。
  • maxSize:最大或许的方针巨细。大于该值的方针将被疏忽。

最终己所不欲勿施于人,显现成果:

plt.figure(figsize=(12,8))
plt.imshow(gray, cmap='gray')
plt.show()

人脸检测在咱们的测验图画上运转杰出。让咱们现在开端进入最振作的部分吧!

I.4.实时人脸检测

让咱们持续进行实时面部检测的Python完成。榜首步是发动摄像头,并捕获视频。然后,咱们将图画转换为灰度图画。这用于减小输入图画的尺度。实践上,咱们运用简略的线性变换,而不是描绘赤色、绿色、蓝色的每个像素3个点,而不是:

这在OpenCV中默许完成。

video_capture = cv2.VideoCapture(0)
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

现在,咱们将运用上面界说的face Cascade变量,它包括一个预先练习断奶过的算法,并将其运用于灰度图画。

faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)

关于检测到的每个脸部,咱们将在脸部周围制造一个矩形:

for (x, y, w, h) in faces:
if w > 250 :
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 3)
roi_gr敢问路在何方,用手制造系列:用python完成面部检测,绿色直播ay = gray[y:y+h, 敢问路在何方,用手制造系列:用python完成面部检测,绿色直播x:x+w]
roi_color = frame[y:y+h, x:x+w]

关于检测到的每个嘴,在它周围画一个矩形:

smile = smileCascade.detectMultiScale(
roi_gray,
scaleFactor= 1.16,
minNeighbors=35,
minSize=(25, 25),
flags=cv2.CASCADE_SCALE_IMAGE
)
for (sx, sy, sw, sh) in smile:
cv2.rectangle(roi_color, (sh, sy), (sx+sw, sy+sh), (255, 0, 0), 2)
cv2.putText(frame,'Smile',(x + sx,y + sy), 1, 1, (敢问路在何方,用手制造系列:用python完成面部检测,绿色直播0, 255, 0), 1)

关于检测到的每只眼睛,在其周围制造一个矩形:

eyes = eyeCascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_c敢问路在何方,用手制造系列:用python完成面部检测,绿色直播olor,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.putText(frame,'Eye',(x + ex,y + ey), 1, 1, (0, 255, 0), 1)

然后,核算面部总数,并显现全体图画:

if cv2.waitKey(1) & 0xFF == ord('q'):
break

当咱们想经过按q来中止相机时,履行退出选项:

video_capture.release()
cv2.destroyAllWindows()

最终,当一切都完成后,开释捕获并毁掉一切窗口。在Mac上封闭Windows或许存在一些问题,或许需求稍后从活动管理器中kill Python。

I.5.总结

I.6.成果

这儿做了一个人脸检测算法的快速宅男撸管演示。

II.Dlib中的定向梯度直方图(HOG)

Dlib供给了第二种最常用的人脸检测东西,它运用了一种名为直方图梯度(HOG)的概念。这是Dalal和Triggs的原始论文的完成。

II.1. 理论

HOG背面的主意是将特征提取到矢量中,并将其供给给分类算法,例如支撑向量机,例如,它将评价一个人脸(或您练习它实践辨认的任何方针)是否存在于某个区域中。

提取的特征是图画的梯度方向(定向梯度)的散布(直方图)。梯度一般在边际和旮旯周围较大,并答应咱们检测这些区域。

在原始论文中,对人体检测进程进行了完成,检测链如下:

II.1.a.预处理

首要,输入图画有必要具有相同的尺度(裁剪和从头缩放图画)。咱们将运用的色块要求宽高比为1:2,因而输入图画的尺度或许为64x128或100x200。

II.1.b.核算梯度图画

榜首步是经过运用以下内核核算图画的水平缓笔直梯度:

用于核算梯度的内核

图画的梯度一般会删去非必要信息。

咱们在上面考虑的图画的梯度能够在Python中以这种办法找到:

gray = cv2.imread('images/face_detect_test.jpeg', 0)
im = np.float32(gray) / 255.0
# Calculate gradient
gx = cv2.Sobel(im, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(im, cv2.CV_32F, 0, 1, ksize双胞胎攻=1)
mag, angle = cv2.cartToPo敢问路在何方,用手制造系列:用python完成面部检测,绿色直播lar(gx, gy, angleInDegrees=True)

并制造图片:

plt.figure(figsize=(12,8))
plt.imshow(mag)
plt.show()

咱们之前没有对图画进行预先处理。

II.1.c.核算HOG

然后将图画分红8x8单元,以供给一个紧凑的表明,使咱们的HOG对噪声愈加鲁棒。然后,咱们为每个单元格核算一个HOG。

为了估量区域内的梯度方向,咱们只需在每个区域内的64个梯度方向值(8x8)及其巨细(别的64个值)之间构建直方图。直方图的类别对应于梯度的视点,从0到180。一共9类:0、20、40...... 160。

上面setma的代码给了咱们2个信息:

  • 梯度的方向
  • 梯度的巨细

当咱们构建HOG时,有3个子事例:

  • 视点小于160,且不介于两类之间。在这种情况下,视点将增加到HOG的右侧类别中
  • 视点小于160,恰好在2级之间。在这种情况下,咱们考虑对2个最近的类进行持平的奉献,并将巨细分红2个部分

  • 视点大于160。在这种情况下,咱们以为像素的奉献份额为160和0。

关于每个8x8单元,HOG看起来像这样:

Hog

II.1.d. 区间归一化

最终,能够运用16x16块对图画进行归一化,使其不受光照的影响。这能够经过将巨细为8x8的HOG的每个值除以包括它的16x16块的HOG的L2范数来完成,这实践上是长度为9 * 4 = 36的简略向量。

II.2.检测图画上的脸部

施行十分简略:

face_detect = dlib.get_frontal_face_detector()
rects = face_detect(gray, 1)
for (i, rect) in enumerate(rects):
(x, y, w, h) = face_utils.rect_to_bb(rect)
cv2.rectangle(gray, (x, y), (x + w, y + h), (255, 255, 255), 3)

plt.figure(figsize=(12,8))
plt.imshow(gray, cmap='gray')
plt.show()

II.3.实时人脸检测

如前所述,该算法十分简单完成。咱们还经过仅检测面部来完成更轻的版别。 Dlib也很简单检测面部要害点,但这是另一个论题。

III.Dlib中的卷积神经网络

最终一种办法根据卷积神经网络(CNN)。它还完成了一篇关于最大边距方针检测(MMOD)的论文,以增强成果。

III.1.一点理论

卷积神经网络(CNN)是前馈神经网络,首要用于核算机视觉。它们供给主动图画预处理以及密布的神经网络部分。 CNN是用于处理具有网格状拓扑的数据的特别类型的神经网络。 CNN的架构遭到动物视觉皮层的启示。

在曾经的办法中,很大一部分作业是挑选滤镜以创立特征,以便尽或许多地从图画中提取信息。跟着深度学习和更高核算才能的进步,这项作业现在能够完成主动化。 CNN的称号来自于咱们将初始图画输入与一组过滤器进行卷积的现实。要挑选的参数仍然是要运用的过滤器数量以及过滤器的尺度。过滤器的尺度乌镇在哪称为步幅长度。步幅的典型值介于2和5之间。

在这种特定情况下,CNN的输出是二进制分类,假如有面部,则取值1,否则取0。

III.2.检测图画上的脸部

一些元素在完成中发生了改变。

榜首步是在这儿下载mars预先练习的模型。将权重移动到您的文件夹,并界说dnnDaceDetector:

dnnFaceDetector = dli俯卧撑的正确做法b.cnn_face_detection_model_v1("mmod_human_face_detector.dat")

然后,与咱们迄今为止所做的彻底相同:

rects = dnnFaceDetector(gray, 1)
for (i, rect) in enumerate(rects):
x1 = rect.rect.left()
y1 = rect.rect.top()
x2 = rect.rect.right()
y2 = rect.rect.巨野气候bottom()
# Rectangle around the face
cv2.rectangle(gray, (x1, y1), (x2, y2), (255, 255, 255), 3)
plt.figure(figsize=(12,8))
plt.imshow(gray, cmap='gray')
plt.show()

III.3.实时人脸检测

最终,咱们将完成CNN人脸检测的实时版别:

IV.哪一个挑选?

这是一个扎手的问题,但咱们只会经过两个重要目标:

  • 核算时刻
  • 精确性

在速度方面,HoG似乎是最快的算法,其次是Haar Cascade分类器和CNN。

可是,Dlib中的CNN往往是最精确的算法。 HoG体现适当不错,但有一些辨认小面孔方华严经面的问题。 HaarCascade分类器的性能与HoG相同好。

我个人首要在我的个人项目中运用HoG,由于它能够快速的进行实时人脸检测。

V. 来历 :

  • HOG
  • DLIB
  • Viola-Jones Paper
  • Face Detection 1
  • Face Detection 2
  • Face Detection 3
  • DetectMultiScale
  • Viola-Jones

原文作者:Mal Fabien

编译出品


评论(0)