OpenCV解析SVM

支持向量机:将不同类样本在样本空间进行分割,得出一个间隔最大超平面。

调用OpenCV中SVM分类器流程如下:

1)建立训练样本

注意:CvSVM的train函数要求训练样本存储在float类型的Mat结构中,故需将训练数据存储为符合条件的Mat变量中。

2)设置SVM分类器参数

注意:此处主要涉及到SVM分类器相关参数设置。下面是自己对SVM分类器相关参数总结。

 参数介绍
degree:内核函数(POLY)的参数degree
gamma:内核函数(POLY/RBF/SIGMOID)的参数r
coef0:内核函数(POLY/SIGMOID)的参数coef0
Cvalue:SVM类型(C_SVC/EPS_SVR/NUSVR)的参数C
nu:SVM类型(NU_SVC/ONE_CLASS/NU_SVR)的参数v
p:SVM类型(EPS_SVR)的参数e
class_weights:C_SVC中的可选权重,赋给指定的类,乘以C以后变成class_weightssi*C。这些权重影响不同类别的错误分类惩罚项。权重越大,某一类的误分类数据的惩罚项就越大。
term_crit:SVM的训练过程的终止条件,解决部分受约束二次最优问题。可以指定公差和/或最大迭代次数。

struct SvmParams
{
    int         svmType;      // SVM类型
    int         kernelType;   // 核函数类型
    double      gamma;        // 针对多项式、rbf、sigmoid核函数设置参数
    double      coef0;        // 针对多项式、sigmoid核函数设置参数
    double      degree;       // 针对多项式核函数设置参数
    double      C;            // 损失函数,在C-SVC、e-SVR、v-SVR中有效
    double      nu;           // 设置v-SVC″、一类SVM、v-SVR参数
    double      p;            // 设置e-SVR中损失函数值
    Mat         classWeights; // C-SVC权重
    TermCriteria termCrit;    // SVM训练终止条件
// SVM参数默认值
    SvmParams()
    {
        svmType = SVM::C_SVC;
        kernelType = SVM::RBF;
        degree = 0;
        gamma = 1;
        coef0 = 0;
        C = 1;
        nu = 0;
        p = 0;
        termCrit = TermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
    }
	// SVmParams有参构造函数
    SvmParams( int _svmType, int _kernelType,
            double _degree, double _gamma, double _coef0,
            double _Con, double _nu, double _p,
            const Mat& _classWeights, TermCriteria _termCrit )
    {
        svmType = _svmType;
        kernelType = _kernelType;
        degree = _degree;
        gamma = _gamma;
        coef0 = _coef0;
        C = _Con;
        nu = _nu;
        p = _p;
        classWeights = _classWeights;
        termCrit = _termCrit;
    }
};

3)训练SVM分类器

训练SVM主要调用其中的train函数进行训练。

bool CvSVM::train( const Mat& _train_data, const Mat& _responses,
                  const Mat& _var_idx, const Mat& _sample_idx, CvSVMParams _params )
// 训练一个SVM分类器
// trainData:训练数据,数据类型为CV_32FC1(32位浮点类型,单通道)。数据必须是CV_ROW_SAMPLE的,即特征向量以行来存储。
// response:响应数据,通常是1D向量存储在CV_32FC1(仅仅用在分类问题上)或者CV_32FC1格式。
// varIdx:指定感兴趣的特征,可以是整数向量,以0开始索引,或8位的使用的特征或样本的掩码。用户可传入NULL指针,用来训练中所用的变量和样本。
// sampleIdx:指定感兴趣的样本
// parames:SVM参数

4)用训练得到的支持向量机进行分类

float CvSVM::predict( const CvMat* sample, bool returnDFVal ) const
// 利用SVM分类器进行预分类操作
// 对输入样本做预测响应
// sample:需要预测的输入样本
// returnDFVal:指定返回值类型,如果为true,则是一个2类分类问题,该方法返回的决策函数值是边缘的符号距离
// 这个函数用来预测一个样本的响应数据;在分类问题中,这个函数返回类别编号;在回归问题中,返回函数值;
// 输入的样本必须与传给trainData的训练样本同样大小;如果训练中使用了varIdx参数,则在predict函数中使用跟训练特征一致的特征;
// 后缀const是说预测函数不会影响模型的内部状态,函数可以很安全地从不同的线程调用


你可能感兴趣的:(OpenCV解析SVM)