我正在开发一个使用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;
答案 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为你处理多类问题。