用初次训练的SVM+HOG分类器在负样本原图上检测HardExample

难例(或叫做难样本,Hard Example,Hard Negative,Hard Instance)是指利用第一次训练的分类器在负样本原图(肯定没有人体)上进行行人检测时所有检测到的矩形框,这些矩形框区域很明显都是误报,把这些误报的矩形框保存为图片,加入到初始的负样本集合中,重新进行SVM的训练,可显著减少误报。这种方法叫做自举法(Bootstrap),自举法首先使用初始负样本集来训练一个模型,然后收集被这个初始模型错误分类的负样本来形成一个负样本难例集。用此负样本难例集训练新的模型,此过程可以重复多次。

比如典型的误报如下:



上图中将树干误认为是人体,这些就是Hard Example,将这些矩形框保存为64*128的图片文件,加入到负样本集合中。

也就是说,难例就是分错类的负样本,将难例加入负样本集合进行二次训练就是告诉分类器:“这些是你上次分错类的,要吸取教训,改正错误”

初次训练SVM+HOG分类器见:自己训练SVM分类器进行HOG行人检测

Navneet Dalal在CVPR2005上的HOG原论文翻译见:http://blog.csdn.net/masibuaa/article/details/14056807


#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;

int hardExampleCount = 0; //hard example计数

int main()
{
	Mat src;
	char saveName[256];//剪裁出来的hard example图片的文件名
	string ImgName;
	ifstream fin_detector("HOGDetectorForOpenCV_2400PosINRIA_12000Neg.txt");//打开自己训练的SVM检测器文件
	ifstream fin_imgList("INRIANegativeImageList.txt");//打开原始负样本图片文件列表
	//ifstream fin_imgList("subset.txt");

	//从文件中读入自己训练的SVM参数
	float temp;
	vector<float> myDetector;//3781维的检测器参数
	while(!fin_detector.eof())
	{
		fin_detector >> temp;
		myDetector.push_back(temp);//放入检测器数组
	}
	cout<<"检测子维数:"<<myDetector.size()<<endl;

	//namedWindow("src",0);
	HOGDescriptor hog;//HOG特征检测器
	hog.setSVMDetector(myDetector);//设置检测器参数为自己训练的SVM参数

	//一行一行读取文件列表
	while(getline(fin_imgList,ImgName))
	{
		cout<<"处理:"<<ImgName<<endl;
		string fullName = "D:\\DataSet\\INRIAPerson\\INRIAPerson\\Train\\neg\\" + ImgName;//加上路径名
		src = imread(fullName);//读取图片
		Mat img = src.clone();//复制原图

		vector<Rect> found;//矩形框数组
		//对负样本原图进行多尺度检测,检测出的都是误报
		hog.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);

		//遍历从图像中检测出来的矩形框,得到hard example
		for(int i=0; i < found.size(); i++)
		{
			//检测出来的很多矩形框都超出了图像边界,将这些矩形框都强制规范在图像边界内部
			Rect r = found[i];
			if(r.x < 0)
				r.x = 0;
			if(r.y < 0)
				r.y = 0;
			if(r.x + r.width > src.cols)
				r.width = src.cols - r.x;
			if(r.y + r.height > src.rows)
				r.height = src.rows - r.y;

			//将矩形框保存为图片,就是Hard Example
			Mat hardExampleImg = src(r);//从原图上截取矩形框大小的图片
			resize(hardExampleImg,hardExampleImg,Size(64,128));//将剪裁出来的图片缩放为64*128大小
			sprintf(saveName,"hardexample%09d.jpg",hardExampleCount++);//生成hard example图片的文件名
			imwrite(saveName, hardExampleImg);//保存文件


			//画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
			//r.x += cvRound(r.width*0.1);
			//r.width = cvRound(r.width*0.8);
			//r.y += cvRound(r.height*0.07);
			//r.height = cvRound(r.height*0.8);
			rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);

		}
		//imwrite(ImgName,img);
		//imshow("src",src);
		//waitKey(100);//注意:imshow之后一定要加waitKey,否则无法显示图像

	}

	system("pause");
}


源码下载,环境为VS2010 + OpenCV2.4.4

http://download.csdn.net/detail/masikkk/6549325

参考

用初次训练的SVM+HOG分类器在负样本原图上检测HardExample


  • 8
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值