OpenCV学习笔记-人脸检测
一、人脸检测方法
在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Harr特征和LBP特征。具体的介绍参考:图像特征提取三大法宝:HOG特征,LBP特征,Haar特征
在OpenCV中,使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV-master的data文件夹下。OpenCV-master的下载资源在连接:OpenCV-master
上图中文件夹的名字‘harrcascades’,'hogcascades','lbpcascades'分别表示通过‘harr','hog','lbp'三种不同的特征而训练出来的分类器:即各文件及中的文件。'haar'特征主要用于人脸检测,'hog'特征主要用于行人检测,'lbp'特征主要用于人脸识别。
在OpenCV里,我们用CascadeClassifier()类加载分类器,实现人脸检测主要依赖于detectMulitiScale()。
face_detect = cv.CascadeClassifier('E:/BaiduNetdiskDownload/opencv-master/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml')
detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None)
image: 待检测图像,一般为灰度图
scaleFactor: 表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口依次扩大10%。
minNeighbors: 表示构成检测目标的相邻矩形的最小个数(默认为3个)。我们可以通过设置矩形个数调整检测准确率,如果检测到的错误目标比较多,我们增大相邻矩形个数,如果检测不到目标,或者很少,我们可以减少相邻矩形的个数,放大尺度。
flags: 一般不设置,如果使用,只能设置为CV_HAAR_DO_CANNY_PRUNING,函数将会使用Canny边缘检测来排除边缘过多或者过少的区域,因此这些区域通常不会是人脸所在区域。
minSize、maxSize: 用来限制得到的目标区域范围。
二、代码实现
检测图片中的 人脸和眼睛:
现在我们在图像中检测面部。如果检测到面部,它会返回面部所在的矩形区域rect(x, y, w, h)。一旦我们获得这个位置,我们可以穿件一个ROI并在其中进行眼部检测。
def face_detect_demo(img): gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('E:/BaiduNetdiskDownload/opencv-master/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml') eye_cascade = cv.CascadeClassifier('E:/BaiduNetdiskDownload/opencv-master/opencv-master/data/haarcascades/haarcascade_eye.xml') faces = face_detect.detectMultiScale(gray, 1.1, 5) for x, y, w, h in faces: cv.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2) 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, 10) for (ex, ey, ew, eh) in eyes: cv.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) cv.imshow('result', img)
结果如下:
检测视频中的人脸:
def video_face_cascade(): capture = cv.VideoCapture(0) cv.namedWindow('img', cv.WINDOW_AUTOSIZE) while (True): ret, frame = capture.read() #因为我们读取的视频是反的 所以执行翻转操作 frame = cv.flip(frame, 1) face_detect_demo(frame) c = cv.waitKey(10) if c == 27: break
flip()函数可以实现图像的垂直、水平和同时垂直水平变换:
filpCode: =0 图像向下翻转;>0 图像向右翻转;<0 图像同时向下向右翻转
效果如下: