# Getting error using SVM with SURF

Below is some part of my code , which is running fine but after a long processing it show me the run time error

Initialization part

std::vector< DMatch > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor();

SurfFeatureDetector detector(500);
std::vector<KeyPoint> keypoints;
int dictionarySize = 1500;
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bow(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor dextract(extractor,matcher);

// Initialize constant values
const int nb_cars = files.size();
const int not_cars = files_no.size();
const int num_img = nb_cars + not_cars; // Get the number of images


As my personal approach i think error starts from here

// Initialize your training set.
cv::Mat training_mat(num_img,image_area,CV_32FC1);
cv::Mat labels(num_img,1,CV_32FC1);
std::vector<string> all_names;
all_names.assign(files.begin(),files.end());
all_names.insert(all_names.end(), files_no.begin(), files_no.end());
int count = 0;
Mat unclustered;
vector<string>::const_iterator i;
string Dir;
for (i = all_names.begin(); i != all_names.end(); ++i)
{
Dir=( (count < files.size() ) ? YourImagesDirectory : YourImagesDirectory_2);

tmp_img = cv::imread( Dir +*i, 0 );

resize( tmp_img, tmp_dst, tmp_dst.size() );

Mat row_img = tmp_dst; // get a one line image.

detector.detect( row_img, keypoints);

extractor->compute( row_img, keypoints, descriptors_1);

unclustered.push_back(descriptors_1);

++count;
}

cout<<"second part";
int count_2=0;
vector<string>::const_iterator k;
Mat vocabulary = bow.cluster(unclustered);
dextract.setVocabulary(vocabulary);
for (k = all_names.begin(); k != all_names.end(); ++k)
{
Dir=( (count_2 < files.size() ) ? YourImagesDirectory : YourImagesDirectory_2);

tmp_img = cv::imread( Dir +*k, 0 );

resize( tmp_img, tmp_dst, tmp_dst.size() );

Mat row_img = tmp_dst; // get a one line image.

detector.detect( row_img, keypoints);

dextract.compute( row_img, keypoints, descriptors_1);

training_mat.push_back(descriptors_1);

labels.at< float >(count_2, 0) = (count_2<nb_cars)?1:-1; // 1 for car, -1 otherwise*/

++count_2;
}


After processing sometime it show me the below runtime error Error :

Edit :

Mat training_mat(0,dictionarySize,CV_32FC1);


to

Mat training_mat(1,extractor->descriptorSize(),extractor->descriptorType());


but didn't solve the problem

edit retag close merge delete

You are not willing to learn, are you? Your "question" is still a heap of code without proper formatting nor a precise problem description. sigh

( 2013-08-23 16:11:31 -0500 )edit

@SR How i know where i am doing mistake its runtime logical error , if it was syntax than i will paste only that part , if i knw where i did mistake than why i post the question here ? and i post the small peace of code here and its dont have error than i post the second part and so on ? i think i did the coding on my own and i am here for help not for coding , thats why i mention the error here , i think my question is short and clear , i just want to know the error and that's it

( 2013-08-24 02:05:03 -0500 )edit

Sort by » oldest newest most voted

dear FLY, do yourself a favour, leave that code alone for a while.

imho, you got 2 major problems there:

• seems you can't code your way out of a paper bag. (sorry for the harsh truth, but unless you solve that, this won't go anywhere)
• you're totally impatient. you're still having problems processing your data for a svm, yet you're messing with bow.

i can only try to address the 2nd problem

you don't have to resize the images. SURF is scale invariant, just trust in it.

you've got to find a way how to properly use an SVM with your descriptors:

extractor->compute( row_img, keypoints, descriptors_1);


descriptors_1 will be a Mat with n rows, one for each descriptor found in the image. n will vary for each image(it'll find 3 descriptors in one image, 5 in another).

since SVM expects all training vecs to have the same length, you'll have to find a way dealing with that, either :

• some procrustes approach( limit it to a fixed number of descriptors, and ignore images that give less ), then reshape(1,1), that desc-mat to a single row [there's your runtime error, btw]
• go for single descriptors in the first place, chop the descriptor-mat into rows, and insert single descriptors ( and a label for each ) this would avoid the problem of different desc. counts, but add a problem in the prediction, you'll have to do predict on several single descs as well, and find some kind of voting scheme.

whatever you choose, you'll need the same procedure in the training and prediction stage.

so , again. start all simple this time, take only 2 positive and 2 negative images, and try to train an SVM only on that. (maybe you even should skip the images/descriptors, and start with simple mockup data, [2,5,3,4] : label 1; [3,5,3,1] : label -1 , etc )

don't dare to proceed, until you get that right,

more

@berak Thanks for a nice explanation and bitter truth :) , and i am not getting the right documentation where i study how to use surf with svm , opencv documentation is not that easy , i studied paper on surf.

( 2013-08-24 05:23:11 -0500 )edit

hey, noone said, it's easy. honestly, it's not.

( 2013-08-24 05:39:42 -0500 )edit

Let me show you some of your error's to make your code better for those who answer you better for this error :

Your resize your images to a very small size which is difficult for surf to collect keypoints

const int image_area = 40*30;
cv::Mat training_mat(num_img,image_area,CV_32FC1);


there is no need for

cv::Mat tmp_dst( 500, 450, CV_8UC1 );


because on one side your making size 40*30 and on the other side you are changing this size in loop , so you don't these steps too in both loops:

    resize( tmp_img, tmp_dst, tmp_dst.size() );

Mat row_img = tmp_dst; // get a one line image.


So the final code without removing error become something like this :

// Initialize constant values
const int nb_cars = files.size();
const int not_cars = files_no.size();
const int num_img = nb_cars + not_cars; // Get the number of images
cv::Mat training_mat(num_img,image_area,CV_32FC1); // error
cv::Mat labels(num_img,1,CV_32FC1);

std::vector<string> all_names;
all_names.assign(files.begin(),files.end());
all_names.insert(all_names.end(), files_no.begin(), files_no.end());

int count = 0;
vector<string>::const_iterator i;
string Dir;
for (i = all_names.begin(); i != all_names.end(); ++i)
{
Dir=( (count < files.size() ) ? YourImagesDirectory : YourImagesDirectory_2);

Mat row_img = cv::imread( Dir +*i, 0 );

detector.detect( row_img, keypoints);

extractor->compute( row_img, keypoints, descriptors_1);

++count;
}

int count_2=0;
vector<string>::const_iterator k;
Mat vocabulary = bow.cluster();
dextract.setVocabulary(vocabulary);
for (k = all_names.begin(); k != all_names.end(); ++k)
{
Dir=( (count_2 < files.size() ) ? YourImagesDirectory : YourImagesDirectory_2);

Mat row_img = imread( Dir +*k, 0 );

detector.detect( row_img, keypoints);

dextract.compute( row_img, keypoints, descriptors_1);

training_mat.push_back(descriptors_1);

labels.at< float >(count_2, 0) = (count_2<nb_cars)?1:-1;
++count_2;
}

more

But i am still getting the same error

( 2013-08-23 08:28:48 -0500 )edit

Official site

GitHub

Wiki

Documentation