Why this code gives me this error: "train data must be floating-point matrix"
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;
}
}
sure, we need to see code, but that's a whole wall of it. could you restrict it to the svm() function ?
Thank you for reply, But I think the whole of code is relative to problem. Ok I will change it.
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.
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?
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!
" my input image is a 32bit image" - oh, i see. you should check the img.type() first, though.