利用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>
结果:
下图就是使用上述代码对内置摄像头的视频流进行人脸检測的结果图像:

注意复制分类器文件 haarcascade_frontalface_alt.xml 和haarcascade_eye_tree_eyeglasses.xml 到你的当前文件夹下. 他们在OpenCV安装文件夹
opencv/data/haarcascades 里面.
下图是使用分类器文件 lbpcascade_frontalface.xml (LBP特征训练的) 进行的检測结果. 对于双眼的检測依然使用刚才使用过的分类器.
參考:
利用opencv中的级联分类器进行人脸检測-opencv学习(1)的更多相关文章
- OpenCv 人脸检測的学习
近期公司要组织开发分享,可是自己还是新手真的不知道分享啥了,然后看了看前段时间研究过OpenCv,那么就分享他把. openCv就不介绍了,说下人脸检測.事实上是通过openCv里边已经训练好的xml ...
- 使用级联分类器实现人脸检测(OpenCV自带的数据)
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...
- Viola-Jones人脸检測
OpenCV中有一个基于树的技术:Haar分类器,它建立了boost筛选式级联. 它能够识别出人脸和其它刚性物体. 对于检測"基本刚性"的物体(脸,汽车,自行车,人体等)这类识别任 ...
- OpenCV中基于Haar特征和级联分类器的人脸检测
使用机器学习的方法进行人脸检测的第一步需要训练人脸分类器,这是一个耗时耗力的过程,需要收集大量的正负样本,并且样本质量的好坏对结果影响巨大,如果样本没有处理好,再优秀的机器学习分类算法都是零. 今年3 ...
- 【从零学习openCV】IOS7下的人脸检測
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
- OpenCV人脸检測(完整源代码+思路)
本博文IDE为vs2013 OpenCV2.49 话不多说,先看视频演示(20S演示): 例如以下: https://v.youku.com/v_show/id_XMjYzMzkxMTYyMA==.h ...
- OpenFace库(Tadas Baltrusaitis)中基于Haar Cascade Classifiers进行人脸检測的測试代码
Tadas Baltrusaitis的OpenFace是一个开源的面部行为分析工具.它的源代码能够从 https://github.com/TadasBaltrusaitis/OpenFace 下载. ...
- 基于QT和OpenCV的人脸检測识别系统(1)
人脸识别分为两大步骤 1.人脸检測 这个是首要实现的.你得实现人脸显示的时候把人脸框出来,当然算法非常多,另一些人眼检測鼻子检測什么的 主要用的是这个 const char *faceCascadeF ...
- Matlab人脸检測方法(Face Parts Detection)具体解释
今天同学让我帮忙制作一个人脸表情识别的样本库,当中主要是对人脸进行裁剪,这里用到了一个相对较新的Matlab人脸检測方法Face Parts Detection.网上百度了一下发现关于Matlab人脸 ...
随机推荐
- python2.7_1.2_打印设备名和IPv4地址
代码如下: # -*- coding: utf-8 -*- import socket def print_machine_info(): host_name = socket.gethostname ...
- NET Core 环境搭建和命令行CLI入门
NET Core 环境搭建和命令行CLI入门 2016年6月27日.NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布,社区里涌现了很多文章,我也计划写个系列文 ...
- jQuery入门学习贴
先引一下阮一峰大牛翻译的书<软件随想录>中的一句话: “ joel认为,软件开发,最缺的是天才.而我认为,最缺的是全才.什么“全”:全面.全局.全心全意.全力以赴. ” 最近再学习jQue ...
- 返回hash 类型的json
else{ $hash{$phone}="没有找到需要的验证码信息"; $c->render(json => \%hash );
- cocos2dx进阶学习之CCScene
继承关系 CCScene -> CCNode -> CCObject CCScene抽象了一个场景的概念,类似舞台的一幕 函数 static CCScene *create(void); ...
- opencv是什么
OpenCV是一个用于图像处理.分析.机器视觉方面的开源函数库. 不管你是做科学研究,还是商业应用,opencv都能够作为你理想的工具库,由于,对于这两者,它全然是免费的.该库採用C及C+ ...
- ASP.NET站点安全
<configuration> <appSettings/> <connectionStrings> <add name="MyBookShop&q ...
- A. Case of the Zeros and Ones----解题报告
A. Case of the Zeros and Ones Description Andrewid the Android is a galaxy-famous detective. In his ...
- C语言,单链表操作(增删改查)(version 0.1)
这天要面试,提前把链表操作重新写了一遍.备份一下,以备不时之需. 希望有人能看到这篇代码,并指正. // File Name : list.h #include "stdafx.h" ...
- ubuntu卸载vmware
下面方法摘抄网上方法,经过证实好使 lsmod——显示已载入系统的模块 ps aux : 显示其他用户启动的进程(a) 查看系统中属于自己的进程(x) 启动这个进程的用户和它启动的 ...