这两天学习了人脸识别,看了学长写的代码,边看边码边理解搞完了一边,再又是本身靠着理解和记忆硬码了一边,感受仍是很生疏,就只能来写个随笔加深一下印象了。html
关于人脸识别,首先须要了解的是级联分类器CascadeClassifier,它能够它既能够是Haar特征,也能够是LBP特征的分类器,能够加载OpenCV所提供的库当中的.xml文件,文件存放在anaconda\pkgs\libopencv-3.4.1-h875b8b8_3\Library\etc的haarcascades文件夹中,包含了许多个.xml文件,分别有不一样的用途。而在使用级联分类器进行人脸检测时,须要调用 .detectMultiScale 方法,其中的参数为ide
img:传入图像
object:被检测的物体的矩形框向量组
scaleFactor:表示先后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口扩大10%
minNegihbors,表示构成检测目标的相邻矩形的最小个数(默认为3个)
flags:要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,若是设置为CV_HAAR_DO_CANNY_PRUNING,那么函数会使用Canny边缘检测来排除边缘过多或者过少的区域,这些一般不会是人脸所在区域
minSize和maxSize:用来限制获得的目标区域的范围函数
其输出为一个vector矩阵,保存人脸的坐标和大小,须要注意的是,传入的图像必须为灰度图像,由于级联分类器检测须要接收灰度图像。学习
1.首先是静态图片中的人脸检测spa
这部分并不算难,看着注释应该也能够看懂,就很少作解释。code
def StaticDetect(filename): ''' 静态图像的人脸检测 ''' #建立一个级联分类器,加载一个 .xml文件,它既能够是Haar特征,也能够是LBP特征的分类器 face_casecade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml') #加载图像 img=cv2.imread(filename,cv2.IMREAD_COLOR) #转换为灰度图像 gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ''' detectMultiScale进行人脸检测 传入参数为args: img:传入图像 object:被检测的物体的矩形框向量组 scaleFactor:表示先后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口扩大10% minNegihbors,表示构成检测目标的相邻矩形的最小个数(默认为3个) flags:要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,若是设置为CV_HAAR_DO_CANNY_PRUNING,那么函数会使用Canny边缘检测来排除边缘过多或者过少的区域,这些一般不会是人脸所在区域 minSize和maxSize:用来限制获得的目标区域的范围 输出为:vector保存各我的脸的坐标、大小(用矩形表示) ''' faces=face_casecade.detectMultiScale(gray_img,1.2,5) for (x,y,w,h) in faces: #在原图上绘制矩形 img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) cv2.namedWindow('Face_Detected') cv2.imshow('Face_Detected',img) cv2.waitKey(0) cv2.destroyAllWindows()
检测的结果以下图,图片是我从网上随便找的一张图,若是有任何侵犯的地方,请及时联系我,会即刻删除。咱们能够发现结果并非太好,有许多漏检,因为是初学则不作过多改正尝试,能够尝试修改级联分类器中的文件以及搜索窗口比例系数来改变检测准确度。视频
2.动态人脸检测xml
这一部分采用了两个级联分类器,一个检测面部,一个检测眼睛,须要注意的是,眼睛的检测是在人脸检测后再进行检测,即先从大的人脸开始画出矩形再到眼睛画出的矩形。检测眼睛时能够把眼镜摘下,会准确不少。htm
def Video_detected(): ''' 从视频中进行人脸检测 ''' #建立一个级联分类器,家在一个 .xml文件它既能够是Haar特征,也能够是LBP特征的分类器 face_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml') eye_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_eye.xml') #打开摄像头 camera=cv2.VideoCapture(0) cv2.namedWindow('Dynamic') while(True): #读取一帧图像 ret ret,frame=camera.read() #判断图片读取是否成功 if ret: gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #人脸检测 faces=face_cascade.detectMultiScale(gray_img,1.3,5) for (x,y,w,h) in faces: #在原图上绘制矩形 cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #蓝色 roi_gray=gray_img[y:y+h,x:x+w] #眼睛检测 eyes=eye_cascade.detectMultiScale(roi_gray,1.1,5,0,(40,40)) for (ex,ey,ew,eh) in eyes: cv2.rectangle(frame,(ex+x,ey+y),(ex+x+ew,ey+y+eh),(0,255,0),2) #绿色 cv2.imshow('Dynamic',frame) #若是按下q键则退出 if cv2.waitKey(10) & 0xff==ord('q'): break camera.release() cv2.destroyAllWindows()
检测结果以下图,能够发现对象很少的时候,人脸检测仍是挺准确的,尝试事后,动态状况下多我的脸也是能够检测出来的。咱们能够发现,在眼睛的检测中多了几个参数,这些参数是因为眼睛比较小,而且有鼻子等形成的阴影可能会产生假阳性,所以经过限制检测的眼睛大小为40*40能够去除假阳性的影响。后续能够尝试不一样的参数的检测精度,这里就很少作描述。 对象
这里附上原博客的链接:https://www.cnblogs.com/zyly/p/9410563.html
2018.10.28