svm+hogsvm训练样本本需要多久

2484人阅读
HOG+SVM行人检测(13)
计算机视觉、模式识别、机器学习(19)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
分析了原作者的数据集,结合网上一些资料,下面描述如何制作训练样本
1、如何从原始图片生成样本
对比INRIAPerson\INRIAPerson\Train\pos(原始图片),INRIAPerson\train_64x128_H96\pos(生成样本)可以发现,作者从原始图片裁剪出一些站立的人,要求该人不被遮挡,然后对剪裁的图片left-right reflect。以第一张图片为例crop001001,它剪裁了2个不被遮挡的人,再加上原照片,共3张,再加左右镜像,总共6张。
 可利用基于opencv1.0的程序imageclipper,进行裁剪并保存,它会自动生成文件名并保存在同一路径下新生成的imageclipper文件夹下。
3.改变图片大小
 可以利用Acdsee软件,Tools/open in editor,进去后到Resize选项; tools/rotate还可实现left-right reflect
4. 制作pos.lst列表  进入dos界面,定位到需要制作列表的图片文件夹下,输入 dir /b& pos.lst,即可生成文件列表;
仔细分析了cvhop.cpp中的compute函数,可以直接调用它来获得样本HOG,然后训练得到检测算子
1.制作样本
2.对每一张图片调用
pute(img, descriptors,Size(8,8), Size(0,0));
可以生成hog descriptors,把它保存到文件中
for(int j=0;j&3780;j++)
fprintf(f,&%f,&,descriptors[j]);
3.利用SVM进行训练和分类,可得到权重系数,即getDefaultPeopleDetector()函数中调用的检测算子detector[ ]
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:156482次
积分:1940
积分:1940
排名:第18106名
原创:14篇
转载:109篇
评论:13条
(8)(16)(18)(3)(30)(49)2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。统计手写数字集的HOG特征
转载请注明出处,楼燚(yì)航的blog,
这篇文章是模式识别的小作业,利用svm实现Minist数据集手写体识别,在这里我实现了opencv中的svm和libsvm两个版本,供大家做参考。
[] Github上的工程链接
Hog特征简介
本实验中,使用开源计算机视觉库OpenCV作为图像处理的基本工具,用其提供的loadImage函数读入训练样本后,首先我们考虑如何对样本中的手写数字特征进行提取。在本实验中我们采取了方向梯度直方图(Histogram of OrientedGradient, HOG)的方法。HOG特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。在一副图像中,局部目标的表象和形状能够被梯度和边缘的方向密度分布很好地描述,而HOG通过计算和统计图像局部区域的梯度方向直方图来构成特征。
HOG特征提取算法的实现过程如下:
1)将待检测的图像灰度化;
2)采用Gamma校正法对输入图像进行颜色空间的标准化(归一化)。目的是调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰。
3)计算图像每个像素的梯度(包括大小和方向)。主要是为了捕获轮廓信息,同时进一步弱化光照的干扰。
4)将图像划分成小cells(例如66像素/cell),并统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor。统计梯度直方图过程如下:假设我们采用9个bin的直方图来统计这66个像素的梯度信息。也就是将cell的梯度方向 分成9个方向块,
如果这个像素的梯度方向 是 或者 ,直方图第2个bin的计数就加1,这样,对cell内每个像素用梯度方向在直方图中进行加权投影(映射到固定的角度范围),就可以得到这个cell的梯度方向直方图了,就是该cell对应的9维特征向量(因为有9个bin)。梯度幅值 就是作为投影的权值的。例如说:这个像素的梯度方向是 ,然后它的梯度幅值 是2,那么直方图第2个bin的计数就不是加1了,而是加2。
4)将每几个cell组成一个block(例如3*3个cell/block),一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征descriptor;
5)将图像image内的所有block的HOG特征descriptor串联起来就可以得到该image的HOG特征descriptor了。这个就是最终的可供分类使用的特征向量了。
在我们的实验中使用OpenCV提供的HOG算子HOGDescriotiptor,它的构造函数HOGDescriptor * hog = new HOGDescriptor(Size _winSize,Size _blockSize, Size _blockStride ,Size _cellSize , int bins);相关参数设置如表2.1所示。接下来我们只需再调用hog-&compute()函数并以Image作为参数即可计算出其特征向量descriptors。
hog-&compute(Image, descriptors,Size(1,1), Size(0,0));
LibSVM配置
这里SVM的原理不就做介绍了,网上也有很多的资料介绍SVM
首先设置SVM参数。LibSVM提供了SVM参数结构svm_param,如下段代码所示,各参数意义如表2.2所示。
//配置SVM参数
param.svm_type = C_SVC;
param.kernel_type = RBF;
param.degree = 10.0;
param.gamma = 0.09;
param.coef0 = 1.0;
param.nu = 0.5;
param.cache_size = 1000;
param.C = 10.0;
param.eps = 1e-3;
param.p = 1.0;
在本实验中选择了C_SVC类型的SVM,并且选择了REF核函数。
将待训练的特征向量整理成LibSVM使用的数据格式。2.1.1中使用OpenCV提供的HOG方法得到了特征向量descriptors,要在LibSVM中使用上还需符合LibSVM的训练数据文件格式,如下所示
&label& &index1&:&value1& &index2&:&value2& ...
其中&label& 是训练数据集的目标值,对于分类,它是标识某类的整数(支持多个类)。&index& 是以1开始的整数,可以是不连续的,但是必须在结尾处标记为index=-1;&value&为实数,也就是我们提取出的特征向量。例如我们处理第一张手写图片train_0_0.jpg,该图片表示的是手写数字0,那么&label&标记为0;该图片用HOG方法描述的特征向量descriptor是长度为324的vector&float&,那么将&index1&~&index324&分别标记为0,1,2...323,&index325&标记为-1表示结束;&value1&~&value324&分别赋值为descriptor[0],descriptor[1],descriptor[2]...descriptor[323]。
调用svm_train函数开始训练,得到训练模型svm_model,并保存于“*.model”文件。前面两个步骤已经分别设置好了SVM的一系列参数param并整理了待训练特征向量的格式svm_prob,svm_train函数以param和svm_prob作为参数开始训练。
训练过程中输出如图所示,其中, #iter为迭代次数;nu是选择的核函数类型的参数;obj为SVM文件转换为的二次规划求解得到的最小值;rho为判决函数的偏置项b;nSV为标准支持向量个数(0&a[i]&c);nBSV为边界上的支持向量个数(a[i]=c);Total nSV为支持向量总个数(对于两类来说, 因为只有一个分类模型Total nSV = nSV但是对于多类,这个是各个分类模型的nSV之和)。
得到的“*.model”文件如下所示:
svm_type c_svc
//所选择的SVM类型,默认为c_svc
kernel_type rbf
//训练采用的核函数类型, 此处为RBF核
gamma 0.09
//RBF核的参数γ
nr_class 10
//类别数, 此处为数字0~9,即10个分类问题
total_sv 6364
//支持向量总个数
rho 1.52 -0.41 0....07 -0..069 -0....482 -1.7512 -0....97 2.593 0...519 0.9392 -1.059 -0...5213 -0..6359 -1.035 1.5451
//判决函数的偏置项b
label 0 1 2 3 4 5 6 7 8 9
//原始文件中的类别标识
nr_sv 427 402 677 676 791 569 489 717 805 811//每个类的支持向量机的个数
4)读入测试集图片,提取其HOG特征并整理成LibSVM使用的数据格式svm_node。测试集格式与训练集格式的唯一不同在于测试集不需要标记label,也具有index和value属性。
5)调用svm_predict函数进行测试。首先通过svm_model * 加载训练出的模型“*.Model”,svm_model 和svm_node作为svm_predict函数的参数,该函数以返回一个int类型的数据,即预测出的类别。
OpenCV SVM
除了2.1.2介绍的LibSVM工具,我们小组还尝试了OpenCV提供的SVM工具,它是基于LibSVM软件包开发的,优点是使用起来比LibSVM更简洁,下面简要的介绍一下OpenCV中SVM的训练和测试两阶段:
1)OpenCV中的SVM在训练阶段代码如下所示:
void trainSVM(CvMat * & dataMat,CvMat * & labelMat )
cout&&&train svm start&&&
cout&&dataMat&&
CvSVMP//这里是SVM训练相关参数
CvTermC //这里是迭代终止准则
criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
svm.train( dataMat, labelMat, NULL, NULL, param );//训练数据
svm.save( SVMModel.c_str());
cout&&&SVM Training Complete&&&
其中CvTermCriteria设置了迭代终止准则,最大迭代次数设为1000次,结果的精确性设为FLT_EPSILON = 1.19e-7;CvSVMParams设置了SVM相关的训练参数,参数具体设置仍如表2.1所示。与LibSVM不同的是,OpenCV不需要将特征向量整理成特定的格式,只需要特征向量按行顺序排好,给出它们的label,就可以调用训练函数svm.train()进行训练了。另外,OpenCV训练出的模型保存在“.xml”文件中而非LibSVM中的“.Model”文件,如图2.3所示。
最后所有的支持向量个数为6364个,与LibSVM完全一致,印证了OpenCV SVM底层是基于LibSVM的。
2)在测试阶段,OpenCV SVM的用法与LibSVM基本一致,调用svm.predict函数进行测试。首先通过CvSVM svm加载训练出的模型“*.xml”。接着将测试集图片的HOG向量整理成一个个CvMat,它作为svm_predict函数的参数输入,该函数以返回一个int类型的数据,即预测出的类别。
实验代码实现了LibSVM 和OpenCV SVM分类功能,完成了各个函数功能的封装,整个SVM分类器共分为8个函数,分别为:readTrainFileList、processHogFeature、trainSVM、trainLibSVM,readTestFileList,testLibSVM,testSVM,releaseAll。其中,每个函数的输入输出设置以及功能如下表所示:
本次实验使用“MNIST DATABASE”, 数据集包含了0-9数字手写体,共有60000张训练数据集,10000张测试数据集。测试集的前5000个例子取自原始NIST训练集,后5000取自原始NIST测试集,前5000个数据要比后5000个数据更干净、容易。
预测结果是输出到txt中的,通过Python脚本来分析
1)训练正确率
在训练集上进行正确率测试得到的结果是0.9884。
2)测试正确率
在10000张测试数据集上,我们的实验结果准确率为0.9884,其中10*10的举证结果如下,结果(i,j)代表将第i类错分为第j类的次数。
实验的主要错分类分析
实验中,有一些错分类很难避免,如4和9的错分以及7和2的错分,如下图所示。由于实验数据本身难以识别,造成的错分占据整个实验数据的1%左右。
阅读(...) 评论()2912人阅读
hog+svm(1)
& & & & & 想要训练分类器,首先要有样本,正样本和负样本,在这里就是有人的样本和没有人的样本,我的样本来源于”INRIA Person Dataset”这个网站,链接为,在下边有个蓝色here(970M),点击下载即可,也可以去我的网盘下载,地址,主要是外国网站太难下载了,我费了很大劲才下载成功,没必要因为样本耽误太多时间。
& & &下载了样本解压后,点击进去“96X160H96”这个文件夹里放的是正样本,“Train”文件夹下的“neg”放的是负样本,但是负样本需要处理一下才能成为训练分类器的负样本,处理代码如下:别忘了配置你的opencv环境,千万千万注意要更改图片文件的路径,换成你自己的。
#include &iostream&
#include &iostream&#include &fstream&
#include &stdlib.h& //srand()和rand()函数
#include &time.h& //time()函数
#include &opencv2/core/core.hpp&
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/imgproc/imgproc.hpp&
#include &opencv2/objdetect/objdetect.hpp&
#include &opencv2/ml/ml.hpp&
int CropImageCount = 0; //裁剪出来的负样本图片个数
int main()
string ImgN
char saveName[256];//裁剪出来的负样本图片文件名
ifstream fin(&INRIANegativeImageList.txt&);//打开原始负样本图片文件列表
//ifstream fin(&subset.txt&);
//一行一行读取文件列表
while(getline(fin,ImgName))
cout&&&处理:&&&ImgName&&
ImgName = &E:\\运动目标检测\\INRIAPerson\\Train\\neg\\& + ImgN
src = imread(ImgName,1);//读取图片
//src =cvLoadImage(imagename,1);
//cout&&&宽:&&&src.cols&&&,高:&&&src.rows&&
//图片大小应该能能至少包含一个64*128的窗口
if(src.cols &= 64 && src.rows &= 128)
srand(time(NULL));//设置随机数种子
//从每张图片中随机裁剪10个64*128大小的不包含人的负样本
for(int i=0; i&10; i++)
int x = ( rand() % (src.cols-64) ); //左上角x坐标
int y = ( rand() % (src.rows-128) ); //左上角y坐标
//cout&&x&&&,&&&y&&
Mat imgROI = src(Rect(x,y,64,128));
sprintf(saveName,&E:\\运动目标检测\\INRIAPerson\\negphoto\\noperson%06d.jpg&,++CropImageCount);//生成裁剪出的负样本图片的文件名
imwrite(saveName, imgROI);//保存文件
system(&pause&);
有了样本就可以训练分类器并进行识别测试了,代码如下:同样要配置自己的opencv环境,更改图片的路径
在训练分类器代码中要注意几个#define变量的值,修改这些值会在训练和加载已有分类器之间切换等等,可以自己看看研究下,代码不多,简单易懂。
#include &iostream&
#include &fstream&
#include &opencv2/core/core.hpp&
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/imgproc/imgproc.hpp&
#include &opencv2/objdetect/objdetect.hpp&
#include &opencv2/ml/ml.hpp&
#define PosSamNO 2400
//正样本个数
#define NegSamNO 12000
//负样本个数
#define TRAIN false
//是否进行训练,true表示重新训练,false表示读取xml文件中的SVM模型
#define CENTRAL_CROP true
//true:训练时,对96*160的INRIA正样本图片剪裁出中间的64*128大小人体
//HardExample:负样本个数。如果HardExampleNO大于0,表示处理完初始负样本集后,继续处理HardExample负样本集。
//不使用HardExample时必须设置为0,因为特征向量矩阵和特征类别矩阵的维数初始化时用到这个值
#define HardExampleNO 0
//继承自CvSVM的类,因为生成setSVMDetector()中用到的检测子参数时,需要用到训练好的SVM的decision_func参数,
//但通过查看CvSVM源码可知decision_func参数是protected类型变量,无法直接访问到,只能继承之后通过函数访问
class MySVM : public CvSVM
//获得SVM的决策函数中的alpha数组
double * get_alpha_vector()
return this-&decision_func-&
//获得SVM的决策函数中的rho参数,即偏移量
float get_rho()
return this-&decision_func-&
int main()
//检测窗口(64,128),块尺寸(16,16),块步长(8,8),cell尺寸(8,8),直方图bin个数9
HOGDescriptor hog(Size(64,128),Size(16,16),Size(8,8),Size(8,8),9);//HOG检测器,用来计算HOG描述子的
int DescriptorD//HOG描述子的维数,由图片大小、检测窗口大小、块大小、细胞单元中直方图bin个数决定
MySVM//SVM分类器
//若TRAIN为true,重新训练分类器
string ImgN//图片名(绝对路径)
ifstream finPos(&INRIAPerson96X160PosList.txt&);//正样本图片的文件名列表
//ifstream finPos(&PersonFromVOC2012List.txt&);//正样本图片的文件名列表
ifstream finNeg(&NoPersonFromINRIAList.txt&);//负样本图片的文件名列表
Mat sampleFeatureM//所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数
Mat sampleLabelM//训练样本的类别向量,行数等于所有样本的个数,列数等于1;1表示有人,-1表示无人
//依次读取正样本图片,生成HOG描述子
for(int num=0; num&PosSamNO && getline(finPos,ImgName); num++)
cout&&&处理:&&&ImgName&&
//ImgName = &D:\\DataSet\\PersonFromVOC2012\\& + ImgN//加上正样本的路径名
ImgName = &E:\\运动目标检测\\INRIAPerson\\96X160H96\\Train\\pos\\& + ImgN//加上正样本的路径名
Mat src = imread(ImgName);//读取图片
if(CENTRAL_CROP)
src = src(Rect(16,16,64,128));//将96*160的INRIA正样本图片剪裁为64*128,即剪去上下左右各16个像素
//resize(src,src,Size(64,128));
vector&float&//HOG描述子向量
pute(src,descriptors,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
cout&&&描述子维数:&&&descriptors.size()&&
//处理第一个样本时初始化特征向量矩阵和类别矩阵,因为只有知道了特征向量的维数才能初始化特征向量矩阵
if( 0 == num )
DescriptorDim = descriptors.size();//HOG描述子的维数
//初始化所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数sampleFeatureMat
sampleFeatureMat = Mat::zeros(PosSamNO+NegSamNO+HardExampleNO, DescriptorDim, CV_32FC1);
//初始化训练样本的类别向量,行数等于所有样本的个数,列数等于1;1表示有人,0表示无人
sampleLabelMat = Mat::zeros(PosSamNO+NegSamNO+HardExampleNO, 1, CV_32FC1);
//将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
for(int i=0; i&DescriptorD i++)
sampleFeatureMat.at&float&(num,i) = descriptors[i];//第num个样本的特征向量中的第i个元素
sampleLabelMat.at&float&(num,0) = 1;//正样本类别为1,有人
//依次读取负样本图片,生成HOG描述子
for(int num=0; num&NegSamNO && getline(finNeg,ImgName); num++)
cout&&&处理:&&&ImgName&&
ImgName = &E:\\运动目标检测\\INRIAPerson\\negphoto\\& + ImgN//加上负样本的路径名
Mat src = imread(ImgName);//读取图片
//resize(src,img,Size(64,128));
vector&float&//HOG描述子向量
pute(src,descriptors,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
//cout&&&描述子维数:&&&descriptors.size()&&
//将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
for(int i=0; i&DescriptorD i++)
sampleFeatureMat.at&float&(num+PosSamNO,i) = descriptors[i];//第PosSamNO+num个样本的特征向量中的第i个元素
sampleLabelMat.at&float&(num+PosSamNO,0) = -1;//负样本类别为-1,无人
//处理HardExample负样本
if(HardExampleNO & 0)
ifstream finHardExample(&HardExample_2400PosINRIA_12000NegList.txt&);//HardExample负样本的文件名列表
//依次读取HardExample负样本图片,生成HOG描述子
for(int num=0; num&HardExampleNO && getline(finHardExample,ImgName); num++)
cout&&&处理:&&&ImgName&&
ImgName = &D:\\DataSet\\HardExample_2400PosINRIA_12000Neg\\& + ImgN//加上HardExample负样本的路径名
Mat src = imread(ImgName);//读取图片
//resize(src,img,Size(64,128));
vector&float&//HOG描述子向量
pute(src,descriptors,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
//cout&&&描述子维数:&&&descriptors.size()&&
//将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
for(int i=0; i&DescriptorD i++)
sampleFeatureMat.at&float&(num+PosSamNO+NegSamNO,i) = descriptors[i];//第PosSamNO+num个样本的特征向量中的第i个元素
sampleLabelMat.at&float&(num+PosSamNO+NegSamNO,0) = -1;//负样本类别为-1,无人
//输出样本的HOG特征向量矩阵到文件
/* ofstream fout(&SampleFeatureMat.txt&);
for(int i=0; i&PosSamNO+NegSamNO; i++)
for(int j=0; j&DescriptorD j++)
{ fout&&sampleFeatureMat.at&float&(i,j)&&&
//训练SVM分类器
//迭代终止条件,当迭代满1000次或误差小于FLT_EPSILON时停止迭代
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
//SVM参数:SVM类型为C_SVC;线性核函数;松弛因子C=0.01
CvSVMParams param(CvSVM::C_SVC, CvSVM::LINEAR, 0, 1, 0, 0.01, 0, 0, 0, criteria);
cout&&&开始训练SVM分类器&&&
svm.train(sampleFeatureMat,sampleLabelMat, Mat(), Mat(), param);//训练分类器
cout&&&训练完成&&&
svm.save(&SVM_HOG.xml&);//将训练好的SVM模型保存为xml文件
else //若TRAIN为false,从XML文件读取训练好的分类器
//svm.load(&SVM_HOG_2400PosINRIA_12000Neg_HardExample(误报少了漏检多了).xml&);//从XML文件读取训练好的SVM模型
svm.load(&SVM_HOG.xml&);
/*************************************************************************************************
线性SVM训练完成后得到的XML文件里面,有一个数组,叫做support vector,还有一个数组,叫做alpha,有一个浮点数,叫做
将alpha矩阵同support vector相乘,注意,alpha*supportVector,将得到一个列向量。之后,再该列向量的最后添加一个元素rho。
如此,变得到了一个分类器,利用该分类器,直接替换opencv中行人检测默认的那个分类器(cv::HOGDescriptor::setSVMDetector()),
就可以利用你的训练样本训练出来的分类器进行行人检测了。
***************************************************************************************************/
DescriptorDim = svm.get_var_count();//特征向量的维数,即HOG描述子的维数
int supportVectorNum = svm.get_support_vector_count();//支持向量的个数
cout&&&支持向量个数:&&&supportVectorNum&&
Mat alphaMat = Mat::zeros(1, supportVectorNum, CV_32FC1);//alpha向量,长度等于支持向量个数
Mat supportVectorMat = Mat::zeros(supportVectorNum, DescriptorDim, CV_32FC1);//支持向量矩阵
Mat resultMat = Mat::zeros(1, DescriptorDim, CV_32FC1);//alpha向量乘以支持向量矩阵的结果
//将支持向量的数据复制到supportVectorMat矩阵中
for(int i=0; i&supportVectorN i++)
const float * pSVData = svm.get_support_vector(i);//返回第i个支持向量的数据指针
for(int j=0; j&DescriptorD j++)
//cout&&pData[j]&&& &;
supportVectorMat.at&float&(i,j) = pSVData[j];
//将alpha向量的数据复制到alphaMat中
double * pAlphaData = svm.get_alpha_vector();//返回SVM的决策函数中的alpha向量
for(int i=0; i&supportVectorN i++)
alphaMat.at&float&(0,i) = pAlphaData[i];
//计算-(alphaMat * supportVectorMat),结果放到resultMat中
//gemm(alphaMat, supportVectorMat, -1, 0, 1, resultMat);//不知道为什么加负号?
resultMat = -1 * alphaMat * supportVectorM
//得到最终的setSVMDetector(const vector&float&& detector)参数中可用的检测子
vector&float& myD
//将resultMat中的数据复制到数组myDetector中
for(int i=0; i&DescriptorD i++)
myDetector.push_back(resultMat.at&float&(0,i));
//最后添加偏移量rho,得到检测子
myDetector.push_back(svm.get_rho());
cout&&&检测子维数:&&&myDetector.size()&&
//设置HOGDescriptor的检测子
HOGDescriptor myHOG;
myHOG.setSVMDetector(myDetector);
//myHOG.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
//保存检测子参数到文件
ofstream fout(&HOGDetectorForOpenCV.txt&);
for(int i=0; i&myDetector.size(); i++)
fout&&myDetector[i]&&
/**************读入图片进行HOG行人检测******************/
Mat src = imread(&00000.jpg&);
//Mat src = imread(&.jpg&);
//Mat src = imread(&1.png&);
vector&Rect& found, found_//矩形框数组
cout&&&进行多尺度HOG人体检测&&&
myHOG.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);//对图片进行多尺度行人检测
//src为输入待检测的图片;found为检测到目标区域列表;参数3为程序内部计算为行人目标的阈值,也就是检测到的特征到SVM分类超平面的距离;
//参数4为滑动窗口每次移动的距离。它必须是块移动的整数倍;参数5为图像扩充的大小;参数6为比例系数,即测试图片每次尺寸缩放增加的比例;
//参数7为组阈值,即校正系数,当一个目标被多个窗口检测出来时,该参数此时就起了调节作用,为0时表示不起调节作用。
cout&&&找到的矩形框个数:&&&found.size()&&
//找出所有没有嵌套的矩形框r,并放入found_filtered中,如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
for(int i=0; i & found.size(); i++)
Rect r = found[i];
for(; j & found.size(); j++)
if(j != i && (r & found[j]) == r)
if( j == found.size())
found_filtered.push_back(r);
//画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
for(int i=0; i&found_filtered.size(); i++)
Rect r = found_filtered[i];
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(src, r.tl(), r.br(), Scalar(0,255,0), 3);
imwrite(&ImgProcessed.jpg&,src);
namedWindow(&src&,0);
imshow(&src&,src);
waitKey();//注意:imshow之后必须加waitKey,否则无法显示图像
/******************读入单个64*128的测试图并对其HOG描述子进行分类*********************/
////读取测试图片(64*128大小),并计算其HOG描述子
//Mat testImg = imread(&person014142.jpg&);
//Mat testImg = imread(&noperson000026.jpg&);
//vector&float&
//pute(testImg,descriptor,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
//Mat testFeatureMat = Mat::zeros(1,3780,CV_32FC1);//测试样本的特征向量矩阵
//将计算好的HOG描述子复制到testFeatureMat矩阵中
//for(int i=0; i&descriptor.size(); i++)
// testFeatureMat.at&float&(0,i) = descriptor[i];
//用训练好的SVM分类器对测试图片的特征向量进行分类
//int result = svm.predict(testFeatureMat);//返回类标
//cout&&&分类结果:&&&result&&
system(&pause&);
想下载我的程序可点击下列链接:
训练分类器:
负样本处理:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:41899次
排名:千里之外
原创:28篇
评论:43条
(1)(6)(1)(2)(3)(2)(2)(5)(1)(1)(1)(4)(3)(7)}

我要回帖

更多关于 svm训练正负样本 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信