如何在OpenCV和c++中配置CvSVM进行图像分类

How to configure CvSVM for image classification in OpenCV and C++

本文关键字:CvSVM 配置 图像分类 c++ OpenCV      更新时间:2023-10-16

我正在使用OpenCV LibSVM开发一个手写字符识别系统。我为特征向量提取了14个特征,包括Hu矩、仿射不变矩、角数等。对于每个字符,我使用5个样本(对于字母"A",有5种类型的A)。我知道5个样本是不够的,但目前我每个字符只有5个样本。

我使用opencv文档中的基本线性支持向量机示例。我的问题是,我可以使用该文档的例子,因为它是我的目的。我读过关于使用多类支持向量机的OCR系统。我的应用需要这样的多类支持向量机吗?我不明白这一点。有人能解释一下吗?这是我的代码。

我有180个数字和英文大写字母的样本,其中一个样本有14个特征。

float labels[180][1] = {1.0, 2.0, 3.0, 4.0, 5.0, ,,,,, -> 180.0};
Mat matlabesls(180,1, CV_32FC1, labels);
Mat mattrainingDataMat(180, 14, CV_32FC1, ifarr_readtrainingdata);
CvSVMParams params;
params.svm_type    = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
CvSVM SVM;
SVM.train(mattrainingDataMat,matlabesls,Mat(),Mat(),params);
Mat matinput(1,14,CV_32FC1,ifarr_testarray);
is_recognizedcharacter= SVM.predict(matinput);
return is_recognizedcharacter;

标签设置不正确。您已经定义了180个唯一标签,但只有26个数据类。标签的长度应该是180,但它应该只包含值1..26(任何26个不同的值都可以),其顺序与mattrainingDataMat中的字符顺序一致。

每个字母你需要5000个样本,而不是5个。您可以从MNIST手写数字数据集开始,直到获得适当的数据。

你的代码似乎训练svm只识别1个字符。你不应该这样做,因为它可以花费长的时间来训练svm。你应该单独训练svm并保存模型,这样它就可以被重用,而不必每次都重新训练。

我的理解是OpenCV中的svm代码基于Libsvm的版本。所以我直接使用最新版本的libsvm,而不是OpenCV版本。

同样,对于你的情况,你几乎肯定会得到更好的准确性与RBF核比线性核(尽管线性更容易训练)。看起来你有26个类,所以你当然需要一个多类SVM(这实际上只是许多二进制SVM) - Libsvm为你处理多类问题。