opencv 人脸检测(c++)(利用级联分类器实现)

级联分类器

分类器: 判别某个事物是否属于某种分类的器件,两种结果:是、否
级联分类器: 可以理解为将N个单类的分类器串联起来。如果一个事物能属于这一系列串联起来的的所有分类器,则最终结果就是 是,若有一项不符,则判定为否
比如人脸,它有很多属性,我们将每个属性做一成个分类器,如果一个模型符合了我们定义的人脸的所有属性,则我们人为这个模型就是一个人脸。那么这些属性是指什么呢? 比如人脸需要有两条眉毛,两只眼睛,一个鼻子,一张嘴,一个大概U形状的下巴或者是轮廓等等

定义

class CV_EXPORTS_W CascadeClassifier
{
public:
    CV_WRAP CascadeClassifier();
     //从文件中加载级联分类器
    CV_WRAP CascadeClassifier(const String& filename);
    ~CascadeClassifier();
    //检测级联分类器是否被加载
    CV_WRAP bool empty() const;
    //从文件中加载级联分类器
    CV_WRAP bool load( const String& filename );
    //从FileStorage节点读取分类器
    CV_WRAP bool read( const FileNode& node );

    /** 检测输入图像中不同大小的对象。检测到的对象以矩形列表的形式返回。
    参数:
    image: 包含检测对象的图像的CV_8U类型矩阵
    objects: 矩形的向量,其中每个矩形包含被检测的对象,矩形可以部分位于原始图像之外
    scaleFactor: 指定在每个图像缩放时的缩放比例
    minNeighbors:指定每个候选矩形需要保留多少个相邻矩形
    flags:含义与函数cvHaarDetectObjects中的旧级联相同。它不用于新的级联
    minSize:对象最小大小,小于该值的对象被忽略。
    maxSize:最大可能的对象大小,大于这个值的对象被忽略

    该函数与TBB库并行
    */
    CV_WRAP void detectMultiScale( InputArray image,
                          CV_OUT std::vector<Rect>& objects,
                          double scaleFactor = 1.1,
                          int minNeighbors = 3, int flags = 0,
                          Size minSize = Size(),
                          Size maxSize = Size() );

    /** 
    detectMultiScale重载函数
    参数:
    image:包含检测对象的图像的CV_8U类型矩阵
    objects: 矩形的向量,其中每个矩形包含被检测的对象,矩形可以部分位于原始图像之外
    numDetections: 对应对象的检测编号向量。一个物体被探测到的次数是相邻的被积极分类的矩形的数量,这些矩形被连接在一起形成物体
    scaleFactor: 指定在每个图像缩放时的缩放比例
    minNeighbors:指定每个候选矩形需要保留多少个相邻矩形
    flags:含义与函数cvHaarDetectObjects中的旧级联相同。它不用于新的级联
    minSize:对象最小大小,小于该值的对象被忽略。
    maxSize:最大可能的对象大小,大于这个值的对象被忽略 
    */
    CV_WRAP_AS(detectMultiScale2) void detectMultiScale( InputArray image,
                          CV_OUT std::vector<Rect>& objects,
                          CV_OUT std::vector<int>& numDetections,
                          double scaleFactor=1.1,
                          int minNeighbors=3, int flags=0,
                          Size minSize=Size(),
                          Size maxSize=Size() );

    /**
    detectMultiScale重载函数,此函数允许您检索分类的最终阶段决策确定性
    为此,需要将' outputRejectLevels '设置为true,并提供' rejectLevels '和' levelWeights '参数。
    对于每一个结果检测,‘levelWeights’将在最后阶段包含分类的确定性。

    这个值可以用来区分强分类和弱分类。

    具体使用示例代码
    Mat img;
    vector<double> weights;
    vector<int> levels;
    vector<Rect> detections;
    CascadeClassifier model("/path/to/your/model.xml");
    model.detectMultiScale(img, detections, levels, weights, 1.1, 3, 0, Size(), Size(), true);
    cerr << "Detection " << detections[0] << " with weight " << weights[0] << endl;
    */
    CV_WRAP_AS(detectMultiScale3) void detectMultiScale( InputArray image,
                                  CV_OUT std::vector<Rect>& objects,
                                  CV_OUT std::vector<int>& rejectLevels,
                                  CV_OUT std::vector<double>& levelWeights,
                                  double scaleFactor = 1.1,
                                  int minNeighbors = 3, int flags = 0,
                                  Size minSize = Size(),
                                  Size maxSize = Size(),
                                  bool outputRejectLevels = false );

    CV_WRAP bool isOldFormatCascade() const;
    CV_WRAP Size getOriginalWindowSize() const;
    CV_WRAP int getFeatureType() const;
    void* getOldCascade();

    CV_WRAP static bool convert(const String& oldcascade, const String& newcascade);

    void setMaskGenerator(const Ptr<BaseCascadeClassifier::MaskGenerator>& maskGenerator);
    Ptr<BaseCascadeClassifier::MaskGenerator> getMaskGenerator();

    Ptr<BaseCascadeClassifier> cc;
};

DEMO

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  

#include <vector>  
#include <cstdio>  
int main()
{
	//1.加载分类器
	CascadeClassifier cascade;
	//如果要识别人体的其它部位,只需将上面的haarcascade_frontalface_alt2.xml分类器替换即可。
	cascade.load("E:\\Windowstest\\OPENCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
	Mat srcImg, dstImg, grayImg;

	//定义7种颜色,用于标记人脸
	Scalar colors[] =
	{
		// 红橙黄绿青蓝紫
	   CV_RGB(255,0,0),
	   CV_RGB(255, 97, 0),
	   CV_RGB(255, 255, 0),
	   CV_RGB(0, 255, 0),
	   CV_RGB(255, 97, 0),
	   CV_RGB(0, 0, 255),
	   CV_RGB(160, 32, 240),
	};

	//打开摄像头
	cv::VideoCapture cap(0);
	if (!cap.isOpened())
	{
		printf("open video failed!\n");
		return 1;
	}

	int frameNum = 1000;
	cv::namedWindow("识别结果", CV_WINDOW_NORMAL);
	while (frameNum > 0) {
		if (cv::waitKey(100) == 'q')break;
		//将视频图片传给Mat
		cap >> srcImg;

		//尺寸调整
		int scale = 1.0;
		resize(srcImg, srcImg, Size(srcImg.cols / scale, srcImg.rows / scale), 0, 0, INTER_LINEAR); //用线性插值
		dstImg = srcImg.clone();

		grayImg.create(srcImg.size(), srcImg.type());
		cvtColor(srcImg, grayImg, CV_BGR2GRAY);//生成灰度图,提高检测效率

		// 3.检测
		vector<Rect> rect;
		cascade.detectMultiScale(grayImg, rect, 1.1, 3, 0);//分类器对象调用
		printf("检测到人脸个数:%d\n", rect.size());

		//标记--脸部画矩形
		for (int i = 0; i < rect.size(); i++) {
			rectangle(dstImg, Point(rect[i].x, rect[i].y), Point(rect[i].x + rect[i].width, rect[i].y + rect[i].height), colors[i % 7], 2, 8, 0);
		}

		//5.显示
		imshow("识别结果", dstImg);
		frameNum--;
	}

	waitKey(0);
}

参考地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值