支持向量机:将不同类样本在样本空间进行分割,得出一个间隔最大超平面。
调用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是说预测函数不会影响模型的内部状态,函数可以很安全地从不同的线程调用