OpenCV 实践——人脸检测与人脸图像提取
概述
详细
概述
人脸对比是现在比较常用的功能,比如出租车司机人脸与司机驾照照片对比,门禁系统中进入者的人脸与人脸库中的人脸进行对比。要实现人脸对比,首先要实现的是人脸检测,在摄像头拍摄到的一张图片中,正确的检测到人脸的位置,并且将人脸提取出来。考虑到免费开源,OpenCV 就可以很好的实现这个功能。
实现原理
Haar特征分类器介绍:
Haar特征分类器就是一个XML文件,该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。
Haar特征分类器存放目录:OpenCV安装目录中的\data\ haarcascades目录下,opencv2.4.9版本下的Haar特征分类器如下:
haarcascade_eye.xml haarcascade_eye_tree_eyeglasses.xml haarcascade_frontalface_alt.xml haarcascade_frontalface_alt_tree.xml haarcascade_frontalface_alt2.xml haarcascade_frontalface_default.xml haarcascade_fullbody.xml haarcascade_lefteye_2splits.xml haarcascade_lowerbody.xml haarcascade_mcs_eyepair_big.xml haarcascade_mcs_eyepair_small.xml haarcascade_mcs_leftear.xml haarcascade_mcs_lefteye.xml haarcascade_mcs_mouth.xml haarcascade_mcs_nose.xml haarcascade_mcs_rightear.xml haarcascade_mcs_righteye.xml haarcascade_mcs_upperbody.xml haarcascade_profileface.xml haarcascade_righteye_2splits.xml haarcascade_smile.xml haarcascade_upperbody.xml
detectMultiScale函数详解:
cvHaarDetectObjects是opencv1中的函数,opencv2中人脸检测使用的是 detectMultiScale函数。它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),函数由分类器对象调用:
void detectMultiScale( const Mat& image, CV_OUT vector<Rect>& objects, double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size() );
函数介绍:
参数1:image--待检测图片,一般为灰度图像加快检测速度;
参数2:objects--被检测物体的矩形框向量组;
参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上;
参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域;
参数6、7:minSize和maxSize用来限制得到的目标区域的范围。
前期准备
下载分类器数据:haarcascade_frontalface_default.xml
可到:https://github.com/opencv/opencv/tree/master/data/haarcascades 下载
项目结构
haarcascade_frontalface_default.xml:分类器数据
OpenCV.py :实现文件
实现过程
1.读入分类器数据
cascade = cv.CascadeClassifier("./haarcascade_frontalface_default.xml") ## 读入分类器数据
2.加载图片
sample_image = cv.imread("./cv.png") ## 图片地址
3.利用分类数据筛选人脸
faces = cascade.detectMultiScale(sample_image,scaleFactor=1.1,minNeighbors=5,minSize=(50, 50)) for (x, y, w, h) in faces: cv.rectangle(sample_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
代码片段:
import cv2 as cv cascade = cv.CascadeClassifier("./haarcascade_frontalface_default.xml") ## 读入分类器数据 sample_image = cv.imread("./IMG.jpg") ## 图片地址 faces = cascade.detectMultiScale(sample_image,scaleFactor=1.1,minNeighbors=5,minSize=(50, 50)) for (x, y, w, h) in faces: cv.rectangle(sample_image, (x, y), (x+w, y+h), (0, 255, 0), 2) cv.imwrite("./a.png", sample_image) ## 框出的人脸图片输出到a.png if len(faces) > 0: print("存在" + str(len(faces)) +"张人脸") else: print("不存在人脸")
结果展示
效果: