opencv +Hog + SVM 车辆检测

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_37487118/article/details/83046962

最近尝试了一下用opencv做了一下车辆检测
其中hog特征使用opencv自带函数库进行提取描述如下:

HOGDescriptor *hog = new HOGDescriptor(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9);

上述参数中第一个size代表读入训练数据中图像的大小
第二个为滑动窗口大小
第三个滑动步长
第四个cell的大小
然后就是SVM的使用了

    Ptr < SVM > svm = SVM::create(); //建立对象
	svm->setType(SVM::C_SVC); 
	svm->setKernel(SVM::LINEAR); //线性核
	//导入特征矩阵  每一行代表一个特征向量  最后为特征标签
	Ptr<TrainData> tData = TrainData::create(sample_feature_mat, ROW_SAMPLE,sample_label_mat);
	//自动设置相应参数并训练
	svm->trainAuto(tData);

再看看为什么hog特征能较好的对车辆分类
下图显示了我对100个包含车辆的样本(图像上部)与200个不包含车辆的样本(图像下部)进行可视化,显然包含车辆的特征向量与不包含车辆的特征向量有明显区别
所以hog特征能较强的描述目标物体的形状信息
而一般图像中物体特征的表达通常用形状、纹理或者颜色等特征来描述
一般人体或车辆等能够被形状较强的表征,而hog特征正好适合来表征物体的形状信息,所以一般用hog特征来做行人或者车辆检测等等…
在这里插入图片描述
完整代码如下:

   //我用的是opencv3.4 HOG与SVM的使用与2.X版本的有些区别
    string pos_path = "正样本路径";
	string neg_path = "负样本路径";
	Mat sample_feature_mat,sample_label_mat;
	ifstream input_pos_sample(pos_path);
	ifstream input_neg_sample(neg_path);
	vector<string>pos_sample_path,neg_sample_path,feature_dim;
	string str;
	int pos_sample_num,neg_sample_num ;
	while (getline(input_pos_sample, str))  pos_sample_path.push_back(str);
	while (getline(input_neg_sample, str))  neg_sample_path.push_back(str);
	pos_sample_num = pos_sample_path.size();
	neg_sample_num = neg_sample_path.size();
	input_pos_sample.close();
	input_neg_sample.close();
	HOGDescriptor *hog = new HOGDescriptor(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9);
	//正样本hog特征提取
	for (int i = 0; i < pos_sample_num; ++i) {
		Mat input_img = imread(pos_sample_path[i],0);
		Mat train_data(64, 64, CV_32FC1);
		resize(input_img, train_data, Size(64, 64));
		vector<float>descriptor;
		hog->compute(train_data, descriptor, Size(8, 8));
		if (i == 0) {
			feature_dim = descriptor.size();
			sample_feature_mat = Mat::zeros(pos_sample_num + neg_sample_num, feature_dim, CV_32FC1);
			sample_label_mat = Mat::zeros(pos_sample_num + neg_sample_num, 1, CV_32SC1);
		}
		float *pf = sample_feature_mat.ptr<float>(i);
		int *pl = sample_label_mat.ptr<int>(i);
		for (int j = 0; j < feature_dim; ++j) {
			*pf++ = descriptor[j];
		}
		*pl++ = 1;
	}
	//负样本hog特征提取
	for (int i = 0; i < neg_sample_num; ++i) {
		Mat input_img = imread(neg_sample_path[i],0);
		Mat train_data(64, 64, CV_32FC1);
		resize(input_img, train_data, Size(64, 64));
		vector<float>descriptor;
		hog->compute(train_data, descriptor, Size(8, 8));
		float *pf = sample_feature_mat.ptr<float>(i + pos_sample_num);
		int *pl = sample_label_mat.ptr<int>(i + pos_sample_num);
		for (int j = 0; j < feature_dim; ++j) {
			*pf++ = descriptor[j];
		}
		*pl++ = -1;
	}
	//训练数据
    Ptr < SVM > svm = SVM::create();
	svm->setType(SVM::C_SVC);
	svm->setKernel(SVM::LINEAR);
	Ptr<TrainData> tData = TrainData::create(sample_feature_mat, ROW_SAMPLE,sample_label_mat);
	cout << "train begin" << endl;
	svm->trainAuto(tData);
	svm->save("D:\\traindata\\SVM_Model.xml"); //训练结果保存文件
	cout << "train done" << endl;

我用100个正样本200个负样本训练车辆检测
结果对于KITTI的车辆数据分类正确率大约90%
分类结果还行,增加训练数据还能达到更高的准确率
网上也很多例程,我就不详细说明了

猜你喜欢

转载自blog.csdn.net/qq_37487118/article/details/83046962