OpenCV---人脸检测
一:相关依赖文件下载
https://github.com/opencv/opencv
二:实现步骤(图片检测)
(一)读取图片
image= cv.imread("./d.png") #读取图片
(二)灰度转换
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #在灰度图像基础上实现的
(三)获取人脸识别训练数据
face_detector = cv.CascadeClassifier("./haarcascade_frontalface_alt_tree.xml") #级联检测器获取文件
这个xml文件,就是opencv在GitHub上共享出来的具有普适的训练好的数据。我们可以直接的拿来使用
(四)探测人脸,获取相关数据
faces = face_detector.detectMultiScale(gray,1.1,2)
#第一个参数是灰度图像
#第二个参数是尺度变换,就是向上或者向下每次是原来的多少倍,这里是1.02倍
#第三个参数是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要适当降低
(五)根据相关数据在原图像上画出人脸位置
for x,y,w,h in faces: cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) cv.imshow("face_detection",image)
(六)全部代码
import cv2 as cv import numpy as np def face_detect_demo(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #在灰度图像基础上实现的 face_detector = cv.CascadeClassifier("./haarcascade_frontalface_alt_tree.xml") #级联检测器获取文件 faces = face_detector.detectMultiScale(gray,1.1,2) #在多个尺度空间上进行人脸检测 #第一个参数是灰度图像 #第二个参数是尺度变换,就是向上或者向下每次是原来的多少倍,这里是1.02倍 #第三个参数是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要试单降低 for x,y,w,h in faces: cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) cv.imshow("face_detection",image) src = cv.imread("./d.png") #读取图片 cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应 cv.imshow("input image",src) #通过名字将图像和窗口联系 face_detect_demo(src) cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作 cv.destroyAllWindows() #销毁所有窗口
三:实现视频检测人脸
步骤相同,我们只需要将视频中每一帧图像进行处理,调用上面的图像人脸检测即可
import cv2 as cv import numpy as np def face_detect_demo(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #在灰度图像基础上实现的 face_detector = cv.CascadeClassifier("./haarcascade_frontalface_default.xml") #级联检测器获取文件 faces = face_detector.detectMultiScale(gray,1.1,2) #在多个尺度空间上进行人脸检测 #第一个参数是灰度图像 #第二个参数是尺度变换,就是向上或者向下每次是原来的多少倍,这里是1.02倍 #第三个参数是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要试单降低 for x,y,w,h in faces: cv.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2) cv.imshow("face_detection",image) def video_face_detect(): capture = cv.VideoCapture(0) while True: ret,frame = capture.read() #frame是每一帧图像,ret是返回值,为0是表示图像读取完毕 frame = cv.flip(frame,1) if ret == False: break face_detect_demo(frame) c = cv.waitKey(10) if c == 27: break video_face_detect() cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作 cv.destroyAllWindows() #销毁所有窗口
相关知识补充:
(一)CascadeClassifier级联分类器
是Opencv中做人脸检测的时候的一个级联分类器
有两种选择:一是使用老版本的CvHaarClassifierCascade函数,一是使用新版本的CascadeClassifier类。
老版本的分类器只支持类Haar特征,而新版本的分类器既可以使用Haar,也可以使用LBP特征。
基本原理
xml中存放的是训练后的特征池,特征size大小根据训练时的参数而定,检测的时候可以简单理解为就是将每个固定size特征(检测窗口)与输入图像的同样大小区域比较,如果匹配那么就记录这个矩形区域的位置,然后滑动窗口,检测图像的另一个区域,重复操作。
由于输入的图像中特征大小不定,比如在输入图像中眼睛是50x50的区域,而训练时的是25x25,那么只有当输入图像缩小到一半的时候,才能匹配上,所以这里还有一个逐步缩小图像,也就是制作图像金字塔的流程。
cascPath = "./haarcascade_frontalface_default.xml"
cv2.CascadeClassifier(cascPath) #构造方法加载入xml特征文件
detectMultiScale方法
faces = faceCascade.detectMultiScale(gray,1.1,2,30)
def detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None): # real signature unknown; restored from __doc__
#第一个参数image:是灰度图像
#第二个参数scaleFactor:是尺度变换,就是向上或者向下每次是原来的多少倍,这里是1.02倍
#第三个参数minNeighbors:是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要适当降低
#第四个参数flags:
CASCADE_DO_CANNY_PRUNING=1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域
CASCADE_SCALE_IMAGE=2, 正常比例检测 CASCADE_FIND_BIGGEST_OBJECT=4, 只检测最大的物体
CASCADE_DO_ROUGH_SEARCH=8 初略的检测
#最后两个参数用来限制得到的目标区域的范围
注意:
flags对于新的分类器没有用
设置minNeighbors:是在人脸附近进行指定次数的检测,获取最准确的范围,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要适当降低