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为负样本。
以上头函数,有一些可能没用上的,只是习惯性的复制了上一个项目
//
#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为负样本。
以上头函数,有一些可能没用上的,只是习惯性的复制了上一个项目
相关文章推荐
- OpenCV中将一幅图平均分成N*M份,适合SVM+HOG训练的负样本采集
- Matlab的svmtrain从数据集中抽样训练样本和测试样本的方法
- (OpenCV3.2.0)基于HOG特征的SVM训练与测试实例
- HOG+SVM 自己制作训练样本+训练分类器
- SVM+HOG:用初次训练的.xml分类器在负样本原图上检测生成HardExample样本
- HOG+SVM 自己制作训练样本+训练分类器
- opencv中应用HOG特征训练SVM多分类器的一般框架
- 用训练好的caffe模型来测试样本
- 自己训练SVM分类器进行HOG行人检测
- SVM+HOG:从完全不包含人体的图片中随机剪裁出64*128大小的用于人体检测的负样本
- OpenCV HOG+SVM行人检测:从训练到检测
- HOG 行人检测 学习体会(如何制作训练样本)
- 根据当前文件夹下所有文件随机自动生成训练和测试样本列表
- 开篇-HOG提取训练检测+样本制作
- 用训练好的caffe模型来测试样本
- 如何正确训练一个 SVM + HOG 行人检测器
- OpenCv Hog+SVM 样本 bat批处理
- 自己训练SVM分类器进行HOG行人检测
- 人脸识别(二)--人脸识别样本制作及训练测试
- Opencv中SVM样本训练、归类流程及实现