HOG+SVM样本训练测试例子

// 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;
params.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为负样本。

以上头函数,有一些可能没用上的,只是习惯性的复制了上一个项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值