BoW + SVM won't work [closed]

asked 2013-03-04 05:51:54 -0600

aliciadominica gravatar image

updated 2013-03-04 05:59:52 -0600

Hello, I'm trying to implement a BoW + SVM method for classification that takes several images for class one and two and then classifies the query image based on those. For some reason after constructing bow descriptor, it returns an empty descriptor vector thus I can't train the SVM let alone classify. Relevant part of my code is below, I'd appreciate any insight. Thanks a lot.

Ptr<FeatureDetector> features = FeatureDetector::create("SIFT");
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create("SIFT");
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");

//defining terms for bowkmeans trainer
TermCriteria tc(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 10, 0.001);
int dictionarySize = 100;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);

CvSVMParams params;
params.svm_type    = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

BOWImgDescriptorExtractor bowDE(descriptor, matcher);

Mat features1, features2;
Mat bowDescriptor, bowDescriptor2;

Mat trainme(0, dictionarySize, CV_32FC1); 
Mat labels(0, 1, CV_32FC1);

while (dirp = readdir( dp ))

        filepath = dir + "/" + dirp->d_name;
        // If the file is a directory (or is in some way invalid) we'll skip it 
        if (stat( filepath.c_str(), &filestat )) continue;
        if (S_ISDIR( filestat.st_mode ))         continue;

        Mat img = imread(filepath);
        if (! {
            cout <<"Can't open file." << endl;
        features->detect(img, keypoints);
        descriptor->compute(img, keypoints, features1);
        bowDE.compute(img, keypoints, bowDescriptor);
        float label = 1.0;
        cout << "." << endl;

    while (dirp2 = readdir( dp2 ))
        filepath2 = dir2 + "/" + dirp2->d_name;
        // If the file is a directory (or is in some way invalid) we'll skip it 
        if (stat( filepath2.c_str(), &filestat2 )) continue;
        if (S_ISDIR( filestat2.st_mode ))         continue;

        Mat img2 = imread(filepath2);
        if (! {
            cout <<"Can't open file." << endl;
        features->detect(img2, keypoints2);
        descriptor->compute(img2, keypoints2, features2);
        bowDE.compute(img2, keypoints2, bowDescriptor2);
        float label = 0.0;
        cout << "." << endl;

Mat dictionary = bowTrainer.cluster();


Mat tryme(0, dictionarySize, CV_32FC1);
Mat tryDescriptor;
Mat img3 = imread("c:\\Users\\Elvan\\Desktop\\frame_0118.jpg", 0);
vector<KeyPoint> keypoints3;
features->detect(img3, keypoints3);
bowDE.compute(img3, keypoints3, tryDescriptor);

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by Mathieu Barnachon
close date 2013-05-14 08:37:13.337277


solved the BowDE.compute issue. But still the SVM says that the input argument is not a valid vector.

aliciadominica gravatar imagealiciadominica ( 2013-03-06 02:21:47 -0600 )edit

Which input argument? From your train or from your predict-statement? What is the exact error message ( and from which line does it stem ) ? Afaik the labels should be of type int ( cv::Mat1i / oder cv::Mat with type CV_32SC1 ).

Guanta gravatar imageGuanta ( 2013-03-07 11:40:04 -0600 )edit

Solved the problem, I was getting the "Bad input argument" in SVM.predict line, turns out the file was corrupt, that's all.

aliciadominica gravatar imagealiciadominica ( 2013-03-13 06:14:47 -0600 )edit