您的位置:首页 > 运维架构

SVM+HOG对图像进行多分类(OpenCV实现)

2017-08-09 16:51 751 查看
前几个月写了篇关于MATLAB实现SVM+HOG对图像进行多分类,链接:http://blog.csdn.net/cuixing001/article/details/70908064,先开始是用opencv实现的,可是识别效果很差,以为我写错代码了,后来纠结了好久好久,才发现是核函数选择有很大问题!这次改为线性核,效果在这些图片中(所用的图像数据集为:链接: https://pan.baidu.com/s/1i5OhC7z 密码:
utn7)表现不错。

OpenCV代码如下:

//SVM多分类训练测试
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;
Size imageSize = Size(64, 64);

void coumputeHog(const Mat& src, vector<float> &descriptors)
{
HOGDescriptor myHog = HOGDescriptor(imageSize, Size(16, 16), cvSize(8, 8), cvSize(8, 8), 9);
myHog.compute(src.clone(),descriptors,Size(1,1),Size(0,0));

}

int main(int argc, char** argv){
ifstream inLabels("myImageLabels.txt"), inImages("myImageList.txt"),inTestimage("myImagetest.txt");

string imageName;
signed imageLabel;
vector<Mat> vecImages;
vector<int> vecLabels;
CvSVM *mySVM = new CvSVM();
CvSVMParams params = CvSVMParams();
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 10000, 1e-10);
vector<float> vecDescriptors;

#if(1) //是否需要训练
while ((inImages>>imageName)&&(inLabels>>imageLabel))
{
Mat src = imread(imageName, 0);
resize(src, src, imageSize);
vecImages.push_back(src);
vecLabels.push_back(imageLabel);
}
inLabels.close();
inImages.close();

Mat dataDescriptors;
Mat dataResponse = (Mat)vecLabels;
for (size_t i = 0; i < vecImages.size(); i++)
{
Mat src = vecImages[i];
Mat tempRow;
coumputeHog(src, vecDescriptors);
if (i == 0)
{
dataDescriptors = Mat::zeros(vecImages.size(), vecDescriptors.size(), CV_32FC1);
}
tempRow = ((Mat)vecDescriptors).t();
tempRow.row(0).copyTo(dataDescriptors.row(i));
}

mySVM->train(dataDescriptors, dataResponse, Mat(), Mat(), params);
string svmName = to_string(88) + "_mysvm.xml";
mySVM->save(svmName.c_str());
#else

mySVM->load("mysvm.xml");
#endif

// 预测
string testPath;
while (inTestimage >> testPath)
{
Mat test = imread(testPath, 0);
resize(test, test, imageSize);
vector<float> imageDescriptor;
coumputeHog(test, imageDescriptor);
Mat testDescriptor = Mat::zeros(1, imageDescriptor.size(), CV_32FC1);
for (size_t i = 0; i < imageDescriptor.size(); i++)
{
testDescriptor.at<float>(0, i) = imageDescriptor[i];
}
float  label = mySVM->predict(testDescriptor, false);
cout << label << endl;
imshow("test image", test);
waitKey(0);
}

inTestimage.close();
delete mySVM;
return 0;
}


上面代码用到"myImageLabels.txt", "myImageList.txt","myImagetest.txt"分别为训练图像标记,训练图像路径,测试图像路径。

里面保存内容格式如下:







label=1,2,3,4,5分别表示airplanes,butterfly,camera,scissors,sunflower这五类,测试效果如下,改成RBF效果就很差了:

每按下一次空格键就预测一张图片。







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HOG SVM opencv 图像分类