Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
im learning about SVM, so im making a sample program that trains an SVM to detect if a symbol is in an image or if its not. All the images are black and white (the symbols would be black and the background white). I have 12 training images, 6 positives (with the symbol) and 6 negatives (without it). Im using hu moments to get the descriptors of every image and then i construct the training matrix with those descriptors. also i have a Labels matrix, which contains a label for each image: 1 if its positive and 0 if its negative. but im getting an error (something like a segmentation fault) at the line where i train the SVM. here is my code:


C#
using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    //arrays where the labels and the features will be stored
    float labels[12] ;
    float trainingData[12][7] ;

    Moments moment;
    double hu[7];

  //===============extracting the descriptos for each positive image=========
    for ( int i = 0; i <= 5; i++){

        //the images are called t0.png ... t5.png and are in the folder train
        std::string path("train/t");
        path += std::to_string(i);
        path += ".png";

        Mat input = imread(path, 0); //read the images
        bitwise_not(input, input); //invert black and white
        Mat BinaryInput;
        threshold(input, BinaryInput, 100, 255, cv::THRESH_BINARY); //apply theshold

        moment = moments(BinaryInput, true); //calculate the moments of the current image
        HuMoments(moment, hu); //calculate the hu moments (this will be our descriptor)

        //setting the row i of the training data as the hu moments
        for (int j = 0; j <= 6; j++){
            trainingData[i][j] = (float)hu[j];
        }

        labels[i] = 1; //label=1 because is a positive image
    }

  //===============extracting the descriptos for each negative image=========
    for (int i = 0; i <= 5; i++){

        //the images are called tn0.png ... tn5.png and are in the folder train
        std::string path("train/tn");
        path += std::to_string(i);
        path += ".png";

        Mat input = imread(path, 0); //read the images
        bitwise_not(input, input); //invert black and white
        Mat BinaryInput;
        threshold(input, BinaryInput, 100, 255, cv::THRESH_BINARY); //apply theshold

        moment = moments(BinaryInput, true); //calculate the moments of the current image
        HuMoments(moment, hu); //calculate the hu moments (this will be our descriptor)

        for (int j = 0; j <= 6; j++){
            trainingData[i + 6][j] = (float)hu[j];
        }

         labels[i + 6] = 0;  //label=0 because is a negative image

    }

//===========================training the SVM================
    //we convert the labels and trainingData matrixes to Mat objects
    Mat labelsMat(12, 1, CV_32FC1, labels);
    Mat trainingDataMat(12, 7, CV_32FC1, trainingData);

    //create the SVM
    Ptr<ml::SVM> svm = ml::SVM::create();

    //set the parameters of the SVM
    svm->setType(ml::SVM::C_SVC);
    svm->setKernel(ml::SVM::LINEAR);
    CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
    svm->setTermCriteria(criteria);

     //Train the SVM !!!!!HERE OCCURS THE ERROR!!!!!!
     svm->train(trainingDataMat, ml::ROW_SAMPLE, labelsMat);


    //Testing the SVM...
    Mat test = imread("train/t1.png", 0); //this should be a positive test
    bitwise_not(test, test);
    Mat testBin;
    threshold(test, testBin, 100, 255, cv::THRESH_BINARY);

    Moments momentP = moments(testBin, true); //calculate the moments of the test image

    double huP[7];
    HuMoments(momentP, huP);

    Mat testMat(1, 7, CV_32FC1, huP); //setting the hu moments to the test matrix

    double resp = svm->predict(testMat); //pretiction of the SVM
    printf("%f", resp); //Response

    getchar();

}


i know that the program is running fine until that line because i printed labelsMat and trainingDataMat and the values inside them are ok. Even in the console i can see that the program is running fine until that exact line executes. the console then shows this message:

C#
OpenCV error: Bad argument (in the case of classification problem the responses must be categorical;  either specify varType when creating TrainDatam or pass integer responses)


i dont really know what this means. any idea of what could be causing the problem? if you need any other details please tell me.
Posted
Updated 22-Dec-15 11:46am
v2
Comments
nv3 23-Dec-15 3:42am    
See http://stackoverflow.com/questions/31287207/opencv-svm-training-data for the solution of your problem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900