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;
}

标签数据:

HOG特征提取SVM分类是常用的目标检测图像分类方法之一。下面是使用MATLAB进行HOG特征提取SVM分类的基本步骤: 1. 加载数据集并进行预处理:首先,加载训练数据测试数据,并将它们转换为合适的格式。例如,如果您使用的是图像数据集,则需要将图像转换为灰度图像,并将其大小调整为相同的大小。 2. 提取HOG特征:使用MATLAB的“extractHOGFeatures”函数从每个图像中提取HOG特征。该函数接受图像作为输入,并返回一个向量,该向量包含图像的HOG特征。 3. 训练SVM分类器:使用MATLAB的“fitcsvm”函数训练SVM分类器。该函数接受HOG特征向量作为输入,并使用训练数据来训练分类器。 4. 测试SVM分类器:使用MATLAB的“predict”函数测试SVM分类器。该函数接受HOG特征向量作为输入,并返回分类器对该向量的分类结果。 以下是一个简单的MATLAB代码示例,用于演示如何使用HOG特征提取SVM分类: ``` % 加载数据集 trainData = load('trainData.mat'); testData = load('testData.mat'); % 提取HOG特征 trainFeatures = extractHOGFeatures(trainData.images); testFeatures = extractHOGFeatures(testData.images); % 训练SVM分类器 svmClassifier = fitcsvm(trainFeatures, trainData.labels); % 测试SVM分类器 predictions = predict(svmClassifier, testFeatures); ``` 请注意,以上代码仅提供了一个基本示例,并且需要根据您的具体数据集需求进行修改优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值