OpenCV+Python实战人脸检测

发布于:2025-06-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

《OpenCV计算机视觉开发实践 基于Python朱文伟,李建英 著清华大学出版社 新华书店文轩正版 图书》【摘要 书评 试读】- 京东图书

现代社会中信息安全和网络金融安全越来越受重视,信息和金融安全依赖于个人身份认证,个人身份认证所依赖的信息来源于每个人与生俱来的特殊性,如指纹、DNA、人脸等,这是实现身份认证的前提。想要设计一套通用的、能够准确描述每个人身份的数学模型是比较困难的。相对于其他人体特征,人脸具有以下4个优势:

  • 自然性。自然性体现在每个生物个体都存在着这种特征。具有自然性的生物特征还有声音、形体等,但是声音容易受到外界干扰,提取时需要在安静的空间进行;虽然形体属于图像特征,但是形体容易受到衣服和季节的影响,而且形体图像采集不方便、不确定因素较大。
  • 非强制性。非强制性的优点体现在智能家居或者监控系统中,可以在不被察觉的情况下采集特征并做出响应。非强制性体现在不需要个体刻意配合、采集起来更加方便,还能在一定程度上防止欺骗与伪装识别。
  • 非接触性。当今社会越来越注重人的隐私,人脸图像采集发生在不接触的情况下,很好地保证了身份验证对象的权利,而且这种非接触性有利于预防和消除疾病等依赖接触性传播的负面影响。
  • 并发性。在实际应用中人脸识别有可能被同时应用,依赖人脸进行身份认证的优势得以体现。

人脸检测的常用方法

人脸检测是人脸识别的基础,此阶段的任务是在静态图像中分辨出是否存在人脸,而且还要标记出人脸的位置。人脸检测的评价标准是速度、错误率以及成功率。目前人脸检测技术已经非常成熟,常见的方法如图15-24所示,可以看到其包括先验知识、模板匹配、机器学习、深度学习四大类方法。

图15‑24

(1)基于先验知识的人脸检测算法是对人的面部进行观察,根据已有经验对面部特征进行分析,然后对人脸图像统一编码。一般人脸图像的核心区域是对称分布的,面部有亮有暗。人们根据自己的先验知识设计相关检测算法,优势在于速度快、对硬件要求低;缺点是局限性强,只能用于简单的正面人脸检测。每个人对人脸的先验知识理解不一致,因此没有统一的规则。利用先验知识进行人脸检测的常见算法有灰度特征、肤色特征和人脸横纹特征等。

(2)人脸检测的模板匹配的理论依据是归纳总结、反复计算和统计人脸样本,然后根据总结出的经验或者共性提取出人脸特征,最后得到人脸模板。该算法的依据是对比待检测人脸和模板,如果匹配值达到了设定的阈值就进行标记,然后确定人脸的大小和位置。但是,在现实生活中,人脸图像的采集情况比较复杂,远近、大小、光照和倾斜等都使得简单模板缺乏鲁棒性。针对这一局限性,有研究者设计了可变模板,当人脸发生变化时也能设计出最合适的模板与之匹配,提高了识别率。

(3)基于机器学习的人脸检测算法与上述两种检测算法均不一样。机器学习可以利用机器学习和统计进行训练得到相应结果,基本流程是通过对大量的数据样本进行训练,计算机利用统计学原理自主分析学习、记录学习结果、提取人脸特征,将图像检测的难题转换成机器易于理解和处理的二值问题,最后通过各种分类器来完成人脸标记。由于该算法训练数据样本多,因此检测时相对耗时,但在识别精度上优于上述两种算法。

(4)基于深度学习的人脸检测算法是在第三种的基础上增加训练样本,通过网络结构更加复杂、算法更加细化的卷积神经网络提取特征,然后降维,最后设计相关分类器进行分类。该算法在牺牲检测效率的基础上大大提高了识别率,不过对计算机硬件要求也比较高。

为了提高人脸检测的速度和精度,最终的分类器还需要通过几个强分类器级联得到。在一个级联分类系统中,对于每一个输入图像,顺序通过每个强分类器。其中,前面的强分类器相对简单,包含的弱分类器相对较少,后面的强分类器逐级复杂,只有通过前面的强分类检测后的图像,才能送入后面的强分类器检测,比较靠前的几级分类器可以过滤掉大部分不合格的图像,只有通过了所有强分类器检测的图像区域,才是有效的人脸区域。

AdaBoost算法

AdaBoost(Adaptive Boosting,自适应增强)算法是一种提升方法,它将多个弱分类器组合成强分类器。AdaBoost由Yoav Freund和Robert Schapire在1995年提出,它的自适应在于:前一个弱分类器分错的样本的权值(样本对应的权值)会得到加强,权值更新后的样本再次被用来训练下一个新的弱分类器。在每轮训练中,用总体(样本总体)训练新的弱分类器,产生新的样本权值,一直迭代到达到预定的错误率或达到指定的最大迭代次数。其算法原理如下:

(1)初始化训练数据(每个样本)的权值分布。如果有N个样本,那么每一个训练的样本点最开始时都被赋予相同的权重,即1/N

(2)训练弱分类器。在具体的训练过程中,如果某个样本已经被准确地分类,那么在构造下一个训练集中它的权重就会被降低;相反,如果某个样本点没有被准确地分类,那么它的权重就会得到提高。然后,更新权值后的样本集被用于训练下一个分类器。整个训练过程就如此迭代下去。

(3)将各个训练得到的弱分类器组合成强分类器。各个弱分类器的训练过程结束后,分类误差率小的弱分类器的话语权较大,其在最终的分类函数中起着较大的决定作用;而分类误差率大的弱分类器的话语权较小,其在最终的分类函数中起着较小的决定作用。换言之,误差率低的弱分类器在最终分类器中占的比例较大,反之较小。

AdaBoost训练出来的强分类器一般具有较小的误识率,但是检测率并不是很高。一般情况下,高检测率会导致高误识率,这是由强分类阈值的划分导致的。要提高强分类器的检测率就要降低阈值,要降低强分类器的误识率就要提高阈值。增加分类器个数可以在提高强分类器检测率的同时降低误识率,所以级联分类器在训练时要考虑两点平衡:一是弱分类器的个数和计算时间的平衡,二是强分类器检测率和误识率之间的平衡。

如果要从头开始实现人脸检测,就要有较深的“功力”。作为初学者,我们可以站在巨人的肩膀上,比如使用OpenCV的级联分类器(CascadeClassifier)加载预训练模型 haarcascade_frontalface_default.xml(该模型使用AdaBoost算法,运行速度很快)。

【例15.5】  人脸检测

import cv2

# 读取文件
def detectface(imagePath):
	model = 'haarcascade_frontalface_default.xml'
	image = cv2.imread(imagePath)  # 读取图片
	model = cv2.CascadeClassifier(model)  # 加载模型
	# 人脸检测
	faces = model.detectMultiScale(image)
	for (x, y, w, h) in faces:
		cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)  # 画出人脸矩形框

	# 显示和保存图片
	p1='res_';
	p2=str(imagePath)
	path=p1+p2;
	cv2.imwrite(path, image)
	print('已保存')
	cv2.imshow('result', image)

detectface("test.jpg") 
cv2.waitKey(1000)
detectface("lena.png") 
cv2.waitKey(0)
cv2.destroyAllWindows()

运行工程,结果如图15-25所示。

图15‑25

【例15.6】  人眼检测

import cv2

# 读取文件
def detectface(imagePath):
	# 读取文件
	model = 'haarcascade_eye.xml'
	image = cv2.imread(imagePath)  # 读取图片
	model = cv2.CascadeClassifier(model)  # 加载模型

	# 人眼检测
	faces = model.detectMultiScale(image)
	for (x, y, w, h) in faces:
		cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)  # 画出人眼矩形框
	# 显示和保存图片
	cv2.imshow('result', image)


detectface("test.jpg") 
cv2.waitKey(1000)
detectface("lena.png") 
cv2.waitKey(0)
cv2.destroyAllWindows()

代码和上例基本类似,就是训练模型文件换成了haarcascade_eye.xml(在工程目录下,可以直接使用)。

运行工程,结果如图15-26所示。

图15‑26


网站公告

今日签到

点亮在社区的每一天
去签到