图像处理项目——人脸检测—图片
人脸检测
*开发环境为visual studio2010
*使用的是opencv中的Haart特征分类器,harr Cascades
*检测对象为人脸照片
一:主要步骤
1.加载分类器,将人脸检测分类器和笑脸检测分类器放在项目目录中去
2.调用detecMutiScale()函数检测,对函数中相关的参数进行修改调整,
是检测的结果更加精确
3.把检测到的人脸用矩形画出来
opencv中用来做目标检测的级联分类器的一个
类,其结构如下: The constructor for the cv::CascadeClassifier object is: cv::CascadeClassifier::CascadeClassifier( const String& filename ); 这个构造函数只需要一个参数,即存储xml文件的名字,此外还有一个默认参数,即是使用 load()成员加载级联。
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用来限制得到的目标区域的范围。
二 :代码
/*************************************************************** 主要步骤: 1.将人脸检测分类器放在项目目录中去,加载Haart特征分类器(描述人体各个部位的Haar特征值,包括人脸、眼睛、嘴唇等) 2.调用detecMutiScale()函数检测,对函数中相关的参数进行修改调整 3.把检测到的人脸用矩形画出来 ****************************************************************/ #include "opencv2/objdetect.hpp" #include "opencv2/videoio.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; using namespace cv; String Path_faceCascade; //定义xml文件路径,训练模型以xml文件格式保存 CascadeClassifier faceCascade; //定义人脸分类器,opencv中的harr Cascades int main() { int faceNeighborsMax = 10; //10次 int neighborStep = 1; Path_faceCascade = "models/haarcascade_frontalface_default.xml"; //导入xml文件,给Path_faceCascade if( !faceCascade.load( Path_faceCascade ) ) { printf("--(!)Error loading face cascade\n"); return -1; } std::vector<Rect> faces; //数组容器类,尖括号表示里面的Rect是实际类,整体定义了faces对象是一个Rect数组 Mat srcImage = imread("a4.jpg"); //读取照片 Mat grayImage, dstImage; cvtColor(srcImage, grayImage, COLOR_BGR2GRAY); //frame图片灰度化,结果给frameGray //检测人脸 for (int n = 0; n < faceNeighborsMax; n = n + neighborStep) { dstImage = srcImage.clone(); //调用detectMultiScale函数,检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示)到faces faceCascade.detectMultiScale( grayImage, faces, 1.2, n); printf("Neighbors = %d,检测到人脸个数:%d\n", n,faces.size()); for ( size_t i = 0; i < faces.size(); i++ ) { int x = faces[i].x; int y = faces[i].y; int w = faces[i].width; int h = faces[i].height; //在脸的部分画圆 Point center; int radius; center.x = cvRound((faces[i].x + faces[i].width * 0.5)); center.y = cvRound((faces[i].y + faces[i].height * 0.5)); radius = cvRound((faces[i].width + faces[i].height) * 0.25); circle(dstImage, center, radius, Scalar(255,0,0), 2); //rectangle(dstImage, Point(x, y), Point(x + w, y + h), Scalar(0,0,255),3, 4); //这个函数画出来的蓝色“矩形” } putText(dstImage, format(" Neighbors = %d",n), Point(20, 40), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 4); imshow( "Face Detection Demo", dstImage ); int k = waitKey(500); //按"q"退出 if(k == 113){ destroyAllWindows(); break; } } system("pause"); }
三 : 检测结果
![](https://img2018.cnblogs.com/blog/1463512/201903/1463512-20190313135855419-1768257446.png)
标签:
杂谈 |
opencv人脸检测的例程中,该参数被设置为3.检测的结果如下:
![cvHaarDetectObjects函数中的min_neighbors参数解释]()
将参数改为2和1时,检测的效果上依然是两个矩形窗口。
min neighbors
Minimum number (minus 1) of neighbor rectangles that makes up an object.
All the groups of a smaller number of rectangles than min neighbors-1 are rejected. If
min neighbors is 0, the function does not any grouping at all and returns all the detected
candidate rectangles, which may be useful if the user wants to apply a customized grouping
procedure
大致意思是,对于groups of rectangles 小于 min_neighbors - 1 就不认为是人脸。
将参数设为0,将能看到所有 detected candidate rectangles。结果如下:
![cvHaarDetectObjects函数中的min_neighbors参数解释]()
从以上的实验可以看出(即图像上方的两个较小的retangles),当groups of rectangles当且只有一个时,是不会检测为人脸的。
参数为0时,一共检测出了90个rectangles。
可以看到帽子的毛绒装饰处检测出了4个rectangles。
胳膊处2个rectangles,图像上方左右各一个rectangles。
其他82个rectangles集中在lena的面部区域。
那么怎么定义group of rectangles呢?胳膊处的两个rectangles不能分为一个group。
当min_neighbors = 4时,检测的结果为:
![cvHaarDetectObjects函数中的min_neighbors参数解释]()
当min_neighbors = 82 -3 时,检测区域消失。
将参数改为2和1时,检测的效果上依然是两个矩形窗口。
min neighbors
Minimum number (minus 1) of neighbor rectangles that makes up an object.
All the groups of a smaller number of rectangles than min neighbors-1 are rejected. If
min neighbors is 0, the function does not any grouping at all and returns all the detected
candidate rectangles, which may be useful if the user wants to apply a customized grouping
procedure
大致意思是,对于groups of rectangles 小于 min_neighbors - 1 就不认为是人脸。
将参数设为0,将能看到所有 detected candidate rectangles。结果如下:
从以上的实验可以看出(即图像上方的两个较小的retangles),当groups of rectangles当且只有一个时,是不会检测为人脸的。
参数为0时,一共检测出了90个rectangles。
可以看到帽子的毛绒装饰处检测出了4个rectangles。
胳膊处2个rectangles,图像上方左右各一个rectangles。
其他82个rectangles集中在lena的面部区域。
那么怎么定义group of rectangles呢?胳膊处的两个rectangles不能分为一个group。
当min_neighbors = 4时,检测的结果为:
当min_neighbors = 82 -3 时,检测区域消失。
萍水相逢逢萍水,浮萍之水水浮萍!