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

时间:2013-05-26 07:10:10

标签: c++ opencv machine-learning libsvm

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

我在opencv文档中使用了基本的LINEAR SVM示例。我的问题是,为了我的目的,我可以使用该文档示例吗?我读过有关使用多类SVM的OCR系统。我是否需要这种多类SVM用于我的应用程序。我不明白这一点。请有人解释一下吗?这是我的代码。

我有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;

1 个答案:

答案 0 :(得分:8)

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

每个字母需要更多5000个样本而不是5个样本。您可以从MNIST手写数字数据集开始,直到您拥有正确的数据。

您的代码似乎训练svm只识别1个字符。你不应该这样做,因为它可能需要时间训练svm。您应该单独训练svm并保存模型,以便可以重复使用而无需每次都重新训练。

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

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