[Opencv]Cascade级联分类器

文章目录​​​​​​

  1. 训练级联分类器
  2. 使用级联分类器检测
  3. 总结 



前言

        最近在尝试识别指定物体,之前用Opencv自带的级联分类器做过人脸识别感觉效果不错,所以想用级联分类器来做其它物体的识别。

        选择学习这种传统目标检测算法,主要是迎合电赛上的需求。虽然深度学习算法已经有许多种,但在树莓派这样没有GPU加速的平台上运行的帧率并不理想,做不到实时性。而Cascade用CPU就可以达到比较高的帧率。

        不可否认,Cascade在精确度上远不及其它深度学习的方法,但在背景单一,目标特征较简单的环境下,也可以有较好的效果。

        本文分享训练分类器和使用分类器进行检测的方法



一、训练分类器     

1.收集数据

        首先就是收集正负样本

        正样本是只包含要识别物体的图像,负样本就是背景图片,只要不包含目标就行,最好用所在环境的背景图片。

        附规范化命名和图像灰度化代码:

import os
#图片路径
path = 'C:/Users/lyf31/yolov5-boat/data/train/images'
num= 1

for file in os.listdir(path):
    os.rename(os.path.join(path,file),os.path.join(path,str(num)+".jpg"))
    num+=1
import cv2
#图片数量
num=22
#图片路径
path = "G:/Image_process/project/cascade/earphone/train/pos/"
for i in range(1, num+1):
    print(path+str(i)+'.jpg')
    img = cv2.imread(path+str(i)+'.jpg', cv2.IMREAD_GRAYSCALE)
    #图片大小
    img = cv2.resize(img, (72, 72))
    cv2.imshow("img", img)
    cv2.imwrite(path+str(i)+'.jpg', img)
    print(str(i)+'.jpg')

        正样本要求大小一致,Opencv默认是24*24,并且为灰度图。负样本也为灰度图,但大小无要求。

        准备好图片后生成正负样本索引。

        在官方文档中,正样本索引的格式为:

        img/img1.jpg 1 140 100 45 45

        分别是图片路径,目标数量,坐标。

        我是参照下面的博文来生产索引的,注意格式的意义更改代码。

        python生成opencv正样本和负样本描述文件_interstellar-ai的博客-CSDN博客

2.生成vec文件

        使用Opencv自带的应用程序来生成,在编译生成的bin文件夹里。        

        

        将上图两个应用程序加入文件夹。我们用opencv_createsamples.exe生产vec文件,在文件夹里用CMD或PowerShell运行指令:

        opencv_createsamples.exe -info pos.dat -vec pos.vec -num 22 -w 72 -h 72

        -info是正样本索引文件,-vec 是生成的vec文件,-num是样本个数,-w和-h是样本宽和高。

        以上是我测试过必须输入的参数,其实还有其它参数,可以运行opencv_createsamples.exe指令查看。

        

3.训练级联分类器

        同样是使用应用程序,运行指令:

        opencv_traincascade.exe -data data -vec pos.vec -bg neg.dat -numPos 12 -numNeg 50 -numStages 16 -w 72 -h 72 -mode ALL

        每个参数的意义也可以通过上面的方法看到,在此不一一列举。

        训练过程如下所示:

        

 训练结果



二、使用分类器检测

检测的步骤大致分为转换为灰度图——>直方图均衡化——>送入分类器检测——>框出目标。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

String fileName = "cascade.xml";
CascadeClassifier earphones_classifier;

int main(int argc, char** argv) 
{
	vector<Rect> earphones;
	if (!earphones_classifier.load(fileName)) 
    {
		printf("could not load face feature data...\n");
		return -1;
	}

	VideoCapture cap(1);
	Mat image, gray_image;

	while (1)
	{
		cap >> image;
		resize(image, image, Size(320, 240));
		cvtColor(image, gray_image, COLOR_BGR2GRAY);
		equalizeHist(gray_image, gray_image);

		earphones_classifier.detectMultiScale(gray_image, earphones, 1.1, 3,0,Size(5,5),Size(100,100));
		for (size_t t = 0; t < earphones.size(); t++) 
		{
			rectangle(image, earphones[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);
		}

		imshow("detect earphone", image);
		
		if (waitKey(5) == 'q')
		{
			destroyAllWindows();
			break;
		}

	}
	
	return 0;
}

其中detectMultiScale()函数的参数尤为重要。

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() );

1.image表示的是要检测的输入图像。

2.objects表示检测到的人脸目标序列。

3.scaleFactor表示每次图像尺寸减小的比例。

4. minNeighbors表示每一个目标至少要被检测到3次才算是真的目标。

5.flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域, 因此这些区域通常不会是人脸所在区域;

6.minSize为目标的最小尺寸

7.minSize为目标的最大尺寸

调节4、6、7参数能排除干扰,使检测结果更加准确

附上自己训练并检测的结果


四、总结

        Cascade级联分类器的检测效果总的来说较为普通,但实测帧率高,一般可以达到20—25帧,可作为目标检测的备选方案。      

OpenCV是一个开源的计算机视觉库,它提了许多用于图像和视频处理的功能。其中之一就是级联分类器Cascade Classifier),它是一种基于机器学习的目标检测算法。 级联分类器是通过训练得到的,可以用于检测特定对象或特征。在OpenCV中,最常见的应用就是人脸检测。级联分类器通过使用Haar特征和AdaBoost算法来训练,可以在图像中快速准确地检测出人脸。 在Python中使用OpenCV级联分类器,首先需要加载已经训练好的分类器模型。OpenCV提供了一些预训练好的模型,可以直接使用。然后,将待检测的图像传入分类器中进行检测,如果检测到目标对象,则返回目标的位置信息。 下面是使用OpenCV Python级联分类器的基本步骤: 1. 导入OpenCV库:`import cv2` 2. 加载分类器模型:`face_cascade = cv2.CascadeClassifier('path/to/haarcascade_frontalface_default.xml')` 3. 读取待检测的图像:`img = cv2.imread('path/to/image.jpg')` 4. 将图像转换为灰度图像:`gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)` 5. 使用级联分类器进行检测:`faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))` 6. 遍历检测到的目标,绘制矩形框标记:`for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)` 7. 显示检测结果:`cv2.imshow('Detected Faces', img)` 8. 等待按键退出:`cv2.waitKey(0)` 以上是一个简单的人脸检测示例,你可以根据需要调整参数和模型路径。除了人脸检测,级联分类器还可以用于其他目标的检测,如眼睛、车辆等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值