Commit b8093d6d3570ef36b7dea1a39abfe99fbde72952

Authored by Scott Klum
1 parent 67818edc

Sliding window bug fix

openbr/plugins/imgproc/slidingwindow.cpp
... ... @@ -19,6 +19,7 @@
19 19 #include <openbr/core/qtutils.h>
20 20  
21 21 #include <opencv2/imgproc/imgproc.hpp>
  22 +#include <opencv2/highgui/highgui.hpp>
22 23  
23 24 using namespace cv;
24 25  
... ... @@ -50,6 +51,7 @@ class SlidingWindowTransform : public MetaTransform
50 51 Q_PROPERTY(float eps READ get_eps WRITE set_eps RESET reset_eps STORED false)
51 52 Q_PROPERTY(float minNeighbors READ get_minNeighbors WRITE set_minNeighbors RESET reset_minNeighbors STORED false)
52 53 Q_PROPERTY(bool group READ get_group WRITE set_group RESET reset_group STORED false)
  54 + Q_PROPERTY(int shrinkingFactor READ get_shrinkingFactor WRITE set_shrinkingFactor RESET reset_shrinkingFactor STORED false)
53 55 BR_PROPERTY(br::Classifier*, classifier, NULL)
54 56 BR_PROPERTY(int, minSize, 20)
55 57 BR_PROPERTY(int, maxSize, -1)
... ... @@ -58,6 +60,7 @@ class SlidingWindowTransform : public MetaTransform
58 60 BR_PROPERTY(float, eps, 0.2)
59 61 BR_PROPERTY(int, minNeighbors, 3)
60 62 BR_PROPERTY(bool, group, true)
  63 + BR_PROPERTY(int, shrinkingFactor, 1)
61 64  
62 65 void train(const TemplateList &data)
63 66 {
... ... @@ -100,42 +103,47 @@ class SlidingWindowTransform : public MetaTransform
100 103 QList<float> confidences;
101 104  
102 105 int dx, dy;
103   - const Size originalWindowSize = classifier->windowSize(&dx, &dy);
  106 + const Size classifierSize = classifier->windowSize(&dx, &dy);
104 107  
105 108 for (double factor = 1; ; factor *= scaleFactor) {
106   - const Size windowSize(cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor));
107   - const Size scaledImageSize(cvRound(imageSize.width/factor), cvRound(imageSize.height/factor));
108   - const Size processingRectSize(scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height);
  109 + // TODO: This should support non-square sizes
  110 + // Compute the size of the window in which we will detect faces
  111 + const Size detectionSize(cvRound(minSize*factor),cvRound(minSize*factor));
109 112  
110   - if (processingRectSize.width <= 0 || processingRectSize.height <= 0)
111   - break;
112   - if (windowSize.width < minSize || windowSize.height < minSize)
113   - continue;
  113 + // Stop if detection size is bigger than the image itself
  114 + if (detectionSize.width > imageSize.width || detectionSize.height > imageSize.height)
  115 + break;
  116 +
  117 + const float widthScale = (float)classifierSize.width/detectionSize.width;
  118 + const float heightScale = (float)classifierSize.height/detectionSize.height;
  119 +
  120 + // Scale the image such that the detection size within the image corresponds to the respresentation size
  121 + const Size scaledImageSize(cvRound(imageSize.width*widthScale), cvRound(imageSize.height*heightScale));
114 122  
115 123 Template rep(t.file);
116 124 foreach (const Mat &m, t) {
117 125 Mat scaledImage;
118   - resize(m, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR);
  126 + resize(m, scaledImage, scaledImageSize, 0, 0, CV_INTER_AREA);
119 127 rep.append(scaledImage);
120 128 }
121 129 rep = classifier->preprocess(rep);
122   -
  130 +
123 131 // Pre-allocate the window to avoid constructing this every iteration
124 132 Template window(t.file);
125 133 for (int i=0; i<rep.size(); i++)
126 134 window.append(Mat());
127 135  
128   - const int step = factor > 2.0 ? 1 : 2;
129   - for (int y = 0; y < processingRectSize.height; y += step) {
130   - for (int x = 0; x < processingRectSize.width; x += step) {
  136 + const int step = factor > 2.0 ? shrinkingFactor : shrinkingFactor*2;
  137 + for (int y = 0; y < scaledImageSize.height-classifierSize.height; y += step) {
  138 + for (int x = 0; x < scaledImageSize.width-classifierSize.width; x += step) {
131 139 for (int i=0; i<rep.size(); i++)
132   - window[i] = rep[i](Rect(Point(x, y), Size(originalWindowSize.width + dx, originalWindowSize.height + dy))).clone();
  140 + window[i] = rep[i](Rect(Point(x, y), Size(classifierSize.width+dx, classifierSize.height+dy))).clone();
133 141  
134 142 float confidence = 0;
135 143 int result = classifier->classify(window, false, &confidence);
136 144  
137 145 if (result == 1) {
138   - rects.append(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height));
  146 + rects.append(Rect(cvRound(x/widthScale), cvRound(y/heightScale), detectionSize.width, detectionSize.height));
139 147 confidences.append(confidence);
140 148 }
141 149  
... ...