Ask Your Question
0

OpenCV 3.1.0 Assertion failed checkDetectorSize in cv::HOGDescriptor::setSVMDetector

asked 2016-04-05 04:44:05 -0500

just_trying_stuff gravatar image

updated 2016-04-06 04:50:31 -0500

I'm trying to train SVM with my own images and feed that to the HOGDescriptor in OpenCV. The training looks to be going well, but when I try to give the model to the HOGDescriptor with the setSVMDetector function it fails. Code for training

    HOGDescriptor hog = new HOGDescriptor(new Size(96, 160), new Size(8,8), new Size(4,4), new Size(4,4), 9);

    SVM svm = SVM.create();
    svm.setKernel(SVM.LINEAR);

    MatOfFloat traindata = new MatOfFloat();
    Mat trainlabel = new Mat();

    String personsPath = "C:\\_small\\pos";
    for (File file : new File(personsPath).listFiles()) {
        if(file.isFile()){
            Mat img = Imgcodecs.imread(file.getPath());
            MatOfFloat descriptors = new MatOfFloat();

            Mat gray = new Mat();
            Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);

            hog.compute(gray, descriptors);
            traindata.push_back(descriptors);
            trainlabel.push_back(Mat.ones(descriptors.rows(), 1, CvType.CV_32SC1));
        }
    }

    String personsPathneg = "C:\\_small\\neg";
    for (File file : new File(personsPathneg).listFiles()) {
        if(file.isFile()){
            Mat img = Imgcodecs.imread(file.getPath());
            MatOfFloat descriptors = new MatOfFloat();

            Mat gray = new Mat();
            Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
            Imgproc.resize(gray, gray, new Size(96 , 160));

            hog.compute(gray, descriptors);
            traindata.push_back(descriptors);
            trainlabel.push_back(Mat.zeros(descriptors.rows(), 1, CvType.CV_32SC1));
        }
    }

    svm.train(traindata, Ml.ROW_SAMPLE, trainlabel);

    Mat supportVector = svm.getSupportVectors();

    Mat alpha = new Mat();
    Mat svidx = new Mat();
    double rho = svm.getDecisionFunction(0, alpha, svidx);

    int size = (int)(supportVector.total() + 1) * supportVector.channels();
    float[] temp = new float[size];

    supportVector.get(0, 0, temp);
    temp[temp.length - 1] = (float)-rho;

    MatOfFloat floatvector = new MatOfFloat(temp);

    if(hog.checkDetectorSize()){
        hog.setSVMDetector(floatvector);
    }

The error message

OpenCV Error: Assertion failed (checkDetectorSize()) in cv::HOGDescriptor::setSVMDetector, file C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\objdetect\src\hog.cpp, line 117
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\objdetect\src\hog.cpp:117: error: (-215) checkDetectorSize() in function cv::HOGDescriptor::setSVMDetector
]
    at org.opencv.objdetect.HOGDescriptor.setSVMDetector_0(Native Method)
    at org.opencv.objdetect.HOGDescriptor.setSVMDetector(HOGDescriptor.java:302)
    at feature.extraction.App.main(App.java:86)

It's driving me crazy does anybody have an idea?

Edit3: Changed the code to train the features (thanks to berak) but still I get the same error message. The error message points to hog.cpp line 117 the assert that is being called is CV_Assert(checkDetectorSize()); I call the java variant of this function at the end to check if it's true and it always returns true So what is the difference between the c++ checkDetectorSize and the java one.

edit retag flag offensive close merge delete

Comments

i guess, you forgot to add -rho to the support vector

(and the libpng warning is unrelated)

berak gravatar imageberak ( 2016-04-05 04:48:29 -0500 )edit

I've edited the question with added -rho but still the same error, I don't know if I did it right though.

just_trying_stuff gravatar imagejust_trying_stuff ( 2016-04-05 06:26:58 -0500 )edit
2

hmm, imho, you have to create a new array, 1 larger than the original, and then put -rho at the end.

berak gravatar imageberak ( 2016-04-05 06:37:55 -0500 )edit

I did that (See edit) but still the same error. It's driving me nuts I don't know what i'm doing wrong

just_trying_stuff gravatar imagejust_trying_stuff ( 2016-04-06 02:59:32 -0500 )edit
1

oh, wait, i missed the obvious : you have to train the SVM on hog features, not images

berak gravatar imageberak ( 2016-04-06 03:40:40 -0500 )edit

Yeah that's true, I'm just playing with the trainer now just trying to get it to work. But that shouldn't matter that much right? Anyways it may be better to do it the right way and train the features. I'll report back when I edited the code.

just_trying_stuff gravatar imagejust_trying_stuff ( 2016-04-06 03:47:36 -0500 )edit
1
berak gravatar imageberak ( 2016-04-06 03:55:16 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2016-04-07 08:12:20 -0500

just_trying_stuff gravatar image

After a lot of hours and help from berak I figured it out. Instead of using a Mat and using the push_back function. I made a 2d float array and put the descriptor output from the compute function in there.

//for loop each image
float[] vector = descriptors.toArray();
trainVector[i] = vector;

Afterwards I made an empty Mat and put the values of the float array in there. And used that for training. Also don't forget to put the rho at the end of the supportvectorfrom the svm.

edit flag offensive delete link more

Comments

i dont understand, how to copy float[][] trainVector to Mat object! Please help me

jikolp95 gravatar imagejikolp95 ( 2018-03-05 06:33:31 -0500 )edit

Full code explained please

EdoTwentySix gravatar imageEdoTwentySix ( 2018-03-31 15:43:57 -0500 )edit

please add full code

kurenchuksergey gravatar imagekurenchuksergey ( 2018-03-31 16:09:15 -0500 )edit
2

answered 2016-04-06 03:50:24 -0500

berak gravatar image

you have to train the SVM on hog features, not images

so, processing the train data should look like:

HOGDescriptor hog = new HOGDescriptor(new Size(160, 96), new Size(8,8), new Size(4,4), new Size(4,4), 9);
for (each image) {
        Mat img = Imgcodecs.imread(file.getPath());
        Mat newImg = new Mat();
        Imgproc.cvtColor(img, newImg, Imgproc.COLOR_BGR2GRAY);
        Imgproc.resize(newImg, newImg, new Size(160 , 96));
        Mat descriptors = new Mat();
        hog.compute(newImg, descriptors);
        // now train your svm with the descriptors, not the images !
}
edit flag offensive delete link more

Comments

I've edited the code to train the features but still I get the same error message. (i've edited the main question with the new code)

just_trying_stuff gravatar imagejust_trying_stuff ( 2016-04-06 04:53:35 -0500 )edit
1

again, pleas check, if the size if your floatvector matches the expectation .

(i have some weird feeling, that 160x96 is not an acceptable size)

berak gravatar imageberak ( 2016-04-06 05:01:43 -0500 )edit
1

the 160x96 was indeed wrong but I changed that already, it's now 96*160. The floatvector object is 2*1*CV_32FC1. And I made sure that the descriptor size matches the expectation. I also added hog.checkDetectorSize() before training with svm and it returns true.

just_trying_stuff gravatar imagejust_trying_stuff ( 2016-04-06 05:44:38 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2016-04-05 04:44:05 -0500

Seen: 3,893 times

Last updated: Apr 07 '16