OpenCV4学习笔记(37)——级联检测器

今天要整理记录的笔记是OpenCV中级联检测器的使用。

在OpenCV中提供了一些级联检测器来进行目标检测,例如人脸检测、微笑检测、眼睛检测等等,在我们从官网直接下载的或者自己编译的OpenCV包中已经包含了一些训练好的模型文件,其路径是opencv\build\etc\。其中包含了haarcascadeslbpcascades这两个文件夹,其中分别对应haar级联检测器和LBP(局部二值模式Local Binary Pattern)级联检测器。

级联检测器是由多个分类器分级构成的,每一个分类器来负责判断某个特征feature是否存在,再将多个分类器进行分级联接。当对某个区域进行检测时,如果某一级分类器其负责的特征的检测结果是存在,则会将该区域进入下一级分类器的特征检测过程,逐级检测最终输出结果。如果某一级分类器负责的特征的检测结果是不存在,就直接判定该区域不是待检测目标。

在OpenCV中主要分为haar级联检测器和LBP(局部二值模式Local Binary Pattern)级联检测器。

haar级联检测器是基于Haar特征的一种检测器。Haar特征分为四类:边缘特征、线性特征、中心特征和对角线特征,针对不同目标依靠不同类型的特征组合成特征模板来表示这个目标,反映的是图像的对比度和梯度变化。每一级分类器对每个区域的特征利用特征模板进行检测,再用多级分类器组成特定目标的级联检测器,只有当某个区域满足级联检测器每一级的特征时才认定为检测目标。Haar级联检测器以浮点型数据进行计算,虽然检测速度相对比较慢,但是更精准一些。

LBP(局部二值模式Local Binary Pattern)级联检测器是基于LBP特征的检测器。遍历区域中的每一个像素的邻域,把该邻域中比中心像素值大的像素点置为1,比中心像素值小的像素点置为0,然后和位编码矩阵(顺时针按0、1、2、3、4、5、6、7、8排序的3x3矩阵)进行按位相乘操作,再对最后得到的矩阵进行求和操作,得到一个LBP特征值。LBP特征具有整体光照不变性,但是局部光照变化剧烈会造成较大影响、旋转不变性(需要经过傅里叶变换到频域空间),主要用来实现2D图像纹理分析、对象识别与检测等应用。LBP级联检测器以整型数据进行计算,其检测速度比较快。

在OpenCV中,我们需要先创建一个CascadeClassifier类的对象,作为我们的级联检测器detector。然后通过detector.load(path)的方式来加载所需的级联检测器。

在通过detector.detectMultiScale()对图像进行目标检测,其参数含义如下:
第一个参数image: CV_8U类型的检测图像;
第二个参数objects:矩形向量,其中每个矩形都包含检测到的对象,这些矩形可能部分位于原始图像的外部;
第三个参数scaleFector:表示图像缩放时尺寸减小的比例,scaleFector=(缩放前尺寸:缩放后尺寸),为double类型;当该参数小于1时会报错,默认值为1.1;该参数越大,尺寸减小得更多,检测速度更快,但可能会忽略掉一些目标;
第四个参数minNeighBors:指定每个候选矩形必须存在多少邻近候选矩形;只有当邻近候选矩形大于该参数时,该候选矩形才认定为目标,相当于一个检测阈值;
第五个参数flag:在OpenCV4中已经不需要该参数,直接置零就可以;
第六个参数minSize:最小检测的目标大小,小于此值的目标将被忽略;注意当需要检测较小目标时,由于检测目标尺寸必须比样本尺寸Size(24,24)要大,所以不能一味地下调minSize,否则当minSize小于Size(24,24)时就没什么变化了,在下调minSize的同时需要对scaleFector进行调整;
第七个参数maxSize:最大检测的目标大小,大于此值的目标将被忽略;如果maxSize == minSize,模型是按单一比例评估的;检测顺序是从最大尺寸开始检测。

下面看一下演示代码:

	CascadeClassifier detector;
	String model_path = "D:/opencv_c++/opencv_tutorial/installer/etc/haarcascades/haarcascade_frontalface_alt2.xml";
	detector.load(model_path);				//加载级联检测器模型
	VideoCapture capture;
	capture.open(0);
	if (!capture.isOpened())
	{
		return 0;
	}
	Mat frame, frame_gray;
	while (capture.read(frame))
	{
		flip(frame, frame, 1);
		cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
		equalizeHist(frame_gray, frame_gray);			//对灰度图进行直方图均衡化,增强图像灰度特征
		vector<Rect> detections;
		detector.detectMultiScale(frame_gray, detections, 1.1, 3, 0, Size(30, 30), Size(300, 300));
		
		if (detections.size() > 0)
		{
			for (int i = 0; i < detections.size(); i++)
			{
				rectangle(frame, detections[i], Scalar(0, 255, 0), 1, LINE_AA, 0);
			}
		}
		imshow("frame", frame);

		char ch = waitKey(20);
		if (ch == 27)
		{
			break;
		}
	}
	capture.release();

由于这是人脸检测的演示,就不开摄像头露脸了哈哈哈哈哈~~~

虽然级联检测器的使用是比较方便的,但是其效果并不是很好,所以越来越被一些深度学习方法给替代了,其使用范围也是越来越小,以至于在OpenCV4发布后官方支持的人脸检测方法已经转换成为基于深度学习的方法,而haar级联检测器训练的工具在OpenCV4中已经被除名了。所以级联检测器这种目标检测方法,可以了解了解但是没有很大的必要去深入地研究,毕竟应用空间太窄这点极大的限制了它的价值。如果有朋友知道级联检测器的其他方面的用途,欢迎在评论区给我科普科普。

好的今天的笔记整理到此为止,谢谢阅读~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

发布了49 篇原创文章 · 获赞 71 · 访问量 5139

猜你喜欢

转载自blog.csdn.net/weixin_45224869/article/details/105275628