Ask Your Question

Training SVM Error - Assertion failed

asked 2020-06-26 10:06:25 -0500

albeh95 gravatar image

updated 2020-06-26 16:11:00 -0500

Hello everyone, basically I have this code:

#include <opencv2/imgcodecs.hpp>
#include <fstream>
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/ml/ml.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d.hpp>

using namespace cv;
using namespace std;
using namespace xfeatures2d;
using namespace ml;

int main() {
//load dictionary first
Mat dictionary;
FileStorage fs("myDictionary.yml", FileStorage::READ);
fs["vocabulary"] >> dictionary;

Ptr<SIFT> detector = SIFT::create(); //detector to detect SIFT features 

Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);

BOWImgDescriptorExtractor bowDE(detector, matcher);

cout << "extracting histograms in the form of BOW for each Training image " << endl;
Mat labels;
int dictSize = 400;

Mat trainingData;
int k = 0;
vector<KeyPoint> keypoint;
Mat bowDescriptor;
Mat img;

vector<String> fn;
glob("C:/Users/albma/Desktop/Università/Computer Vision/Final_Project/training_alberi/*.jpg", fn, true);

//extracting histogram in the form of bow for each image
for (size_t i = 0; i < fn.size(); i++) { //each class having 60 images

    printf("Training Image = %s\n", fn[i]);
    img = imread(fn[i], 0);
    detector->detect(img, keypoint); //detect keypoints
    bowDE.compute(img, keypoint, bowDescriptor); //compute descriptors
    labels.push_back((int)1); //push labels in a matrix.. 1

cout << trainingData.size() << endl;
cout << labels.size() << endl;

//SVM Part

Ptr<SVM> svm = SVM::create();
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

printf("Training SVM\n");
Ptr<TrainData> td = TrainData::create(trainingData, ROW_SAMPLE, labels); //start training SVM

And the last 2 lines gives me the error: OpenCV(4.3.0-pre) Error: Assertion failed ((layout == ROW_SAMPLE && responses.rows == nsamples) || (layout == COL_SAMPLE && responses.cols == nsamples)) in cv::ml::TrainDataImpl::setData

What could be the problem?

edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted

answered 2020-06-26 10:54:42 -0500

berak gravatar image

updated 2020-06-26 16:16:38 -0500

don't preallocate with the wrong datatype here (push_back() won't change this):

Mat trainingData(0, dictSize, CV_32S);

train data for the SVM needs to be float, not int !

just use:

Mat trainingData; // all you need. 1st push_back() will determine the type
edit flag offensive delete link more


Thank you berak, I've edited my code following your suggestion but still I get the same error. Should I do something on the labels Mat too?

albeh95 gravatar imagealbeh95 ( 2020-06-26 12:27:26 -0500 )edit

ah, sorry, misread the error msg (just scanned your code for "the usual suspects") ;)

while above still holds true, it complains, that you don't have exactly 1 sample per label (traindata.rows != labels.rows)

you simply don't need to preallocate the labels, and (we had that already, dear...) push_back() ints not floats

berak gravatar imageberak ( 2020-06-26 12:37:53 -0500 )edit

last -- a LINEAR SVM tries to find a "dividing margin", and thus needs at least 2 classes (thing / not-thing)

it's a bit unclear, what you're trying to achieve here

berak gravatar imageberak ( 2020-06-26 12:46:56 -0500 )edit

berak gravatar imageberak ( 2020-06-26 12:49:32 -0500 )edit

Thank you again! So basically I only wrote Mat labels() without parameters and set the push_back() cast into int (sorry I forgot to do that before)... But I still got the same error message :'( EDIT: it's weird because yesterday I tried with another dataset (made of airplanes) and it perfectly worked! I switched to trees and now it's not working anymore (I've used the same number of tree images for the training, they were of different size, same for the test set). Before of this part code there's another in which I compute the dictionary I'm using here (which took 5 hours today with trees: yesterday with the airplanes it just took one half hour but images were smaller).

albeh95 gravatar imagealbeh95 ( 2020-06-26 14:27:07 -0500 )edit

yea, somewhat puzzled, too.

did you print out the sizes of trainData and labels ?

berak gravatar imageberak ( 2020-06-26 14:28:56 -0500 )edit

Trining is 400x31 while labels is 1x32 mmm

albeh95 gravatar imagealbeh95 ( 2020-06-26 15:19:23 -0500 )edit

find out, where the 31 -- 32 mismatch happens

(not visible in the code you show above currently)

still got that silly int data[1] initialization around ?

berak gravatar imageberak ( 2020-06-26 15:27:30 -0500 )edit

I posted the full code, can't find the mismatch! I swear berak I'll put your name in my thesys credits when I'll graduate

albeh95 gravatar imagealbeh95 ( 2020-06-26 16:11:54 -0500 )edit

I'm thinking about the fact that, to make the dictionary, I've used 2 images among the 63 of the training set that actually are the same image but used twice: could it be the mismatch?

albeh95 gravatar imagealbeh95 ( 2020-06-26 16:15:39 -0500 )edit

Question Tools

1 follower


Asked: 2020-06-26 10:06:25 -0500

Seen: 87 times

Last updated: Jun 26 '20