HOG特征提取和SVM训练

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

#define posSampleNum 682
#define negSampleNum 770

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
	int winWidth = 64;
	int winHeight = 128;
	int blockWidth = 16;
	int blockHeight = 16;
	int blockStrideX = 8;
	int blockStrideY = 8;
	int cellWidth = 8;
	int cellHeight = 8;
	int bins = 9;

	string backgroundSamplePath = "..//bkImageMarkInfo1.txt";
	string targetSamplePath = "..//targetImageMarkInfo.txt";

	string backgroundSampleName;
	string targetSampleName;
	string negSampleImg;
	string posSampleImg;
	vector<string> stringData;


	string str;

	int startX;
	int startY;
	int endX;
	int endY;

	int posSampleN = 0;
	int negSampleN = 0;

	Mat srcImg;
	Mat roiImg;  // 样本图
	Mat tempImg;
	Mat targetImg;

	Mat sampleFeatureMat; // 所有训练样本的特征向量组成的矩阵,行数为所有样本个数,列数为HOG描述字维度
	Mat sampleLabelMat;   // 训练样本的类别向量,行数为样本个数,列数为1或-1。1表示有无人机;-1表示没有无人机

	cv::HOGDescriptor hog(Size(winWidth, winHeight),
		Size(blockWidth, blockHeight),
		Size(blockStrideX, blockStrideY),
		Size(cellWidth, cellWidth),
		bins);

	int descriptorDim = 0;  // 特征描述子维度
	vector<float> descriptors;
	vector<float> negSampleDescriptors;

	/***********************************************************************/
	/*                          正样本数据                                */
	ifstream readFile(targetSamplePath);
	if (readFile.is_open())
	{
		while (!readFile.eof())
		{

			//获取文本的一行数据
			getline(readFile, targetSampleName);
			

			// 以逗号进行分隔
			stringstream ss(targetSampleName);
			str;
			while (getline(ss, str, ','))
			{
				stringData.push_back(str);
			}
			// 获取样本信息
			// stringData[0]:样本所在图像名字
			// stringData[1]-stringData[4]:
			// 样本坐标点:起点X
			// 样本坐标点:起点Y
			// 样本坐标点:终点X
			// 样本坐标点:终点Y

			posSampleImg = stringData[0];
			startX = stoi(stringData[1]);
			startY = stoi(stringData[2]);
			endX = stoi(stringData[3]);
			endY = stoi(stringData[4]);
			// cout << posSampleImg << endl;
			stringData.clear();

			// 读取图片srcImg
			srcImg = imread(posSampleImg);
			tempImg = srcImg.clone();

			// 获取图像中无人机
			roiImg = tempImg(Range(startY, endY), Range(startX, endX));

			resize(roiImg, targetImg, Size(winWidth, winHeight));
			hog.compute(targetImg, descriptors, Size(blockStrideX, blockStrideY));
			//imshow("targetImg",targetImg);
			//waitKey(20);
			descriptorDim = descriptors.size();

			if (posSampleN == 0)
			{
				sampleFeatureMat = Mat::zeros(posSampleNum + negSampleNum, descriptorDim, CV_32FC1);
				sampleLabelMat = Mat::zeros(posSampleNum + negSampleNum, 1, CV_32SC1);
			}
			

			// 将计算好的hog描述字复制到样本特征矩阵中
			for (int i = 0; i < descriptorDim; i++)
			{
				sampleFeatureMat.at<float>(posSampleN, i) = descriptors[i];
			}
			sampleLabelMat.at<float>(posSampleN, 0) = 1;
			posSampleN++;
		}

	}

	/****************************************************************/
	/*                        负样本数据                            */
	cout << "提取负样本数据的HOG特征......." << endl;
	ifstream readFile1(backgroundSamplePath);
	if (readFile1.is_open())
	{
		while (!readFile1.eof())
		{

			//获取文本的一行数据
			getline(readFile1, backgroundSampleName);


			// 以逗号进行分隔
			stringstream ss(backgroundSampleName);
			str;
			while (getline(ss, str, ','))
			{
				stringData.push_back(str);
			}
			// 获取样本信息
			// stringData[0]:样本所在图像名字
			// stringData[1]-stringData[4]:
			// 样本坐标点:起点X
			// 样本坐标点:起点Y
			// 样本坐标点:终点X
			// 样本坐标点:终点Y

			negSampleImg = stringData[0];
			startX = stoi(stringData[1]);
			startY = stoi(stringData[2]);
			endX = stoi(stringData[3]);
			endY = stoi(stringData[4]);
			// cout << posSampleImg << endl;
			stringData.clear();

			// 读取图片srcImg
			srcImg = imread(negSampleImg);
			tempImg = srcImg.clone();

			// 获取图像中无人机
			roiImg = tempImg(Range(startY, endY), Range(startX, endX));

			resize(roiImg, targetImg, Size(winWidth, winHeight));
			cv::cvtColor(targetImg, targetImg, CV_RGB2GRAY);
			hog.compute(targetImg, negSampleDescriptors, Size(blockStrideX, blockStrideY));

			descriptorDim = negSampleDescriptors.size();

	

			// 将计算好的hog描述字复制到样本特征矩阵中
			for (int i = 0; i < descriptorDim; i++)
			{
				sampleFeatureMat.at<float>(posSampleNum + negSampleN, i) = negSampleDescriptors[i];
			}
			sampleLabelMat.at<float>(posSampleNum + negSampleN, 0) = -1;
			negSampleN++;
			 
		}

	}

	/***************************************************************************************************/
	/**                        训练SVM分类器                      **/
	// 迭代终止条件, 当迭代满1000次或者误差小于FLT_EPSILON时停止迭代

	// 设置SVM参数
	Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
	svm->setType(cv::ml::SVM::Types::C_SVC);
	svm->setKernel(cv::ml::SVM::KernelTypes::LINEAR);
	svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));

	cout << "开始训练SVM分类器" << endl;
	Ptr<cv::ml::TrainData> td = cv::ml::TrainData::create(sampleFeatureMat, ml::SampleTypes::ROW_SAMPLE, sampleLabelMat);

	// 训练分类器
	svm->train(td);
	cout << "训练完成" << endl;
	svm->save("svm_hog.xml");

	return 0;
}

标签数据:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值