Mike Osvat
Mike Osvat

Reputation: 1

Hu moments and SVM does not work

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 :)


Additional info:

input image: https://i.sstatic.net/GyLO0.png

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
 Moments moments2=moments(croppedImage,false);
 double hu[7];
 HuMoments(moments2,hu);

 // 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
 if (isEye(...))
 {
  labels.at<float>(counter,0)=1.0;
 }
 else
 {
   labels.at<float>(counter,0)=-1.0;
 }

 //I use the following:
    CvSVM svm;
    CvSVMParams params;
    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);

Upvotes: 0

Views: 887

Answers (1)

G453
G453

Reputation: 1456

I hope the following suggestions can help you…..

  1. The simplest task is to use a clustering algorithm and try to cluster the data into two classes. If an algorithm like ‘k-means’ can do the job why make things complex by using SVM and Neural Nets. I suggest you use this technique because your feature vector dimension is of a very small size (7 Hu Moments) as well as your number of samples.

  2. Perform feature Normalization (specified in point 4) to make sure the values fall in a limited range.

  3. Check out “is your data really separable?” As your data is small, take a few samples from positive images and a 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.

  4. Only if you then decide to use SVM you should know the following:

    • 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 positively and negatively labeled.

    • Last but not least SVM is not magic, at the end of the day it is just drawing a line between two sets of points. So don’t expect it to classify anything you give it as input.

  5. If nothing works “Just improve your feature extraction technique”

Upvotes: 3

Related Questions