Why this code gives me this error: "train data must be floating-point matrix"

asked 2014-06-28 00:36:03 -0600

prince0fpersia gravatar image

updated 2014-06-28 01:58:44 -0600

How can I correct this program? I want to read 100 binary images, do some process on them, save the results as 40 length arrays, give a label to each picture and finally train them in SVM classification. This is my first experience to use SVM and I don't know how can I correct the problem?

int detection
{
    if(number==0)
    {
        labels[g1]=0;

    }
    if(number==1)
    {
        labels[g1]=1;

    }
    if(number==2)
    {
        labels[g1]=2;

    }
    if(number==3)
    {
        labels[g1]=3;

    }
    if(number==4)
    {
        labels[g1]=4;

    }
    if(number==5)
    {
        labels[g1]=5;
    }
    if(number==6)
    {
        labels[g1]=6;
    }
    if(number==7)
    {
        labels[g1]=7;

    }
    if(number==8)
    {
        labels[g1]=8;

    }
    if(number==9)
    {
        labels[g1]=9;

    }

    } //detection


    //SVM classification (Our fitness function)

    int svm()
    {
            CvSVM SVM;


        for(g1=0; g1<100; g1++)
        {
        for(number=0; number<10; number++)
        {
            Mat img(32, 32, CV_32FC1);
            img=imread(format("/home/chris/bang/bn%04d%d.bmp",g1,number ), CV_LOAD_IMAGE_GRAYSCALE);
            detection(img);


        Mat labelsMat(100, 1, CV_32FC1, labels);


        CvSVMParams params;
        params.svm_type    = CvSVM::C_SVC;
        params.kernel_type = CvSVM::RBF;
        params.gamma=0.5;


        SVM.train(img, labelsMat, Mat(), Mat(), params);
        }

        srand(time(NULL));
        int random=(rand() % 6000);

        Mat image=imread(format("/home/chris/bang/bn%05d",random), CV_LOAD_IMAGE_GRAYSCALE);
        detection(image);
        response= SVM.predict(image);



    return response;

        }
    }
edit retag flag offensive close merge delete

Comments

1

sure, we need to see code, but that's a whole wall of it. could you restrict it to the svm() function ?

berak gravatar imageberak ( 2014-06-28 01:27:50 -0600 )edit

Thank you for reply, But I think the whole of code is relative to problem. Ok I will change it.

prince0fpersia gravatar imageprince0fpersia ( 2014-06-28 01:51:14 -0600 )edit

oh, better now. well, you need float data for the svm, but your img is not. imread just overwrites the Mat with grayscale, CV_8U data. so it would need a convertTo after that (before won't work).

also then, you're training the svm on 1 image only, and repeat that in a loop ? that's clearly wrong.

in the loop, you should reshape(1,1) your image to a single line, push_back() that into a train Mat, and later train the svm on all 100 or so (flattened) images.

see, e.g. here

also, to my exp., multi-class svm does not work properly using an RBF kernel. try POLY or LINEAR instead.

berak gravatar imageberak ( 2014-06-28 02:09:59 -0600 )edit

I changed the code but a new problem occurred. In my detection function I got the images intensity values by this code " int pix_val=(int)img.at<uchar>(x,y); "

But now I don't know how can I get the values? I should say my images are binary(black and white) with ".bmp" format. I used that code to know which pixels are black! now, how can I do that?

prince0fpersia gravatar imageprince0fpersia ( 2014-06-28 03:06:13 -0600 )edit
  • int pix_val=(int)img.at<uchar>(y,x); // not x,y - we're in row , col world here (but not sure, if i understood you correctly here)
  • there is countNonZero(mat) - did you mean that ?
berak gravatar imageberak ( 2014-06-28 05:25:04 -0600 )edit

I meant x=row position and y=column position of a pixel of an image! In past my image was grayscale 8-bit image, and I could read each pixel intensity by that code, but now I've changed my code and my input image is a 32bit image , so i don't know how can I find black pixels in my images!

prince0fpersia gravatar imageprince0fpersia ( 2014-06-28 06:45:00 -0600 )edit

" my input image is a 32bit image" - oh, i see. you should check the img.type() first, though.

  • if it is CV_32S, (3), a single, 32bit grayscale channel, use int pix_val=(int)img.at<int>(y,x);
  • if it is CV_8UC4, (16), then you got 4 8bit channels, Vec4b pix=img.at<Vec4b>(y,x); uchar &b = pix[0]; //...etc
berak gravatar imageberak ( 2014-06-28 07:30:31 -0600 )edit