Cannot detect a simple rectangle
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 ...
can you show one of your positive images ?
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
@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
... 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, 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
oook, sorry for the noise, then..