SVM训练样本方法总结(用于目标识别)

http://blog.csdn.net/xw20084898/article/details/21389885 原文链接


目录(?)[-]

  1. 引言
  2. 步骤
  3. 1生成SVM描述文件
  4. 2将描述文件读入容器中
  5. 3读入样本数量生成样本矩阵和类型矩阵
  6. 4读入样本图像
  7. 5提取HOG特征
  8. 6将HOG特征写入txt文件
  9. 7进行SVM训练
SVM样本训练步骤

尊重原创,转载本文请说明出处:http://blog.csdn.net/xw20084898/article/details/21389885

1、引言

近期在做飞形体目标识别的研究,需要做SVM训练来生成识别的分类器。从网上找了大量的参考文章,但是发现很多文章都讲的比较零散。鉴于此原因,本文对SVM训练过程做一个较为系统的总结,希望对广大初学者有所帮助。

2、步骤

(1)生成SVM描述文件;

将需要训练的样本文件的路径和对应的分类类别号写入txt文档,如:
plane/飞机训练正样本Normalize/0.jpg
1
plane/飞机训练正样本Normalize/1.jpg            命名为:SVM_DATA.txt
1

(2)将描述文件读入容器中;

定义两个容器,用于保存样本路径和分类标号,如:

 vector img_path;  
     
   vector img_catg;  

读入数据:

         int nLine = 0;  
   string buf;  
   ifstream svm_data( "SVM_DATA.txt" ); 

[cpp]  view plain copy
  1.  while( svm_data )    
  2.         {    
  3.             if( getline( svm_data, buf) )   
  4.         /*原型 
  5.   istream& getline ( istream &is , string &str , char delim );   istream& getline ( istream& , string& ); 
  6. 参数  is 进行读入操作的输入流   str 存储读入的内容   delim 终结符    返回值 与参数is是一样的 
  7. 功能  将输入流is中读到的字符存入str中,直到遇到终结符delim才结束。 
  8.   对于第一个函数delim是可以由用户自己定义的终结符;对于第二个函数delim默认为 '\n'(换行符)。    
  9.   函数在输入流is中遇到文件结束符(EOF)或者在读入字符的过程中遇到错误都会结束。    
  10.   在遇到终结符delim后,delim会被丢弃,不存入str中。在下次读入操作时,将在delim的下个字符开始读入。*/   
  11.             {    
  12.             nLine ++;    
  13.             if( nLine % 2 == 0 )    
  14.                 {    
  15.                      img_catg.push_back( atoi( buf.c_str() ) );//atoi将字符串转换成整型,值为0或1  用0,1区分正负样本  
  16.                      //功 能: 把字符串转换成整型数。   名字来源:array to integer 的缩写。     
  17.                      //原型: int atoi(const char *nptr);     
  18. //函数说明: 参数nptr字符串,如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,  
  19. //之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。   
  20.                     // 函数声明:const char *c_str();   c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.   
  21.             }    
  22.             else    
  23.                 {    
  24.                 img_path.push_back( buf );//图像路径     
  25.                 }    
  26.             }    
  27.         }    
  28.         svm_data.close();//关闭文件     

3)读入样本数量,生成样本矩阵和类型矩阵

[cpp]  view plain copy
  1. CvMat *data_mat, *res_mat;    
  2.         int nImgNum = nLine / 2;            //读入样本数量     
  3.     ////样本矩阵,nImgNum:横坐标是样本数量, WIDTH * HEIGHT:样本特征向量,即图像大小     
  4.         data_mat = cvCreateMat( nImgNum, 144, CV_32FC1 );    
  5.         cvSetZero( data_mat );    
  6.         //类型矩阵,存储每个样本的类型标志     
  7.         res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );    
  8.         cvSetZero( res_mat );    

(4)读入样本图像

[cpp]  view plain copy
  1. IplImage* src;    
  2.     IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);//需要分析的图片  
  3.       
  4.    
  5.     for( string::size_type z = 0; z != img_path.size(); z++ )    //整体循环为z  
  6.     {    
  7.            src=cvLoadImage(img_path[z].c_str(),1);   
  8.         // 函数声明:const char *c_str();c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.    
  9.             if( src == NULL )    
  10.             {    
  11.                 cout<<" can not load the image: "<
  12.                continue;    
  13.             }    
  14.     
  15.             cout<<" processing "<

5)提取HOG特征

[cpp]  view plain copy
  1.  //以下为提取Hog特征  
  2.                cvResize(src,trainImg);   //读取图片,归一化大小        
  3.                HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(16,16),cvSize(16,16),9);    
  4.   
  5.                 vector<float>descriptors;//结果数组        
  6.                 hog->compute(trainImg, descriptors,Size(8,8), Size(0,0)); //调用计算函数开始计算        
  7.                 cout<<"HOG dims: "<
  8.                 //CvMat* SVMtrainMat=cvCreateMat(descriptors.size(),1,CV_32FC1);     
  9.                 n=0;    
  10.                 for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)    //迭代器  
  11.                 {    
  12.                 cvmSet(data_mat,z,n,*iter);   //将HOG特征 存入data_mat矩阵中  
  13. x=cvmGet(data_mat,z,n);  
  14. cout<<"hog"<
  15.                     n++;    
  16.                 }  

6)将HOG特征写入txt文件

[cpp]  view plain copy
  1. FILE *fp1;  
  2.     int i,j;  
  3.     if((fp1=fopen("Hog.txt","ab"))==NULL)// 读写打开一个二进制文件,允许读或在文件末追加数据。  
  4.     {  
  5.         printf("can not open the hu file\n");  
  6.         exit(0);//正常退出程序  
  7.     }  
  8.     for (i = 0; i <144; ++i)   
  9.     {  
  10.         fprintf(fp1,"%lf ",descriptors[i]);   
  11.     }  
  12.         //fprintf(fp1,"\r\n");  
  13.     fclose(fp1);  
  14.   
  15.                 cvmSet( res_mat, z, 0, img_catg[z] );   //将正负样本标记存入矩阵res_mat中  
  16.                 cout<<" end processing "<" "<
  17.     }    

7)进行SVM训练

[cpp]  view plain copy
  1. CvSVM svm = CvSVM();      
  2.     CvSVMParams param;      
  3.     CvTermCriteria criteria;      
  4.        criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );      
  5.     param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );      
  6. /*     
  7.     SVM种类:CvSVM::C_SVC     
  8.     Kernel的种类:CvSVM::RBF     
  9.     degree:10.0(此次不使用)     
  10.     gamma:8.0     
  11.    coef0:1.0(此次不使用)     
  12.     C:10.0     
  13.     nu:0.5(此次不使用)     
  14.    p:0.1(此次不使用)     
  15.    然后对训练数据正规化处理,并放在CvMat型的数组里。     
  16.                                                         */         
  17.     //SVM学习          
  18.     svm.train( data_mat, res_mat, NULL, NULL, param );      
  19.     //利用训练数据和确定的学习参数,进行SVM学习        
  20.     svm.save( "SVM_DATA1.xml" );     
  21.   
  22.     cvReleaseImage(&src);  
  23.     cvReleaseMat( &data_mat );   
  24.     cvReleaseMat( &res_mat );    
  25.      return 0;  

在以上训练过程中,要特别注意的是在创建样本矩阵的时候,其矩阵大小由样本数量和样本提取的特征维数决定的。比如上面创建的样本矩阵大小为:
[cpp]  view plain copy
  1. int nImgNum = nLine / 2; 行,144列;  144是由提取HOG特征时,由窗口大小、块大小、胞元大小和每个抱怨大小中的特征数共同决定的。  

你可能感兴趣的:(HOG算子)