SVM实践之OPENCV模块

转自:https://blog.csdn.net/chaipp0607/article/details/68067098/

特征选取
其实特征提取和数据的准备是同步完成的,我们最后要训练的也是正负样本的特征。本例程中同样在getBubble()与getNoBubble()函数中完成特征提取工作,只是我们简单粗暴将整个图的所有像素作为了特征,因为我们关注更多的是整个的训练过程,所以选择了最简单的方式完成特征提取工作,除此中外,特征提取的方式有很多,比如LBP,HOG等等。

  SrcImage= SrcImage.reshape(1, 1);

我们利用reshape()函数完成特征提取,原型如下:

 Mat reshape(int cn, int rows=0) const;

可以看到该函数的参数非常简单,cn为新的通道数,如果cn = 0,表示通道数不会改变。参数rows为新的行数,如果rows = 0,表示行数不会改变。我们将参数定义为reshape(1, 1)的结果就是原图像对应的矩阵将被拉伸成一个一行的向量,作为特征向量。
参数配置
参数配置是SVM的核心部分,在Opencv中它被定义成一个结构体类型,如下:

struct CV_EXPORTS_W_MAP CvSVMParams
{
    CvSVMParams();
    CvSVMParams(  
    int svm_type, 
    int kernel_type,
    double degree, 
    double coef0,
    double Cvalue, 
    double p,
    CvMat* class_weights, 
    CvTermCriteria term_crit );
    CV_PROP_RW int         svm_type;
    CV_PROP_RW int         kernel_type;
    CV_PROP_RW double      degree; // for poly
    CV_PROP_RW double      gamma;  // for poly/rbf/sigmoid
    CV_PROP_RW double      coef0;  // for poly/sigmoid
    CV_PROP_RW double      C;  // for CV_SVM_C_SVC,       CV_SVM_EPS_SVR and CV_SVM_NU_SVR
    CV_PROP_RW double      nu; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR
    CV_PROP_RW double      p; // for CV_SVM_EPS_SVR
    CvMat*      class_weights; // for CV_SVM_C_SVC
    CV_PROP_RW CvTermCriteria term_crit; // termination criteria
};

所以在例程中我们定义了一个结构体变量用来配置这些参数,而这个变量也就是CVSVM类中train函数的第五个参数,下面对参数进行说明。
SVM_params.svm_type :SVM的类型:
C_SVC表示SVM分类器,C_SVR表示SVM回归
SVM_params.kernel_type:核函数类型
线性核LINEAR:
d(x,y)=(x,y)
多项式核POLY:
d(x,y)=(gamma*(x’y)+coef0)degree
径向基核RBF:
d(x,y)=exp(-gamma*|x-y|^2)
sigmoid核SIGMOID:
d(x,y)= tanh(gamma*(x’y)+ coef0)

SVM_params.degree:核函数中的参数degree,针对多项式核函数;
SVM_params.gama:核函数中的参数gamma,针对多项式/RBF/SIGMOID核函数;
SVM_params.coef0:核函数中的参数,针对多项式/SIGMOID核函数;
SVM_params.c:SVM最优问题参数,设置C-SVCEPS_SVRNU_SVR的参数;
SVM_params.nu:SVM最优问题参数,设置NU_SVCONE_CLASSNU_SVR的参数;
SVM_params.p:SVM最优问题参数,设置EPS_SVR 中损失函数p的值.
训练模型

CvSVM svm;
svm.train(trainingData, classes, Mat(), Mat(), SVM_params);

通过上面的过程,我们准备好了待训练的数据和训练需要的参数,其实可以理解为这个准备工作就是在为svm.train()函数准备实参的过程。来看一下svm.train()函数,Opencv将SVM封装成CvSVM库,这个库是基于台湾大学林智仁(Lin Chih-Jen)教授等人开发的LIBSVM封装的,由于篇幅限制,不再全部粘贴库的定义,所以一下代码只是CvSVM库中的一部分数据和函数:

class CV_EXPORTS_W CvSVM : public CvStatModel
{
public:
virtual bool train( 
  const CvMat* trainData, 
  const CvMat* responses,
  const CvMat* varIdx=0, 
  const CvMat* sampleIdx=0,
  CvSVMParams params=CvSVMParams() );
virtual float predict( 
  const CvMat* sample, 
  bool returnDFVal=false ) const;

我们就是应用类中定义的train函数完成模型训练工作。
保存模型

svm.save("svm.xml");

保存模型只有一行代码,利用save()函数,我们看下它的定义:

    CV_WRAP virtual void save( const char* filename, const char* name=0 ) const;

该函数被定义在CvStatModel类中,CvStatModel是ML库中的统计模型基类,其他 ML 类都是从这个类中继承。

总结:到这里我们就完成了模型训练工作,可以看到真正用于训练的代码其实很少,OpenCV对支持向量机的封装极大地降低了我们的编程工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值