Cannot detect a simple rectangle

asked 2016-11-21 16:37:14 -0600

aneksteind gravatar image

I am using code inspired by https://github.com/opencv/opencv/blob.... My code is barely any different, and yet cannot detect ANYTHING. Any help would be appreciated. When running the program, it says (as I have instructed it to if this happens) that the list of detections is empty...

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <opencv2/objdetect.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>

#include <time.h>

using namespace cv;
using namespace cv::ml;
using namespace std;

void getSvmDetector(Ptr<SVM> & svm, vector < float > & detector);
void draw_locations(Mat & img, const vector < Rect > & locations, const Scalar & color);
void load_images(string dir, vector< Mat > & images, int numFiles);
void compute_hog(vector < Mat > & mats, vector < Mat > & gradient, Size & s);
void train_svm(const vector < Mat > & gradient_list, const vector < int > & labels);
void convert_to_ml(const vector< Mat > & train_samples, Mat & trainData);

int main(int, char**)
{
    int numPos = 6;
    int numNeg = 20;

    vector< Mat > pos_lst;
    vector< Mat > neg_lst;
    vector< Mat > gradient_list;
    vector < int > labels;

    string posDir = "C:/Users/danekstein/Desktop/rectangle/";
    string negDir = "C:/Users/danekstein/Desktop/nr/";

    // load and label positive images
    cout << "positive images loading..." << endl;
    load_images(posDir, pos_lst, numPos);
    labels.assign(pos_lst.size(), +1);

    // size with only positives
    const unsigned int old = (unsigned)labels.size();

    // load and label positive images
    cout << "negative images loading..." << endl;
    load_images(negDir, neg_lst, numNeg);   
    labels.insert(labels.end(), neg_lst.size(), -1);

    // check the labels were successfully added
    CV_Assert(old < labels.size());

    cout << "computing hog for positives" << endl;
    compute_hog(pos_lst, gradient_list, Size(256, 128));

    cout << "computing hog for negatives" << endl;
    compute_hog(neg_lst, gradient_list, Size(256, 128));


    train_svm(gradient_list, labels);

    Scalar border_color(0, 255, 0);
    Mat img, draw;
    Ptr<SVM> svm;
    HOGDescriptor hog = HOGDescriptor::HOGDescriptor();
    hog.winSize = Size(256, 128);


    // locations where a plane is detected
    vector< Rect > locations;

    // loading the trained svm
    svm = StatModel::load<SVM>("C:/Users/danekstein/Desktop/r.yml");

    // set the trained svm to the hog 
    vector< float > hog_detector;

    getSvmDetector(svm, hog_detector);

    // set the detector
    hog.setSVMDetector(hog_detector);

    Mat image = imread("C:/Users/danekstein/Desktop/rectangle/1.jpg");

    locations.clear();

    cout << "detecting features from sample" << endl;

    hog.detectMultiScale(image,locations);

    draw = image.clone();
    draw_locations(draw, locations, border_color);

    imshow("Image", draw);
    waitKey(0);
    destroyAllWindows();

}

void load_images(string dir, vector< Mat > & images, int numImages) {
    for (int i = 0; i < numImages; i++) {

        Mat im = imread(dir + to_string(i) + ".jpg");
        if (im.empty()) cout << "not good";

#ifdef _DEBUG

#endif
        images.push_back(im.clone());
    }
}

void compute_hog(vector < Mat > & mats, vector < Mat > & gradients, Size & size) {
    HOGDescriptor hog;
    hog.winSize = size;
    Mat gray;
    vector< Point > location;
    vector< float > descriptors;

    vector< Mat >::const_iterator img = mats.begin();
    vector< Mat >::const_iterator end = mats.end();
    for (; img != end; ++img) {
        cvtColor(*img, gray, COLOR_BGR2GRAY);
        hog.compute(gray, descriptors, Size(1,1), Size(0, 0), location);
        gradients.push_back(Mat(descriptors).clone());
    }
}

void getSvmDetector(Ptr<SVM> & svm, vector< float>  & detector) {
    // grab the support vectors... yay!
    Mat sv = svm->getSupportVectors();
    const int sv_total = sv.rows;

    // get the decision function
    Mat alpha, svidx;
    double rho = svm->getDecisionFunction ...
(more)
edit retag flag offensive close merge delete

Comments

can you show one of your positive images ?

berak gravatar imageberak ( 2016-11-22 01:15:38 -0600 )edit

It was essentially only a 256x128 picture of a black solid rectangle on top of a white background.. The rectangle itself was probably around 100x50 in size, and I had 6 positive images of it placed in various spots on top of the white background. My negatives were simply a white 256x128 picture @berak

aneksteind gravatar imageaneksteind ( 2016-11-23 11:15:50 -0600 )edit

@berak, it was something I made in microsoft paint. It didn't work on 14000 positive and negative samples for this, and it didn't work for 20 samples in this circumstance either, same issue of no detections

aneksteind gravatar imageaneksteind ( 2016-11-23 11:16:54 -0600 )edit

it was something I made in microsoft paint. It didn't work

... ooook, problem might be there. see, hog needs gradients to work, and your painting probably only had "edges" (might get some more "real world" data here).

berak gravatar imageberak ( 2016-11-23 12:20:12 -0600 )edit
1

@berak, I trained it using 9000 images of airplanes at gates, and 4000 randomly generated images, and I had the same problem, it definitely didn't only have edges then

aneksteind gravatar imageaneksteind ( 2016-11-23 12:24:20 -0600 )edit

oook, sorry for the noise, then..

berak gravatar imageberak ( 2016-11-23 12:26:45 -0600 )edit