Reputation: 3688
i am developing a handwritten character recognition system using OpenCV LibSVM. i have extracted 14 features for the feature vector including Hu moments, affine invariant moments, numbers of corners etc. For each character, i use 5 samples( for letter "A", there 5 types of A's). I know 5 samples is not enough, but at the moments i have only 5 samples for each character.
I use the basic LINEAR SVM example in opencv documentation. My problem is, can i use that documentation example as it is, for my purpose. I have read about OCR systems that use multi- class SVMs. Do i need such Multi-Class SVM for my application. I do not understand about this. Please can someone explain ? Here is my code.
i have 180 samples of digits and English capital letters and for one sample there are 14 features.
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;
Upvotes: 2
Views: 7364
Reputation: 11941
The setup of your labels is incorrect. You have defined 180 unique labels, but you only have 26 classes of data. Labels should be 180 in lengeth but it should only contain the values 1..26 (any 26 distinct values will do) in an order that is in accord with the order of characters in mattrainingDataMat.
You will need more like 5000 samples of each letter rather than just 5. You could start with the MNIST hand-writen digits data set until you have proper data.
Your code seems to training an svm to just recognize 1 character. You shouldn't do it like that because it can take a long time to train an svm. You should train the svm separately and save the model so it can be reused without have to retrain everytime.
My understanding is that the svm code in OpenCV is based on an old version of Libsvm. So I just use the latest vesion of libsvm directly rather the OpenCV version.
Also, for your case you will almost surely get much better accurary with an RBF kernel than the linear kernel (although linear is easier to train). It seems you have 26 classes so of course you need a multiclass SVM (which is really just many binary SVMs) - Libsvm handles the multiclass issue for you.
Upvotes: 8