2

我正在使用 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;
4

1 回答 1

8

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

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

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

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

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

于 2013-05-26T10:15:49.497 回答