opencv3.0函数调用,svm训练分类器

本文介绍了一个使用HOG+SVM进行目标检测的C++实现案例。该案例详细展示了如何从图片中提取HOG特征,并利用SVM进行训练,最终保存训练好的模型。涉及HOG参数设置、特征提取流程及SVM训练过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>   
#include <fstream>   
#include <opencv2/opencv.hpp> 
#include <opencv2/ml/ml.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <string> 
#include <io.h>
using namespace std;
using namespace cv;
using namespace cv::ml;
#define PosSamNO 480    //正样本个数   
#define NegSamNO 3384  //负样本个数   
#define HardExampleNO //难例个数 
int  main(int argc, char** argv)
{
       //HOG检测器,用来计算HOG描述子的 
       //检测窗口(48,48),块尺寸(16,16),块步长(8,8),cell尺寸(8,8),直方图bin个数9   param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
       cv::HOGDescriptor hog(cv::Size(64, 64), cv::Size(16, 16), cv::Size(16, 16), cv::Size(8, 8), 9);
       int DescriptorDim;//HOG描述子的维数,由图片大小、检测窗口大小、块大小、细胞单元中直方图bin个数决定  
       
       SVM::Params params;
       params.svmType = SVM::C_SVC;
       params.C = 0.1;
       params.kernelType = SVM::LINEAR;//SVM::LINEAR;//SVM::LINEAR;
       params.termCrit = TermCriteria(TermCriteria::MAX_ITER, (int)10000, 1e-6);
       //正样本图片路径文件,具体通过图片生成图片路径文件的代码,在我上传的资源里面可以找到
       std::ifstream finPos("E:/opencv_studydocumence/opencv_study/HOG+SVM/code/Release/labels_20180206/svm20180206_x.txt");
       //负样本图片的文件列表 
       std::ifstream finNeg("E:/opencv_studydocumence/opencv_study/HOG+SVM/code/Release/labels_20180206/svmtrain_neg.txt");
       std::string ImgName;
       //所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数  
       cv::Mat sampleFeatureMat;
       //训练样本的类别向量,行数等于所有样本的个数,列数等于1;1表示有目标,-1表示无目标  
       cv::Mat sampleLabelMat;
       //依次读取正样本图片,生成HOG描述子   
       for (int num = 0; num < PosSamNO && getline(finPos, ImgName); num++)
       {
              std::cout << "Processing:" << ImgName << std::endl;
              std::cout << "1" << std::endl;
              cv::Mat image = cv::imread(ImgName);
              //HOG描述子向量  
              std::vector<float> descriptors;
              //计算HOG描述子,检测窗口移动步长(8,8) 
              hog.compute(image, descriptors, cv::Size(8, 8));
              //处理第一个样本时初始化特征向量矩阵和类别矩阵,因为只有知道了特征向量的维数才能初始化特征向量矩阵   
              if (0 == num)
              {
                     //HOG描述子的维数  
                     DescriptorDim = descriptors.size();
                     //初始化所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数sampleFeatureMat   
                     sampleFeatureMat = cv::Mat::zeros(PosSamNO + NegSamNO + HardExampleNO, DescriptorDim, CV_32FC1);
                     //初始化训练样本的类别向量,行数等于所有样本的个数,列数等于1  
                     sampleLabelMat = cv::Mat::zeros(PosSamNO + NegSamNO + HardExampleNO, 1, CV_32SC1);
              }
              //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat   
              for (int i = 0; i < DescriptorDim; i++)
              {
                     //第num个样本的特征向量中的第i个元素  
                     sampleFeatureMat.at<float>(num, i) = descriptors[i];
              }
              //正样本类别为17,有目标     
              sampleLabelMat.at<float>(num, 0) = 9;
       }
       //依次读取负样本图片,生成HOG描述子   
       for (int num = 0; num < NegSamNO && getline(finNeg, ImgName); num++)
       {
              std::cout << "-1"<< std::endl;
              std::cout << "Processing:" << ImgName << std::endl;
              cv::Mat src = cv::imread(ImgName);
              cv::resize(src, src, cv::Size(64, 64));
              //HOG描述子向量 
              std::vector<float> descriptors;
              //计算HOG描述子,检测窗口移动步长(8,8)  
              hog.compute(src, descriptors, cv::Size(8, 8));
              std::cout << "descriptor dimention:" << descriptors.size() << std::endl;
              //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat   
              for (int i = 0; i < DescriptorDim; i++)
              {
                     //第PosSamNO+num个样本的特征向量中的第i个元素 
                     sampleFeatureMat.at<float>(num + PosSamNO, i) = descriptors[i];
              }
              //负样本类别为-1,无目标 
              sampleLabelMat.at<float>(num + PosSamNO, 0) = -1;
       }
       //处理HardExample负样本   
       if (HardExampleNO > 0)
       {
              //HardExample负样本的文件列表  
              std::ifstream finHardExample("svmtrain_hard.txt");
              //依次读取HardExample负样本图片,生成HOG描述子   
              for (int num = 0; num < HardExampleNO && getline(finHardExample, ImgName); num++)
              {
                     std::cout << "2" << std::endl;
                     std::cout << "Processing:" << ImgName << std::endl;
                     cv::Mat src = cv::imread(ImgName, cv::IMREAD_GRAYSCALE);
                     cv::resize(src, src, cv::Size(64, 64));
                     //HOG描述子向量   
                     std::vector<float> descriptors;
                     //计算HOG描述子,检测窗口移动步长(8,8)  
                     hog.compute(src, descriptors, cv::Size(8, 8));
                     //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat   
                     for (int i = 0; i < DescriptorDim; i++)
                     {
                           //第PosSamNO+num个样本的特征向量中的第i个元素 
                           sampleFeatureMat.at<float>(num + PosSamNO + NegSamNO, i) = descriptors[i];
                     }
                     //负样本类别为-1,无目标  
                     sampleLabelMat.at<float>(num + PosSamNO + NegSamNO, 0) =2;
              }
       }
       //训练SVM分类器   
       //迭代终止条件,当迭代满1000次或误差小于FLT_EPSILON时停止迭代   
       std::cout << "start training SVM" << std::endl;
       //cout << "Starting training process" << endl;
       Ptr<SVM> svm = StatModel::train<SVM>(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat, params);
       cout << "Finished training process" << endl;
       //训练分类器   
       //svm->train(td);
       std::cout << "训练完成" << std::endl;
       //将训练好的SVM模型保存为xml文件 
       svm->save("20180206_xmls/svmx_20180206.xml");
       return 0;
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值