目录
💡推荐
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击跳转到网站】
人脸检测与识别是基于人的脸部特征信息进行身份识别的一种生物识别技术,主要用像机或相机采集含有人险的视频流或图像,并自动在图像中检测和跟踪人险,进而对测的人脸进行脸部识别,通营也叫作人像识别、面部识别。调用 OpenCV训练好的分类器和自带的检测函数检测人脸、人眼等的步骤如下:
1)加载分类器,找到分类器的位置,如 *\opencv\sources\data\haarcascades(Harr 分类器)
2)调用 detectMultiScale() 雨数进行检测,调整函数的参数可以使检测结果更加精确
3)把检测到的人脸等用矩形(或者圆形等其他图形)标记出来
一、图像预处理
图像预处理时,要先把图像转化为灰度图像。使用的OpenCV函数为:
gray = cv2.cvtColor(image,cv.COLOR_BGR2GRAY)
这样的转化可能会造成图像的灰度值分布不均匀,通常认为,对所有可用像素强度值均衡使用,才是一幅高质量的图像,所以,我们需要让图像的灰度直方图尽可能平稳。OpenCV 提供了一个简单好用的均衡化函数:
cv2 .equalizeHist(gray, gray)
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。在一个完全均衡化的直方图中,图像中包含的像素数量是相等的,也就是说,像素大于128的有一半像素值小于128的也有一半,像素值小于64的是小于128的一半,以此类推。
提高对比度和增加亮度使用的OpenCV 函数为:
new_img =cv2.addWeighted(img, c, new_img, 1-c, b)
其中c是对比度倍数,b是亮度增加数
图像对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的量化级数,即一幅图像灰度反差的大小。差异范围越大代表对比度越大,差异范围越小代表对比度越小。图像亮度是指画面的明亮程度,通常用像素值来表示
二、Haar 特征分类器
利用 OpenCV 自带的 xml文件可以实时检测摄像头中人脸的 Haar 特征或 LBP 特征。它们描述不同的局部信息,Haar描述的是图像在局部范围内像素值明暗变换信息,LBP描述的是图像在局部范围内对应的纹理信息,Haar与LBP区别如下:
1)Haar 特征是浮点数计算,LBP特征是整数计算
2)LBP训练需要的样本数量比Haar大
3)LBP 的速度一般比 Haar 快
4)使用同样的样本,Haar训练出来的检测结果比LBP准确
5)扩大LBP的样本数据可达到 Haar的训练效果
Haar 特征分类器是一个 xm1文件,文件描述了检测物体的Haar 特征值,Haar 分类器雷要通过大量的数据来训练。Haar特征包括三类:边缘特征、线性特征、中心特征和对角线特征,它们组合成特征模板。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况,如脸部的一些特征能由矩形特征进行描述,如眼睛要比脸颊颜色要深、鼻梁两侧比鼻梁颜色要深、嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构(如边缘、线段)敏感,所以只能描述特定走向(水平、垂直、对角)的结构
三、人脸检测程序
对图像进行人脸特征矩形检测,符合人脸特征的区域会被认定为人脸。在开始人脸检测时,需要加载 Haar 分类器。循环读取人脸的矩形对象列表,获得人脸矩形的坐标和宽高,然后在原图像中画出该矩形框,调用的是OpenCV的rectangle方法,其中矩形框的颜色等是可调整的。putText函数用于在图像上加文字信息(如文字、位置、字体、大小、颜色、粗细等)
在人脸检测中用到的检测函数是detectMultiScaleO,它可以检测出图像中所有的人脸并用向量保存人脸的坐标、大小(用矩形表示),其语法格式为:
objects=cv2.CascadeClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flagsf,[minsizef[,maxsizei]]])
其输入和输出参数如下:
(1)obiects:表示被检测物体的矩形框向量组
(2)image:表示要检测的输人图像,一般为灰度图像,可加快检测速度
(3)scaleFactor:表示在前后两次扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗日依次扩大 10%
(4)minNeighbors:表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于min_neighbors-1,就会被排除。如果 min_neighbor为0,则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上
(5)flags:使用默认值或使用CVHAAR_DOCANNYPRUNING。如果设置为CVHAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,这些区域通常不会是人脸所在区域
minSize为目标的最小尺寸,用来限制得到的目标区域的范围
maxSize 为目标的最大尺寸,用来限制得到的目标区域的范围
经过适当调整后,三个参数可以用来排除检测结果中的干扰项
# 使用 Haar 分类器对人脸进行检测,并检测出眼睛和是否微笑。程序如下:
import cv2
facehaar ='C:/ProgramData/anaconda3/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml'
eyehaar ='C:/Programata/anaconda3/ib/site-packages/cv2/data/haarcascade_eye.xml'
smilehaar ='C:/ProgramData/anaconda3 /.ib/site-packages /cv2 /data /haarcaecade_smile.xml'
face_detector =cv2.CascadeClassifier(facehaar)# 人脸分类器
eye_detector =cv2.CascadeClassifier(eyehaar)# 眼睛分类器
smile_detector =cv2.CascadeClassifier(smilehaar)# 微笑分类器
image = cv2.imread('d:/pics/face_smile1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.equalizeHist(gray,gray)
cv2.imshow("Origin_img",image)
faces = face_detector.detectMultiScale(gray,1.15,5)
print("face", faces)
for x,y,w,h in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow("face rect",image)
#把人脸单独拿出来检测
face_img = gray[y:y+h, x:w+x]
cv2.imshow("face img",face_img)
eyes = eye_detector.detectMultiScale(face_img,1.3,5,0,(40,40))
for ex,ey,ew,eh in eyes:
cv2.rectangle(image,(x+ex,y+ey),(x+ex+ew,y+ey+eh),(255,0,0),2)
#cv2 imshow("eyes rect",image)
smile = smile_detector.detectMultiScale(face_img,1.16,25,0,(25,25))
if(len(smile)>= 0):
print("检测到微笑")
cv2.putText(image,'Smile',(x,y-20),3,1.3,(0,255,0),2)
cv2.imshow("Result",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
程序运行的结果如图所示