Ask Your Question
0

Error on SVM using images

asked 2013-08-01 15:20:06 -0600

FLY gravatar image

updated 2013-08-03 14:57:47 -0600

I am using SVM using opencv and below is the code i did :

string YourImagesDirectory="D:\\Cars\\";
Mat output_img;
vector<string> files=listFilesInDirectory(YourImagesDirectory+"*.jpg");
float labels[] = {1.0, 1.0, 1.0, 1.0 , 1.0 , 1.0 , 1.0 };
for(int image_in_file=0;image_in_file<files.size();image_in_file++)
    {
         Mat input_mat_positive=imread(YourImagesDirectory+files[image_in_file],0);
         resize(input_mat_positive,output_img,Size(40,30));
         Mat img_mat=output_img;
         int image_area=40*30;
         Mat training_mat(image_in_file,image_area,CV_32FC1);
         Mat labels(image_in_file,1,CV_32FC1);
         int ii=0; //current column in training_mat
         for(int k=0;k<img_mat.rows;k++)
         {
             for(int j=0; j<img_mat.cols ; j++)
             {
                 training_mat.at<float>(image_in_file,ii++)=img_mat.at<uchar>(k,j);
             }
         }
         CvSVMParams Params;
         Params.svm_type=CvSVM::C_SVC;
         Params.kernel_type=CvSVM::LINEAR;
         Params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
         Params.gamma=3;
         CvSVM svm;
         svm.train(training_mat,labels,Mat(),Mat(),Params);
         //svm.save("File_to_save");
         //svm.load("File_to_save");*/
}

I do the code by getting help from here http://stackoverflow.com/questions/14694810/using-opencv-and-svm-with-images , but i am getting the following runtime error :

enter image description here

Getting the value of int ii=0; consistently zero that may be the cause of error , but how to solve it

I have only ONE FILE which contain images , its not so many FILES

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
5

answered 2013-08-02 19:44:11 -0600

I will try to sum up:

string YourImagesDirectory="D:\\Cars\\";
vector<string> files=listFilesInDirectory(YourImagesDirectory+"*.jpg");
//Load NOT cars!
string YourImagesDirectory="D:\\NOTCars\\";
vector<string> files_no=listFilesInDirectory(YourImagesDirectory+"*.jpg");
// Initialize constant values
const int nb_cars = files.size();
const int num_img = nb_cars + filens_no.size(); // Get the number of images
const int image_area = 30*40;
// Initialize your training set.
Mat training_mat(num_img,image_area,CV_32FC1);
Mat labels(num_img,1,CV_32FC1);
// Set temp matrices
Mat tmp_img;
Mat tmp_dst( 30, 40, CV_8UC1 ); // to the right size for resize
// Load image and add them to the training set
for( int i = 0 ;  i < num_img ; ++i )
{
    tmp_img = imread( files[i], 0 ); // load in grayscale.
    resize( tmp_img, tmp_dst, dst.size() );
    Mat row_img = tmp_dst.reshape( 1, 1 ); // get a one line image.
    // copy line and convert to float
    row_img.convertTo( training_mat.row(i), CV_32FC1 );
    labels.at< float >(i, 0) = (i<nb_cars)?1:-1; // 1 for car, -1 otherwise
}
// Train your SVM
CvSVMParams Params;
Params.svm_type=CvSVM::C_SVC;
Params.kernel_type=CvSVM::LINEAR;
Params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
Params.gamma=3;
CvSVM svm;
svm.train(training_mat,labels,Mat(),Mat(),Params);

Some explanations:

  • Load your car images and NOT car images. To determine what is a car, you need to know what is not a car! You should have many different images here, from almost anything.
  • Convert your image to smaller size, and add them to the training set matrix. This will work with very small image (like in the link provided) but you must have to extract HOG (for example) for real application, like if you want to set a car detector like the pedestrians detector in OpenCV.
  • I use a trick to convert images: First I resize, then I reshape to be a vector (the V in SVM is for Vector, and it's dealing only with vectors!), and finally, I copy the vector to the training_mat with a float conversion.
  • Train your SVM. In your post, you only have car images, and all samples have the same label. Therefore SVM can not discriminate anything if it only know one category.
edit flag offensive delete link more

Comments

And yes i will use SURF with it for keypoint extraction and recognition

FLY gravatar imageFLY ( 2013-08-03 05:24:46 -0600 )edit

I would say its the excellent and superb answer and excellent explanation , thank you , but i am still getting the runtime error in loop , but its the best answer

FLY gravatar imageFLY ( 2013-08-03 06:58:28 -0600 )edit
1

answered 2013-08-02 09:33:22 -0600

updated 2013-08-02 09:33:47 -0600

I do not know what will be the the result of this training ... try to process images before put them through SVM (try HOG, LBP, etc.)

For example HOG

for every img:

HOGDescriptor des; 
vector<float> DV;
Vector<float> Loc
hog.compute( img, DV, Size(8,8), Size(0,0), Loc);

Then:

Mat des_mat = Mat(count_of_images,des_size,CV_32FC1); //for HOG 64x128 des_size is 3780

that mat + labels mat go to the SVM

edit flag offensive delete link more

Comments

yes, that's definitely the better idea

berak gravatar imageberak ( 2013-08-02 09:44:22 -0600 )edit

This code should put into the loop "for(int i=0;i<files.size();i++)" before "Mat input_mat_positive=imread(YourImagesDirectory+files[i],0);" ?

FLY gravatar imageFLY ( 2013-08-02 10:30:57 -0600 )edit

some simple steps: 1.Count the images 2.Make a description mat for SVM and label mat. 3. FOR every image compute description vector 4.Put the information from the description vector to the description matrix (from DV to des_mat - with simple loop) 5.Put the label in the label matrix(1 or -1) 6.Train the SVM with those mats. and 7.Save the model file :P

And have patience, every train may take up to 1 hour ;)

Spas Hristov gravatar imageSpas Hristov ( 2013-08-05 01:38:02 -0600 )edit
0

answered 2013-08-02 08:53:01 -0600

berak gravatar image
  • load the images as grayscale [ imread("ghjgjg",0); ] or use cvtColor() to convert, else your pixel-access img_mat.at<uchar>(k,j); is doomed.

  • you want to train one svm, not one per file. put the pixels from all files into one training matrix and then train.

  • you never initialize your labels

------------------------------------------------------------------------------------------------

Mat training_mat( num_files ,image_area,CV_32FC1);
Mat labels(num_files,1,CV_32FC1);

for files :
    load files (grayscale) and put them into traing mat
    add an item to the labels

setup the svm and train it
edit flag offensive delete link more

Comments

@berak I load the image as grayscale Mat input_mat_positive=imread(YourImagesDirectory+files[i],0); and i follow the steps you guide , but still getting the same error , in my code num_files is actually i in loop

FLY gravatar imageFLY ( 2013-08-02 10:25:09 -0600 )edit
1

"in my code num_files is actually i in loop"

yes, that's wrong.

     Mat training_mat(num_img,image_area,CV_32FC1);
     Mat labels(num_img,1,CV_32FC1);

should be before the loop

     CvSVMParams Params;
     Params.svm_type=CvSVM::C_SVC;
     // and anything after that ..

should go after the loop

and again, you need to assign a label per image, just setting up the array is not enough

berak gravatar imageberak ( 2013-08-02 10:33:16 -0600 )edit

@berak What do you mean by num_img and num_files , they are not used in my code , and image_area is defined in loop than how i define it outside the loop is give error on it ,

FLY gravatar imageFLY ( 2013-08-02 10:43:44 -0600 )edit

Question Tools

Stats

Asked: 2013-08-01 15:20:06 -0600

Seen: 1,835 times

Last updated: Aug 03 '13