#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;
}
标签数据: