这是我参与更文挑战的第14天,活动详情查看: 更文挑战
OpenCV
是一个C++
库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块。在Python
中常使用OpenCV
库实现图像处理。
本文将介绍OpenCV
的级联分类器以及如何利用Python
进行动态人脸,眼睛,微笑识别:
级联分类器
级联分类器
级联分类器,即使用类 Haar
特征工作的级联增强分类器,是集成学习的一种特殊情况,称为 boost。它通常依赖于 Adaboost
分类器(以及其他模型,如 Real Adaboost
、Gentle Adaboost
或 Logitboost
)
使用基于Haar
特征的级联分类器的对象检测是Paul Viola
和Michael Jones
在2001
年撰写的论文“使用简单特征的增强级联进行快速对象检测”中提出的一种有效的对象检测方法。
这是一种基于机器学习的方法,其中从许多正负图像中训练级联函数。然后用于检测其他图像中的对象。级联分类器在包含检测目标的几百个样本图像以及不包含检测目标的其他图像上进行训练。
我们如何检测图上是否有人脸呢?有一种名为 Viola-Jones
的目标检测框架的算法,包括了实时人脸检测所需的所有步骤:
- 提取
Haar
特征,特征来自Haar
小波 - 创建图像
Adaboost
训练- 级联分类器
Haar 特征选择
人脸上最常见的一些共同特征如下:
- 与脸颊相比,眼部颜色较深
- 与眼睛相比,鼻梁区域较为明亮
- 眼睛、嘴巴、鼻子的位置较为固定……
这些特征称为 Haar
特征。特征提取过程如下所示:
在上图中,第一个特征测量眼部和上脸颊之间的强度差异。特征值计算的方法很简单,对黑色区域中的像素求和再减去白色区域中的像素即可。
然后,将这个矩形作为卷积核作用到整个图像。为了不产生遗漏,我们需要用到每个卷积核的所有的维度和位置。简单的 24 * 24
的图像可能会产生超过 160000
个特征,每个特征由像素值的和/差组成。这样在计算上无法实现实时人脸检测。
那么,该如何加快这个过程呢?
一旦通过矩形框识别到有用区域,则在与之完全不同的区域上就无需再做计算了。
这一点可以通过 Adaboost
实现。
原始论文中提到几种可用于 Haar
特征提取的矩形框:
- 双矩形特征计算的是两个矩形区域内像素和的差,主要用于检测边缘
(a,b)
- 三矩形特征计算的是中心矩形和减去两个外部矩形和的差,主要用于检测线
(c,d)
- 四矩形特征计算的是矩形对角线对之间的差
(e)
特征提取完成后,使用 Adaboost
分类器将它们应用于训练集,该分类器结合了一组弱分类器来创建准确的集成模型。只需 200
个特征(最初是 16
万个),实现了 95%
的准确率。该论文的作者提取了 6000
个特征,具有38个阶段,在前五个阶段具有1
、10
、25
、25
和50
个特征。
使用 Adaboost 学习分类函数
给定一组带标签的训练图像(正负样本均有),Adaboost
用于:
- 提取一小部分特征。
- 训练分类器。
由于 16
万个特征中的大多数特征与之极不相关,因此我们设计一个增强模型的弱学习算法,用来提取单个矩形特征,将最好的正负样本区分开。
级联分类器
虽然上述过程非常有效,但仍存在一个重大问题。在图像中,大部分图像为非面部区域。对图像的每个区域给予等同的注意力是没有意义的,因为我们应该主要关注最有可能包含人脸的区域。Viola
和 Jone
使用级联分类器在减少了计算时间的同时,实现了更高的检测率。
关键思想是在识别人脸区域时排除不含人脸的子窗口。由于任务是正确识别人脸,我们希望假阴率最小,即包含人脸却未被识别的子窗口最少。
每个子窗口都使用一系列分类器。这些分类器是简单的决策树:
- 如果第一个分类器检测为正样本,继续用第二个。
- 如果第二个分类器检测是正样本,继续用第三个。
- 以此类推。
虽然有时可能包含人脸的图被认成负样本被子窗口漏检。但初级分类器以较低的计算成本筛除了大多数负样本,下图的分类器可额外消除更多的负样本,但需要更多的计算量。
使用 Adaboost
训练分类器,并调整阈值使错误率降到最低。在训练该模型时,变量如下:
- 每个阶段分类器数量。
- 每个阶段的特征数量。
- 每个阶段的阈值。
OpenCV
提供了一种训练方法或预先训练的模型,可以使用cv::CascadeClassifier::load
方法读取。预训练的模型位于OpenCV
安装的data
文件夹中,或在此处找到XML模型库
动态人脸,眼睛,微笑识别
参考往期的几篇文章:
实现代码:
import cv2
face_cascade = cv2.CascadeClassifier('E:\\demo\\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('E:\\demo\\haarcascade_eye.xml')
smile_cascade = cv2.CascadeClassifier('E:\\demo\\haarcascade_smile.xml')
# 调用摄像头摄像头
cap = cv2.VideoCapture(0)
while(True):
# 获取摄像头拍摄到的画面
ret, frame = cap.read()
faces = face_cascade.detectMultiScale(frame, 1.3, 2)
img = frame
for (x,y,w,h) in faces:
# 画出人脸框,蓝色,画笔宽度微
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 框选出人脸区域,在人脸区域而不是全图中进行人眼检测,节省计算资源
face_area = img[y:y+h, x:x+w]
## 人眼检测
# 用人眼级联分类器引擎在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表
eyes = eye_cascade.detectMultiScale(face_area,1.3,10)
for (ex,ey,ew,eh) in eyes:
#画出人眼框,绿色,画笔宽度为1
cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,255,0),1)
## 微笑检测
# 用微笑级联分类器引擎在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表
smiles = smile_cascade.detectMultiScale(face_area,scaleFactor= 1.16,minNeighbors=65,minSize=(25, 25),flags=cv2.CASCADE_SCALE_IMAGE)
for (ex,ey,ew,eh) in smiles:
#画出微笑框,红色(BGR色彩体系),画笔宽度为1
cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,0,255),1)
cv2.putText(img,'Smile',(x,y-7), 3, 1.2, (0, 0, 255), 2, cv2.LINE_AA)
# 实时展示效果画面
cv2.imshow('Capture',img)
# 每5毫秒监听一次键盘动作
if cv2.waitKey(5) & 0xFF == ord('L'):
break
# 最后,关闭所有窗口
cap.release()
cv2.destroyAllWindows()
输出为:
参考资源:
- Paul Viola and Michael J. Jones. Robust real-time face detection. International Journal of Computer Vision, 57(2):137–154, 2004. [228]
- Rainer Lienhart and Jochen Maydt. An extended set of haar-like features for rapid object detection. In Image Processing. 2002. Proceedings. 2002 International Conference on, volume 1, pages I–900. IEEE, 2002. [129]
- Video Lecture on Face Detection and Tracking
- An interesting interview regarding Face Detection by Adam Harvey
- OpenCV Face Detection: Visualized on Vimeo by Adam Harvey
今天的文章【Python3-OpenCV】级联分类器与动态人脸,眼睛,微笑识别分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20087.html