开发十年,就只剩下这套Java开发体系了 >>>
目标
在这届会议上,
- 我们将使用基于Haar特征的级联分类器来了解人脸检测的基础知识
- 我们将延长相同的眼睛检测等。
基础
使用基于Haar特征的级联分类器的对象检测是Paul Viola和Michael Jones在2001年发表的文章“使用简单特征的增强级联的快速对象检测”中提出的一种有效的对象检测方法。它是基于机器学习的方法,其中a级联功能是从许多正面和负面图像进行训练。然后用它来检测其他图像中的对象。
在这里,我们将使用人脸检测。最初,该算法需要大量正面图像(人脸图像)和负面图像(无人脸图像)来训练分类器。然后我们需要从中提取功能。为此,使用下图中显示的haar特征。它们就像我们的卷积核。每个特征是通过从黑色矩形下的像素之和中减去白色矩形下的像素总和而获得的单个值。
现在,每个内核的所有可能的大小和位置都用来计算大量的功能。(想象一下它需要多少计算?即使是一个24x24的窗口也会产生超过160000个特性)。对于每个特征计算,我们需要找到白色和黑色矩形下的像素总和。为了解决这个问题,他们介绍了积分图像。它简化了像素总和的计算,像素数量有多大,涉及到只涉及四个像素的操作。很好,不是吗?它使事情超快。
但在我们计算的所有这些特征中,大多数都是无关紧要的。例如,请考虑下面的图片。顶行显示两个很好的功能。所选的第一个特征似乎集中在眼睛区域比鼻子和脸颊区域更暗的属性上。所选的第二个特征依赖于眼睛比鼻梁更暗的特性。但应用在脸颊或任何其他地方的窗户是无关紧要的。那么我们如何从16万多个功能中选择最佳功能呢?它由Adaboost实现。
为此,我们在所有训练图像上应用每个特征。对于每个特征,它找到最佳的阈值,将脸部分为正面和负面。但显然,会出现错误或错误分类。我们选择错误率最小的特征,这意味着它们是对脸部和非脸部图像进行最佳分类的特征。(这个过程并不像这样简单,每个图像在开始时被赋予相同的权重,每次分类之后,错误分类的图像的权重会增加,然后再次进行相同的处理,计算出新的错误率,并计算新的权重。过程继续进行直到达到所需的准确度或错误率或找到所需的特征数目)。
最后的分类器是这些弱分类器的加权和。它被称为弱,因为它本身不能对图像进行分类,但与其他人形成强大的分类器。该报告称,即使200个功能也能提供95%的准确度检测。他们的最终设置有大约6000个功能。(想象一下从160000+个功能减少到6000个功能,这是一个很大的收获)。
所以现在你拍一张照片。采取每个24x24窗口。为其添加6000个功能。检查它是否正面。哇..哇..是不是有点低效和耗时?是的。作者有一个很好的解决方案。
在图像中,大部分图像区域是非人脸区域。所以最好有一个简单的方法来检查一个窗口是不是一个人脸区域。如果不是,则一次性丢弃它。不要再处理它。而应关注可能有脸部的区域。这样,我们可以找到更多时间来检查可能的脸部区域。
为此,他们引入了分类器级联的概念。不是将所有6000个特征应用于窗口,而是将特征分组到分类器的不同阶段并逐个应用。(通常最初的几个阶段将包含非常少的功能)。如果一个窗口在第一阶段失败,请丢弃它。我们不考虑其他功能。如果通过,则应用第二阶段的功能并继续该过程。通过所有阶段的窗口是一个面部区域。计划如何!
作者的探测器具有6000多个特征,38个阶段,前5个阶段具有1,10,25,25和50个特征。(上图中的两个功能实际上是Adaboost的两个最佳功能)。据作者说,平均而言,每个子窗口评估了6000个以上的10个功能。
因此,这是对Viola-Jones人脸检测工作的直观解释。请阅读论文以获取更多详细信息,或查看其他资源部分中的参考资料
OpenCV中的Haar级联检测
OpenCV随附教练机和探测器。如果你想为汽车,飞机等任何物体训练你自己的分类器,你可以使用OpenCV创建一个。它的全部细节在这里给出:级联分类器培训。
这里我们将处理检测。OpenCV已经包含许多用于面部,眼睛,笑脸等的预先分类器。这些XML文件存储在opencv/data/haarcascades/
文件夹中。让我们用OpenCV创建人脸和眼睛检测器。
首先,我们需要加载所需的XML分类器。然后以灰度模式加载我们的输入图像(或视频)。
import numpy as np import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') img = cv2.imread('sachin.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
现在我们在图像中找到了脸部。如果找到面部,它会以Rect(x,y,w,h)的形式返回检测到的面部的位置。一旦我们获得了这些位置,我们就可以为脸部创建ROI并在此ROI上应用眼部检测(因为眼睛总是在脸上!!!)。
faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.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.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows()
结果如下所示:
其他资源
- 视频演讲人脸检测和跟踪
- 亚当·哈维有关人脸检测的一个有趣采访
参考:
http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_objdetect/py_face_detection/py_face_detection.html
转载请注明出处!!!