I have come across one problem when trying to train data with SVM.
I get some different regions (set of connected pixels) from face images, and regions from eyes are very similar, so I want to use Hu moments for shape description and SVM for training.
But SVM does not work properly, method svm.predict evaluates afterwards everything as non-eye, moreover the same regions which were labeled and used in traning phase as eye, are evaluated as non-eye.
Feature data consists only of 7 Hu moments. I will post here some samples of source code in a moment, thanks in advance :)
Setting up basic svm for 1 image:
int image_regions = 10;
Mat training_mat(image_regions ,7,CV_32FC1); // 7 hu moments
Mat labels(image_regions ,1,CV_32FC1); // for labels 1 (eye) and -1 (non eye)
// computing hu moments
// putting them into svm traning mat
for (int k=0;k<huCounter;k++)
training_mat.at<float>(counter,k) = hu[k]; // counter is current number of region
//I use the following:
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 1e-6);
// ... do the above mentioned phase, and then:
svm.train(training_mat, labels, Mat(), Mat(), params);
I hope the following suggestions can help you..
The simplest task is to use a clustering algorithm and try to cluster my data into two classes. If an algorithm like k-means can do the job for me why to make things complex by using SVM and Neural Nets. I suggest you to use this technique because your feature vector dimension is very small size (7 Hu Moments) as well as your number of samples.
Perform a feature Normalization (specified in point 4) to make sure that the values falls in a limited range.
Check out is your data really separable? As your data is small, take few samples from positive images and few samples from negative images and plot the feature vectors. If you can visually see the difference surely any learning algorithm can do the job for you. As I said earlier simple tricks can do better than complex math.
If you really decided to use SVM only then you should know the following things
As I can see from your code you are using a Linear SVM, may be your data is non-separable by a linear kernel. Try using some polynomial kernel or other kernels. There is one option bool CvSVM::train_auto in openCV just have a look.
Try to check whether the feature vector values you are getting are proper values or not (make sure that they are not some garbage values).
Also you can perform feature normalization ZERO MEAN and UNIT VARIENCE before you use it for training.
Most importantly increase the number of images for training both positive and negative.
Last but not least SVM is not a magic, at the end of the day it is just drawing a line between two set of points. So dont expect it can classify anything you give.
If nothing works Just improve your feature extraction technique