接着第一课学习,学会了初步的openCV操作,那么什么是感兴趣的呢?早期在各种高端展会和技术交流中,牛逼闪闪的人脸识别觉得是最为吸睛的存在了。那么,虽然我才刚刚接触点opencv的皮毛,但是已经迫不及待的想要上人脸识别了。于是第二课的学习就打算直接人脸识别开干。
当然前期也花了些时间学习Python的编程,对于python有一个体系化的了解了之后才开始。因为虽然有很多开源的代码,但是也得要起码看得懂才行。闲话不多说,直接进入正题。
一、基本知识
人脸识别,首先需要的是对人脸的检测,拿给电脑一幅图像,它得想办法首先找到哪些是人脸,然后才是哪个脸对应的是谁的问题。那么这一课就集中在对于人脸进行检测的实现上面。人脸检测实质上是一个分类问题,是将人脸与图像中的其他物体区分出来。一种办法是自己建立分类器模型,另一种是直接采用opencv自带的分类器。对于入门小白的我,当然首选直接采用opencv的自带分类器。
1、调用自带分类器
opencv的自带人脸分类器,使用的时候是调用opencv训练好的分类器函数,其自带函数可以实现人脸检测、眼睛检测、鼻子、身体、手臂等检测都有。检测函数为detectMultiScale(),分类器存储在opencv的安装文件夹(*\opencv\sources\data\haarcascades)路径中。
调用的方法为:1)加载分类器;2)调用分类器
首先解释下什么是分类器,分类器其实就是高手针对人脸特征建立的分类算法,其中包含了各种分类的参数,能够实现把人脸与图像其他物体分类的二分类算法。
python代码为:
#加载分类器
face_cascade=cv2.CascadeClassifier("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml")
#调用分类器
face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
2、函数参数及返回值解释
在上述函数中gray表示的是要检测的输入的灰度图像,scaleFactor表示每次图像尺寸减小的比例,minNeighbors表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸),minSize为目标的最小尺寸。该函数的返回值是检测到人脸后,框住人脸的矩形框的四个参数值:矩形的 x 和 y 坐标,以及它的高h和宽w。
二、实操及步骤
下面都是干货哦,一步都不能少。开始编程之前,先理理思路,其实与编程无关了,主要是解决问题之前,都得理理思路,想想条件、目标、实现路径等等。那么现在开始了。
首先得要有一张有人脸的图片,这个清晰度还是要较好的,其他要求到是不高;其次,你得要能够会通过python去读取调用图片,然后进行预处理。为啥要预处理,这里有这么个问题。通常情况下,我们的图像数据都是彩色图像,对于同一个像素,包含的数据信息除了特征信息以外,还有色彩空间的信息,但是色彩空间的信息对于我们进行图像特征识别而言却意义不大,因此,为了减少计算量,一般的特征提取算法,都会预先将图像处理为灰度图像,以利于快速计算。再次,预处理后,我们需要调用人脸识别分类器和检测函数,对预处理后的图像进行检测;最后检测到人脸后,我们还要回到彩色图像上面把人脸范围给框出来。以上就是人脸检测的基本思路和流程。详细代码如下:
import cv2
#指定图片的人脸识别然后存储
img = cv2.imread("c:\\lwf.jpg")
color = (0, 255, 0)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#识别人脸的训练数据
face_cascade = cv2.CascadeClassifier("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml")
#识别眼睛的训练数据
eye_cascade = cv2.CascadeClassifier("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml")
#DetectMultiScale 函数是检测物体的通用函数,检测人脸的检测函数
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
if len(faces) > 0: # 大于0则检测到人脸
for faceRect in faces: # 单独框出每一张人脸
x, y, w, h = faceRect
cv2.rectangle(img, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 3) #5控制绿色框的粗细
roi_gray = gray[y:y+h,x:x+w]
roi_color = img[y:y+h,x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray,1.1,1,cv2.CASCADE_SCALE_IMAGE,(2,2))
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
# 写入图像
cv2.imwrite('output.jpg',img)
cv2.imshow("Find Faces!",img)
cv2.waitKey(0)
三、提取人脸检测到的局部图像
由于上面从图形中检测到了人脸,并对人脸以画框的方式进行了标注。为进行识别,下一步将对所有图像样本进行局部人脸图像提取,以利于后续人脸识别计算。思路如下:
和上面代码差不多,只是需要用到cv2.resize这个命令,利用该命令,以同样大小尺寸进行图像大小统一,并进行改变后的图像输出即可。下面的代码使用的尺寸是(92,112)像素。提取出来的图像,则可以用于下一步的图像识别算法了。
#DetectMultiScale 函数是检测物体的通用函数,检测人脸的检测函数
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.6, minNeighbors=3, minSize=(32,32))
if len(faces) > 0: # 大于0则检测到人脸
for faceRect in faces: # 单独框出每一张人脸
x, y, w, h = faceRect
cv2.rectangle(img, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 3) #5控制绿色框的粗细
roi_gray = gray[y:y+h,x:x+w]
roi_color = img[y:y+h,x:x+w]
resizepic=cv2.resize(roi_gray, (92, 112),interpolation=cv2.INTER_CUBIC)
eyes = eye_cascade.detectMultiScale(roi_gray,1.1,1,cv2.CASCADE_SCALE_IMAGE,(2,2))
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
#-------将人脸区域提取出来
cv2.imwrite('30.jpg',resizepic)
cv2.imshow("Find Faces!",resizepic)
k=cv2.waitKey(0)
#----------关闭窗口,退出程序
if k==27:
cv2.destroyAllWindows() #wait for ESC key to exit
elif k == ord('s'):
cv2.imwrite('20.jpg',resizepic)#wait for 's' key to save and exit
cv2.destroyAllWindows()