您的位置:首页 > 其它

HOG+SVM样本训练测试例子

2018-01-15 10:06 281 查看
// HOG+SVM.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/opencv.hpp>

#include <core/core.hpp>

#include <stdio.h>

#include <iostream>

#include <fstream>

#include <vector>

#include <omp.h>

using namespace cv;

using namespace std;

static Mat getHOGfeature(Mat src,Size sz)

{
Mat grayimg;
Mat new_src;
if (src.channels()>1)
{
cvtColor(src,grayimg,CV_BGR2GRAY);
}
else
{
src.copyTo(grayimg);
}
resize(grayimg,new_src,sz);
vector <float> Descriptor;
HOGDescriptor hog;
hog.winSize=sz;
hog.compute(new_src,Descriptor,Size(8,8),Size(0,0));
//转置
Mat matf1;
transpose((Mat)Descriptor,matf1);
return matf1;

}

static Mat getLabfeature(Mat src)

{
Mat Labimg;
cvtColor(src,Labimg,CV_BGR2Lab);
int abin=32;
int bbin=32;
int histsize[]={abin,bbin};
float aranges[]={0,255};
float branges[]={0,255};
int chanels[]={1,2};
const float *range[]={aranges,branges};
Mat dst;
calcHist(&Labimg,1,chanels,Mat(),dst,2,histsize,range);
Mat outputdst;
normalize(dst,outputdst);
return outputdst.reshape(1,1);

}

static Mat typechange(vector<Mat>src)

{
Mat dst;
//因为每张图的纬度一致,提取第一张图的纬度
Mat src_mat=src[0];
//创建dst的mat
dst=Mat::zeros(src.size(),src_mat.rows*src_mat.cols,CV_32FC1);
for (int i=0;i<src.size();i++)
{
Mat src_1=src[i];
src_1.copyTo(dst.row(i));
}
return dst;

}

void train_svm(Mat src,Mat labels)

{
SVMParams params;
params.svm_type=CvSVM::C_SVC;
params.kernel_type=CvSVM::RBF;
par
4000
ams.C=2.5;
params.p=0;
params.gamma=3.375e-2;
params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER,1000,1e-5);
CvSVM svm;
svm.train(src,labels,Mat(),Mat(),params);
//自动SVM参数优化
//CvParamGrid nugrid=CvParamGrid(1,1,0.0);
//CvParamGrid coeef=CvParamGrid(1,1,0.0);
//CvParamGrid degreegrid=CvParamGrid(1,1,0.0);
//svm.train_auto(src,labels,Mat(),Mat(),params,
// 10,
// svm.get_default_grid(CvSVM::C),
// svm.get_default_grid(CvSVM::GAMMA),
// svm.get_default_grid(CvSVM::P),
// nugrid,
// coeef,
// degreegrid);
//SVMParams svmparamAF=svm.get_params();
//float C=svmparamAF.C;
//float P=svmparamAF.p;
//float gamma=svmparamAF.gamma;
svm.save("E:\\opencv\\SVM\\svm.xml");

}

int main()

{
vector<string>name;
vector<string>name1;
vector<int>labels;
vector<Mat>feature_1;
string posimgspace;
string negimgspace;
//加载正样本
locale::global(locale(""));
ifstream fin("E:\\opencv\\SVM\\正样本\\LIST.TXT");
locale::global(locale("C"));
while(getline(fin,posimgspace))
{
name.push_back(posimgspace);
}
Rect ROI(40,40,400,400);
for (int i=0;i<name.size();i++)
{
Mat posimg=imread("E:\\opencv\\SVM\\正样本\\"+name[i]);
//四周边界有黑边,提取正中间图像:400*400
Mat new_posimg=posimg(ROI);
//HOG特征提取
Mat Hogfeature=getHOGfeature(new_posimg,Size(64,64));
//Lab特征提取
Mat Labfeature=getLabfeature(new_posimg);
Mat feature;
//矩阵合并
hconcat(Hogfeature,Labfeature,feature);

       feature_1.push_back(feature);
}
//正样本贴标签
labels.assign(name.size(),1);
//加载负样本
locale::global(locale(""));
ifstream fin1("E:\\opencv\\SVM\\负样本\\LIST.TXT");
locale::global(locale("C"));
while(getline(fin1,negimgspace))
{
name1.push_back(negimgspace);
}
for(int j=0;j<name1.size();j++)
{
Mat negimg=imread("E:\\opencv\\SVM\\负样本\\"+name1[j]);
Mat new_negimg=negimg(ROI);
//HOG特征提取
Mat Hogfeature_1=getHOGfeature(new_negimg,Size(64,64));
//Lab特征提取
Mat Labfeatuer_1=getLabfeature(new_negimg);
//矩阵合并
Mat feature_neg;
hconcat(Hogfeature_1,Labfeatuer_1,feature_neg);
feature_1.push_back(feature_neg);
}
//负样本贴标签
labels.insert(labels.end(),name1.size(),-1);
//格式转换 由vector转成Mat类型
Mat feature_final=typechange(feature_1);
//SVM训练
train_svm(feature_final,Mat(labels));
//SVM测试
Mat svmtest=imread("E:\\opencv\\1.jpg");
Mat svmtest_1=svmtest(ROI);
Mat HOGfeature_test=getHOGfeature(svmtest_1,Size(64,64));
Mat Labfeature_test=getLabfeature(svmtest_1);
Mat feature_test;
hconcat(HOGfeature_test,Labfeature_test,feature_test);
CvSVM svm;
svm.load("E:\\opencv\\SVM\\svm.xml");
float res=svm.predict(feature_test);//返回1为正样本,-1为负样本
}

      程序的主要目的是剔除图像中不符合要求的图像,因为样本数据库中,基本上的图像四周均有黑边,且分辨率为480*480,所以只取中间400*400的图像进行特征提取,首先运用HOG提取7*7* 36=1764维特征,在根据Lab提取32*32=1024维特征,最后进行矩阵合并,每张图有1764+1024=2788维特征,采用SVM进行二分类,1位正样本,-1为负样本。

以上头函数,有一些可能没用上的,只是习惯性的复制了上一个项目
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: