ai软件怎么做快速生成色块如何使用OpenCV和Dlib在Python中创建和启动面部检测算法

点击上方关注,AllinAI中国

在本教程中,我们将知道怎样使用OpenCV和Dlib在Python中建立和推进面部检测算法。我们还将添加一些功能,以同时检测多个头部的耳朵和眼睛。本文将介绍人脸检测的最基本推动,包括级联分类器、HOG和深度学习CNN。

我们将使用下面内容覆盖面部检测:

本文最初公布在我的个人博客上:https://maelfabien.github.io/tutorials/face-detection/#

可以在这里找到本文的Github存储库(或者我博客中的所有其它存储库):

介绍

我们将使用OpenCV,一个用C/C++编写的计算机视觉开源库,它有C++、Python和Java接口。支持Windows、Linux、MacOS、iOS和Android。我们的一些工作还必须使用Dlib,这是一个现代C++软件包,包含用于建立复杂硬件的机器学习算法和软件。

要求

第一步是安装OpenCV和Dlib。运行以下命令:

根据您的版本,该文件将安装在这里:

进口和模型路径

我们将构建一个新的Jupyter笔记本/python文件,从下面开始:

I.级联分类器

我们将首先构建级联分类器。

I.1.理论

级联分类器,或者是类似于类似哈尔特征的级联增强分类器,是集成学习的一种特殊状况,称为提高。它一般依赖于Adaboost分类器(或者其它模型,如RealAdaboost、GentleAdaboost或Logitboost)。

级联分类器在包括我们想要测试的对象的几百个图像样本图像或者不包括那些图像的其它图像上进行训练。

我们怎么检查面部是否存在?有一种名为Viola-Jones对象测试框架的算法,包括即时面部检测所需的所有方法:

原始论文于2001年出版。英文版传送门:~efros/courses/LBMV07/Papers/viola-cvpr-01.pdf

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

我们在最常见的人脸上看到了一些共同特征:

这种特性称为哈尔特征。特征提取过程如下所示:

HaarFeatures

在该示例中,第一特点测量的是脸部区域和横跨上脸颊的区域之间的硬度变化。特征值的推导方式很简洁,将白色区域的像素相加,然后除以白色区域的像素。

之后,我们将这个矩形作为聚类内核应用于整个图像上。为了详细无遗,我们必须应用每个内核的所有可能的维度和位置。简单的24*24图像一般会造成低于160'000个特征,每个特征由像素值的和/减法组成。实时面部检测在计算上是不可能的。那么,我们怎么加速这个过程呢?

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

矩形哈尔

目前尚未选择了很多特性,我们使用Adaboost分类将他们应用于训练图像集,该分类结合了一组弱分类器来建立准确的集合模型。具有200个功能(最初不是160'000),实现了95%的效率。该论文的作者选择了6,000个特征。

I.1.b.积分图像

用卷积内核样式计算圆形特征或许很长很长。出于这个理由,作者Viola和Jones提出了一种图像的后面表示:积分图像。积分图像的作用是允许仅使用四个值简单地计算任何矩形和。我们可以看看它是怎样工作的!

假设我们想要确认一个给定像素上坐标(x,y)的圆形特征。然后,像素的积分图像在给定像素的下侧和右侧的像素之和中。

其中ii(xai软件怎么做快速生成色块,y)是积分图像,i(x,y)是原始图像。

当您计算整个积分图像时,有一种方式是重复,只应该在原始图像上递归一次。实际上,我们可以定义下述两组递归:

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

这有哪些用?考虑一个我们想要计算像素总和的区域D。我们还定义了3个其它区域:A、B和C。

此外,区域D中的像素之和可以简单地计算为:4+1-(2+3)。

在一次释放中,我们仅使用4个函数引用计算了矩形内的值。

他们必须简单地观念到矩形在实践中是相当简洁的特点,但足以用于面部检测。当涉及复杂难题时,可操控滤波器通常更灵活。

可操纵的过滤器

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

给定一组标记的练习图像(背面或负面),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_smile.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)

以下是detectMultiScale函数最常用参数的列表:

最终,显示结果:

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)

目前,我们将使用前面定义的faceCascade变量,它包括一个预先练习过的算法,并将其应用于灰度图像。

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)

ai色块渐变怎么做_ai制作几何色块_ai软件怎么做快速生成色块

roi_gray = gray[y:y+h, 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, (0, 255, 0), 1)

针对检测到的每只眼睛,在其周边绘制一个矩形:

eyes = eyeCascade.detectMultiScale(roi_gray)
 for (ex,ey,ew,eh) in eyes:
 cv2.rectangle(roi_color,(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可能存在一些疑问,可能必须稍后从活动管理器中killPython。

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.cartToPolar(gx, gy, angleInDegrees=True)

并绘制图片:

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

ai色块渐变怎么做_ai软件怎么做快速生成色块_ai制作几何色块

我们之前没有对图像进行预先处理。

II.1.c.计算HOG

之后将图像分成8x8单元,以提供一个紧凑的表示,使我们的HOG对噪声非常鲁棒。然后,我们为每位单元格计算一个HOG。

为了估计区域内的梯度方向,我们只需在每位区域内的64个梯度方向值(8x8)以及大小(此外64个值)之间建立直方图。直方图的类型对应于梯度的视角,从0到180°。总共9类:0°、20°、40°......160°。

后面的代码给了我们2个信息:

当我们形成HOG时,有3个子案例:

对于每个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.检测图像上的脸部

一些元素在推动中发生了变化。

第一步是在此处下载预先练习的建模。将权重移动到您的文件夹,并定义dnnDaceDetector:

dnnFaceDetector = dlib.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.哪一个选择?

这是一个棘手的难题,但我们只会通过两个重要指标:

在速度方面ai软件怎么做快速生成色块,HoG似乎是最快的算法,其次是HaarCascade分类器和CNN。

然而,Dlib中的CNN通常是最精确的算法。HoG表现非常不错,但有一些识别小面孔方面的弊端。HaarCascade分类器的性能与HoG一样好。

我个人主要在我的个人项目中使用HoG,因为它可以迅速的进行即时人脸检测。

V.来源:

添加微信

转载原创文章请注明,转载自设计培训_平面设计_品牌设计_美工学习_视觉设计_小白UI设计师,原文地址:http://www.zfbbb.com/?id=5525

上一篇:ai编辑软件全球科技巨头微软决定用人工智能代替自己新闻网站的编辑队伍

下一篇:ai编辑软件人类编辑失业的锅不能全甩给AI,事实永远都不是“非黑即白”