(OpenCV3.2.0)基于HOG特征的SVM训练与测试实例

这篇博客介绍了如何利用OpenCV3.2.0中的HOG特征和SVM进行对象检测。作者作为机器学习初学者,分享了分类器训练与测试的具体步骤,对相关头文件的引入也做了说明。
摘要由CSDN通过智能技术生成

本人作为一个机器学习的小菜鸟,在学习相关知识的过程中,CSDN博客给了我很大的帮助,作为回馈,我也来写点博客为后来者铺路。微笑微笑微笑

注意:在程序前需要包含一些必要的OpenCV头文件,我是将这些头文件写在了CvHeadFiles.h文件之中


#include  "CvHeadFiles.h"       
#include   <iostream>    
#include   <fstream>    
#include   <string>    
#include   <vector>  
using   namespace   cv;
using   namespace   cv::ml;
using   namespace   std;
int   main( int   argc ,   char **   argv )
{
         //--------------准备训练数据--------------------
         //定义相关变量
         int   ImgWidht = 24;
         int   ImgHeight = 24;
         vector < string > img_path;
         vector < int > img_catg;
         int   nLine = 0;
         string   buf;
         int   lab;
         ifstream   svm_data( "SVM_DATA.txt" );  
         unsigned   long   n;
         //依次读入样本的名和标签
         for (;;)
        {
               nLine++;
                if   (nLine % 2)
               {
                       svm_data   >>   buf;
                        if   (buf   ==   "end" )
                               break ;
                       img_path.push_back(buf); //图像路径  
               }
                else
               {
                       svm_data   >>   lab;
                       img_catg.push_back(lab);
               }
        }
        svm_data.close(); //关闭文件   
         //定义相关变量
         Mat   data_mat, res_mat;
         int   nImgNum = (nLine-1)/2;              //读入样本数量    
        res_mat   =   Mat ::zeros(nImgNum, 1,   CV_32SC1 );
         Mat   src;
         Mat   trainImg =   Mat ::zeros(ImgHeight, ImgWidht,   CV_8UC3 );    //需要分析的图片   
         //依次提取样本的HOG特征
         for   ( string :: size_type   i = 0; i != img_path.size(); i++)
        {
                //读入样本
               src   =   imread(img_path [ i ] .c_str(), 1);    //依次读入样本图片
               cout   <<   " processing "   <<   img_path [ i ] .c_str()   <<   endl;
               resize(src, trainImg, cv:: Size (ImgWidht, ImgHeight), 0, 0,   INTER_CUBIC );     //将样本图片调整为标准大小
               
                //对样本提取HOG特征向量
                HOGDescriptor   *hog =   new   HOGDescriptor (cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);    //具体意思见参考文章1,2      
                vector < float > descriptors;    //存放提取HOG特征向量的结果数组 
               hog->compute(trainImg, descriptors,   Size (1, 1),   Size (0, 0));   //对读入的样本图片提取HOG特征向量 
                if   (i == 0)
               {
                       data_mat   =   Mat ::zeros(nImgNum, descriptors.size(),   CV_32FC1 );   //根据输入图片大小进行分配空间  
               }
               cout   <<   "HOG dims: "   <<   descriptors.size()   <<   endl;
                //存储所提取的样本的HOG特征值
               n = 0;
                for   ( vector < float >:: iterator   iter = descriptors.begin();iter   !=   descriptors.end();iter ++ )
               {
                       data_mat.at< float >(i, n) =   * iter;
                       n++;
               }
               
                //存储样本的标签
               res_mat.at< int >(i, 0) = img_catg [ i ] ;
               cout   <<   " end processing "   <<   img_path [ i ] .c_str()   <<   " "   <<   img_catg [ i ]   <<   endl;
        }
        
         //----------------------------设置SVM参数---------------------------------
        cout   <<   "\n------------------------------------------------------------\n" ;
        cout   <<   "Starting training process"   <<   endl;
         Ptr < SVM > svm =   SVM ::create();
        svm -> setType( SVM :: C_SVC );
        svm -> setC(10);
        svm -> setKernel( SVM :: RBF );
        svm -> setTermCriteria( TermCriteria ( TermCriteria :: MAX_ITER , 10000, 1e-6));
        
         //-------------------------------训练SVM------------------------------------------      
        svm -> train(data_mat,   ROW_SAMPLE , res_mat);     //注意此处data_mat和res_mat的类型
         //利用训练数据和确定的学习参数,进行SVM学习      
        svm -> save( "SVM_DATA.xml" );
        cout   <<   "Finished training process"   <<   endl;
         //--------------------------------检测样本---------------------------------------   
         //依次读入测试样本名
         vector < string > img_tst_path;
         ifstream   img_tst( "SVM_TEST.txt" );
         for (;;)
        {
               img_tst   >>   buf;
                if   (buf   ==   "end" )
                        break ;
               img_tst_path.push_back(buf);
        }
        img_tst.close();
         //定义相关变量
         Mat   test;
         int   pos=0, neg=0,sum=0;
         char   line[512];
         ofstream   predict_txt( "SVM_PREDICT.txt" );
         for   ( string :: size_type   j = 0; j < img_tst_path.size(); j++)
        {
                //依次读入测试样本
               test   =   imread(img_tst_path [ j ] .c_str(), 1);     //读入图像    
               resize(test, trainImg, cv:: Size (ImgWidht, ImgHeight), 0, 0,   INTER_CUBIC );     //要搞成同样的大小才可以检测到        
               
                //提取测试样本的HOG特征
                HOGDescriptor   *hog =   new   HOGDescriptor (cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);   
                vector < float >descriptors; //结果数组      
               hog->compute(trainImg, descriptors,   Size (1, 1),   Size (0, 0));   //调用计算函数开始计算  
               cout   <<   "The Detection Result:"   <<   endl;
               cout   <<   "HOG dims: "   <<   descriptors.size()   <<   endl;
                //存储所提取的特征
                Mat   SVMtrainMat =   Mat ::zeros(1, descriptors.size(),   CV_32FC1 );
               n = 0;
                for   ( vector < float >:: iterator   iter = descriptors.begin();iter   !=   descriptors.end();iter ++ )
               {
                       SVMtrainMat.at< float >(0, n) =   * iter;
                       n++;
               }
                //对提取的特征进行检验
                int   ret = svm -> predict(SVMtrainMat);
                if   (ret == 1)
                       pos++;
                else
                       neg++;
               std::sprintf(line,   "%s %d\r\n" , img_tst_path [ j ] .c_str(), ret);
               printf( "%s %d\r\n" , img_tst_path [ j ] .c_str(), ret);
                //getchar();
               predict_txt   <<   line;
        }
        sum = neg + pos;
        cout   <<   "neg="   <<   neg   <<   "\n" ;
        cout   <<   "pos="   <<   pos   <<   "\n" ;
        cout   <<   "sum="   <<   sum   <<   "\n" ;
        predict_txt.close();
        system( "pause" );
         return   0;
}


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值