利用opencv中的级联分类器进行人脸检測-opencv学习(1)

OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification)。注意,新版本号的C++接口除了Haar特征以外也能够使用LBP特征。

先介绍一下相关的结构,级联分类器的计算特征值的基础类FeatureEvaluator,功能包含读操作read、复制clone、获得特征类型getFeatureType,分配图片分配窗体的操作setImage、setWindow,计算有序特征calcOrd,计算绝对特征calcCat,创建分类器特征的结构create函数。级联分类器类CascadeClassifier。目标级联矩形的分组函数groupRectangles。

接下来,我尝试使用CascadeClassifier这个级联分类器类检測视频流中的目标(haar支持的目标有人脸、人眼、嘴、鼻、身体。这里尝试比較成熟的人脸和眼镜)。用load函数载入XML分类器文件(眼下提供的分类器包含Haar分类器和LBP分类器(LBP分类器数据较少))详细过程例如以下:

这里再补充一点:后来我又进行了一些实验,对正面人脸分类器进行了实验,总共同拥有4个,alt、alt2、alt_tree、default。对照下来发现alt和alt2的效果比較好,alt_tree耗时较长,default是一个轻量级的,常常出现误检測。所以还是推荐大家使用haarcascade_frontalface_atl.xml和haarcascade_frontalface_atl2.xml。

1)载入级联分类器

调用CascadeClassifier类成员函数load实现,代码为:

<span style="font-size:18px;">CascadeClassifier face_cascade;
face_cascade.load("haarcascade_frontalface_alt.xml");</span>

2)读取视频流

3)对每一帧使用该分类器

这里先将图像变成灰度图,对它应用直方图均衡化,做一些预处理的工作。接下来检測人脸,调用detectMultiScale函数,该函数在输入图像的不同尺度中检測物体,參数image为输入的灰度图像,objects为得到被检測物体的矩形框向量组,scaleFactor为每个图像尺度中的尺度參数,默认值为1.1,minNeighbors參数为每个级联矩形应该保留的邻近个数(没能理解这个參数,-_-|||),默觉得3,flags对于新的分类器没实用(但眼下的haar分类器都是旧版的,CV_HAAR_DO_CANNY_PRUNING利用Canny边缘检測器来排除一些边缘非常少或者非常多的图像区域,CV_HAAR_SCALE_IMAGE就是按比例正常检測,CV_HAAR_FIND_BIGGEST_OBJECT仅仅检測最大的物体,CV_HAAR_DO_ROUGH_SEARCH仅仅做初略检測),默觉得0.minSize和maxSize用来限制得到的目标区域的范围。这里调用的代码例如以下:

<span style="font-size:18px;">face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );</span>

代码例如以下

<span style="font-size:18px;"> #include "opencv2/objdetect/objdetect.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/imgproc/imgproc.hpp"

 #include <iostream>
 #include <stdio.h>

 using namespace std;
 using namespace cv;

 /** 函数声明 */
 void detectAndDisplay( Mat frame );

 /** 全局变量 */
 string face_cascade_name = "haarcascade_frontalface_alt.xml";
 string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
 CascadeClassifier face_cascade;
 CascadeClassifier eyes_cascade;
 string window_name = "Capture - Face detection";
 RNG rng(12345);

 /** @主函数 */
 int main( int argc, const char** argv )
 {
   CvCapture* capture;
   Mat frame;

   //-- 1. 载入级联分类器文件
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
   if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };

   //-- 2. 打开内置摄像头视频流
   capture = cvCaptureFromCAM( -1 );
   if( capture )
   {
     while( true )
     {
   frame = cvQueryFrame( capture );

   //-- 3. 对当前帧使用分类器进行检測
       if( !frame.empty() )
       { detectAndDisplay( frame ); }
       else
       { printf(" --(!) No captured frame -- Break!"); break; }

       int c = waitKey(10);
       if( (char)c == 'c' ) { break; }
      }
   }
   return 0;
 }

/** @函数 detectAndDisplay */
void detectAndDisplay( Mat frame )
{
  std::vector<Rect> faces;
  Mat frame_gray;

  cvtColor( frame, frame_gray, CV_BGR2GRAY );
  equalizeHist( frame_gray, frame_gray );

  //-- 多尺寸检測人脸
  face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

  for( int i = 0; i < faces.size(); i++ )
  {
    Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
    ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

    Mat faceROI = frame_gray( faces[i] );
    std::vector<Rect> eyes;

    //-- 在每张人脸上检測双眼
    eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );

    for( int j = 0; j < eyes.size(); j++ )
     {
       Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
       int radius = cvRound( (eyes[j].width + eyes[i].height)*0.25 );
       circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
     }
  }
  //-- 显示结果图像
  imshow( window_name, frame );
 }
</span>

结果:

  1. 下图就是使用上述代码对内置摄像头的视频流进行人脸检測的结果图像:

    注意复制分类器文件 haarcascade_frontalface_alt.xmlhaarcascade_eye_tree_eyeglasses.xml 到你的当前文件夹下. 他们在OpenCV安装文件夹
    opencv/data/haarcascades 里面.

下图是使用分类器文件 lbpcascade_frontalface.xml (LBP特征训练的) 进行的检測结果. 对于双眼的检測依然使用刚才使用过的分类器.

參考:

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html

时间: 2024-10-13 23:44:05

利用opencv中的级联分类器进行人脸检測-opencv学习(1)的相关文章

利用opencv中的级联分类器进行人脸检测-opencv学习(1)

OpenCV支持的目标检测的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本的C++接口除了Haar特征以外也可以使用LBP特征. 先介绍一下相关的结构,级联分类器的计算特征值的基础类FeatureEvaluator,功能包括读操作read.复制clone.获得特征类型getFeatureType,分配图片分配窗口的操作setImage.setWindow,计算有序特征calcOrd,计算绝对特征calcC

使用级联分类器实现人脸检测(OpenCV自带的数据)

1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 4 using namespace cv; 5 using namespace std; 6 7 int main(int argc, char** argv) { 8 String cascadeFilePath = "F:/CMake_bulid/install/etc/haarcascades/haarcascade_frontalface_alt.xml

人脸检測中几种框框大小的选择~

人脸检測应用极为广泛,内部细节也偏多,尤其是涉及到几种类型的框,这几种框的大小之前有着千丝万缕的联系,对检測性能的好坏影响程度大小不一.本篇文章基于自己在人脸检測方面的经验,说说对这些框之间关系的一些理解. 如今大部分人脸检測效果都已adaboost+LBP(各种改进)的方式实现,adaboost由N个强分类器组成,每一个强分类器由M个弱分类器组成,而每一个弱分类器事实上就是一个特征. 本文以LBP特征为例,人脸检測共涉及到例如以下几类框: 1. LBP特征矩形框大小(极为重要) 2. 检測框大

OpenCV人脸检測(完整源代码+思路)

本博文IDE为vs2013 OpenCV2.49 话不多说,先看视频演示(20S演示): 例如以下: https://v.youku.com/v_show/id_XMjYzMzkxMTYyMA==.html?spm=a2h0w.8278793.2736843.4#paction 程序截图例如以下: 怎样来用OpenCV来实现能. 以下给出OpenCV实现人脸检測的一般步骤: 1.载入人脸检測器 2.开启摄像头 3.对图片进行灰度处理(事实上能够不处理,上图中原图的标题栏就是未进行灰度处理进行的检

基于QT和OpenCV的人脸检測识别系统(1)

人脸识别分为两大步骤 1.人脸检測 这个是首要实现的.你得实现人脸显示的时候把人脸框出来,当然算法非常多,另一些人眼检測鼻子检測什么的 主要用的是这个 const char *faceCascadeFilename = "haarcascade_frontalface_alt.xml"; detect_and_draw(IplImageBuffer,storage,cascade); 这个函数就是检測人脸的并画框效果例如以下 watermark/2/text/aHR0cDovL2Jsb

【OpenCV新手教程之十七】OpenCV重映射 &amp;amp; SURF特征点检測合辑

本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本号: 2.4.9 本篇文章中,我们一起探讨了OpenCV

人脸检測流程及正负样本下载

人脸检測做训练当然能够用OpenCV训练好的xml.可是岂止于此.我们也要动手做! ~ 首先是样本的选取. 样本的选取非常重要.找了非常久才发现几个靠谱的. 人脸样本:http://www.vision.caltech.edu/Image_Datasets/Caltech_10K_WebFaces/   网上抓取的逾10,000个人脸样本 http://vis-www.cs.umass.edu/lfw/  13.000个人脸 负样本(背景环境衣服动物乱七八糟的):http://groups.cs

实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測

在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact(b2Contact* contact).两个物体開始接触时会响应,但仅仅调用一次. virtual void EndContact(b2Contact* contact).分离时响应. 但仅仅调用一次. virtual void PreSolve(b2Contact* contact, const

《Master Opencv...读书笔记》非刚性人脸跟踪 IV (终)

一.我们目前为止拥有什么 为了有一个连续完整的认识,在介绍最后一节前,先梳理下至今我们训练了哪些数据特征,并且训练它们的目的是什么. 1.      ft_data:利用手工标注工具,获取最原始的样本训练数据,包括以下内容: 图像名称集合imnames:表明在哪幅图像上标注特征点: 二维坐标集合points:手工标准点,后续更高级别特征均围绕这些特征点展开: 对称坐标索引集合symmetry:标注样本图像的镜像图像上的特征点,扩大样本库: 连接索引集合connections:描述手工标注的人脸特