Commit d2bac5329e5a122d966687bcb08249c08eaab21e

Authored by Scott Klum
1 parent a80bf1d2

Updates to sliding window framework

openbr/plugins/classification/cascade.cpp
... ... @@ -13,14 +13,14 @@ namespace br
13 13  
14 14 struct Miner
15 15 {
16   - Mat src;
17   - Mat scaledSrc;
  16 + Template src;
  17 + Template scaledSrc;
18 18 Size windowSize;
19 19 Point offset, point;
20 20 float scale, scaleFactor, stepFactor;
21 21  
22   - Miner(const Mat &m, const Size &windowSize, const Point &offset) :
23   - src(m),
  22 + Miner(const Template &t, const Size &windowSize, const Point &offset) :
  23 + src(t),
24 24 windowSize(windowSize),
25 25 offset(offset),
26 26 point(offset)
... ... @@ -29,43 +29,57 @@ struct Miner
29 29 scaleFactor = 1.4142135623730950488016887242097F;
30 30 stepFactor = 0.5F;
31 31  
32   - scale = max(((float)windowSize.width + point.x) / ((float)src.cols),
33   - ((float)windowSize.height + point.y) / ((float)src.rows));
34   - Size size((int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F));
35   - resize(src, scaledSrc, size);
  32 + scale = max(((float)windowSize.width + point.x) / ((float)src.m().cols),
  33 + ((float)windowSize.height + point.y) / ((float)src.m().rows));
  34 + Size size((int)(scale*src.m().cols + 0.5F), (int)(scale*src.m().rows + 0.5F));
  35 + scaledSrc = resize(src, size);
36 36 }
37 37  
38   - Mat mine(bool *newImg)
  38 + Template resize(const Template &src, const Size &size)
39 39 {
40   - // Copy region of winSize region of img into m
41   - Mat window(windowSize.height, windowSize.width, CV_8U,
42   - (void*)(scaledSrc.data + point.y * scaledSrc.step + point.x * scaledSrc.elemSize()),
43   - scaledSrc.step);
  40 + Template dst(src.file);
  41 + for (int i=0; i<src.size(); i++) {
  42 + Mat buffer;
  43 + cv::resize(src[i], buffer, size);
  44 + dst.append(buffer);
  45 + }
  46 + return dst;
  47 + }
44 48  
45   - Mat sample;
46   - window.copyTo(sample);
  49 + Template mine(bool *newImg)
  50 + {
  51 + Template dst(src.file);
  52 + // Copy region of winSize region of img into m
  53 + for (int i=0; i<scaledSrc.size(); i++) {
  54 + Mat window(windowSize.height, windowSize.width, CV_8U,
  55 + (void*)(scaledSrc[i].data + point.y * scaledSrc[i].step + point.x * scaledSrc[i].elemSize()),
  56 + scaledSrc[i].step);
  57 + Mat sample;
  58 + window.copyTo(sample);
  59 + dst.append(sample);
  60 + }
47 61  
48   - if ((int)(point.x + (1.0F + stepFactor) * windowSize.width) < scaledSrc.cols)
  62 + if ((int)(point.x + (1.0F + stepFactor) * windowSize.width) < scaledSrc.m().cols)
49 63 point.x += (int)(stepFactor * windowSize.width);
50 64 else {
51 65 point.x = offset.x;
52   - if ((int)(point.y + (1.0F + stepFactor) * windowSize.height) < scaledSrc.rows)
  66 + if ((int)(point.y + (1.0F + stepFactor) * windowSize.height) < scaledSrc.m().rows)
53 67 point.y += (int)(stepFactor * windowSize.height);
54 68 else {
55 69 point.y = offset.y;
56 70 scale *= scaleFactor;
57 71 if (scale <= 1.0F) {
58   - Size size((int)(scale*src.cols), (int)(scale*src.rows));
59   - resize(src, scaledSrc, size);
  72 + Size size((int)(scale*src.m().cols), (int)(scale*src.m().rows));
  73 + scaledSrc = resize(src, size);
60 74 } else {
61 75 *newImg = true;
62   - return sample;
  76 + return dst;
63 77 }
64 78 }
65 79 }
66 80  
67 81 *newImg = false;
68   - return sample;
  82 + return dst;
69 83 }
70 84 };
71 85  
... ... @@ -156,10 +170,10 @@ class CascadeClassifier : public Classifier
156 170 negative = getNegative(offset);
157 171 samplingLocker.unlock();
158 172  
159   - Miner miner(negative.m(), windowSize(), offset);
  173 + Miner miner(negative, windowSize(), offset);
160 174 forever {
161 175 bool newImg;
162   - Template sample(negative.file, miner.mine(&newImg));
  176 + Template sample = miner.mine(&newImg);
163 177 if (!newImg) {
164 178 if (negSamples.size() >= numNegs)
165 179 return passedNegatives;
... ... @@ -169,7 +183,6 @@ class CascadeClassifier : public Classifier
169 183 QMutexLocker miningLocker(&miningMutex);
170 184 if (negSamples.size() >= numNegs)
171 185 return passedNegatives;
172   -
173 186 negSamples.append(sample);
174 187 printf("Negative samples: %d\r", negSamples.size());
175 188 }
... ... @@ -198,7 +211,7 @@ class CascadeClassifier : public Classifier
198 211 stages.append(next_stage);
199 212 }
200 213  
201   - for (int i = 0; i < numStages; i++) {
  214 + for (int i = 0; i < stages.size(); i++) {
202 215 qDebug() << "===== TRAINING" << i << "stage =====";
203 216 qDebug() << "<BEGIN";
204 217  
... ...
openbr/plugins/imgproc/slidingwindow.cpp
... ... @@ -95,75 +95,77 @@ class SlidingWindowTransform : public MetaTransform
95 95 Size minObjectSize(minSize, minSize);
96 96 Size maxObjectSize;
97 97  
98   - for (int i=0; i<t.size(); i++) {
99   - Mat m;
100   - OpenCVUtils::cvtUChar(t[i], m);
101   - QList<Rect> rects;
102   - QList<float> confidences;
103   -
104   - if (maxObjectSize.height == 0 || maxObjectSize.width == 0)
105   - maxObjectSize = m.size();
106   -
107   - Mat imageBuffer(m.rows + 1, m.cols + 1, CV_8U);
108   -
109   - for (double factor = 1; ; factor *= scaleFactor) {
110   - int dx, dy;
111   - Size originalWindowSize = classifier->windowSize(&dx, &dy);
112   -
113   - Size windowSize(cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) );
114   - Size scaledImageSize(cvRound(m.cols/factor ), cvRound(m.rows/factor));
115   - Size processingRectSize(scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height);
116   -
117   - if (processingRectSize.width <= 0 || processingRectSize.height <= 0)
118   - break;
119   - if (windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height)
120   - break;
121   - if (windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height)
122   - continue;
123   -
124   - Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data);
125   - resize(m, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR);
  98 + Mat m = t.m();
  99 + QList<Rect> rects;
  100 + QList<float> confidences;
  101 +
  102 + if (maxObjectSize.height == 0 || maxObjectSize.width == 0)
  103 + maxObjectSize = m.size();
  104 +
  105 + for (double factor = 1; ; factor *= scaleFactor) {
  106 + int dx, dy;
  107 + Size originalWindowSize = classifier->windowSize(&dx, &dy);
  108 +
  109 + Size windowSize(cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) );
  110 + Size scaledImageSize(cvRound(m.cols/factor ), cvRound(m.rows/factor));
  111 + Size processingRectSize(scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height);
  112 +
  113 + if (processingRectSize.width <= 0 || processingRectSize.height <= 0)
  114 + break;
  115 + if (windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height)
  116 + break;
  117 + if (windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height)
  118 + continue;
  119 +
  120 + Template scaleBuffer(t.file);
  121 + for (int i=0; i<t.size(); i++) {
  122 + Mat scaledImage;
  123 + resize(t[i], scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR);
  124 + scaleBuffer.append(scaledImage);
  125 + }
126 126  
127   - Template repImage(t.file, scaledImage);
128   - repImage = classifier->preprocess(repImage);
  127 + Template rep(t.file);
  128 + rep = classifier->preprocess(scaleBuffer);
129 129  
130   - int step = factor > 2. ? 1 : 2;
131   - for (int y = 0; y < processingRectSize.height; y += step) {
132   - for (int x = 0; x < processingRectSize.width; x += step) {
133   - Mat window = repImage.m()(Rect(Point(x, y), Size(originalWindowSize.width + dx, originalWindowSize.height + dy))).clone();
134   - Template t(window);
  130 + int step = factor > 2. ? 1 : 2;
  131 + for (int y = 0; y < processingRectSize.height; y += step) {
  132 + for (int x = 0; x < processingRectSize.width; x += step) {
  133 + Template window(t.file);
  134 + for (int i=0; i<rep.size(); i++) {
  135 + Mat w = rep[i](Rect(Point(x, y), Size(originalWindowSize.width + dx, originalWindowSize.height + dy))).clone();
  136 + window.append(w);
  137 + }
135 138  
136   - float confidence = 0;
137   - int result = classifier->classify(t, false, &confidence);
  139 + float confidence = 0;
  140 + int result = classifier->classify(window, false, &confidence);
138 141  
139   - if (result == 1) {
140   - rects.append(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height));
141   - confidences.append(confidence);
142   - }
  142 + if (result == 1) {
  143 + rects.append(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height));
  144 + confidences.append(confidence);
  145 + }
143 146  
144   - // TODO: Add non ROC mode
  147 + // TODO: Add non ROC mode
145 148  
146   - if (result == 0)
147   - x += step;
148   - }
  149 + if (result == 0)
  150 + x += step;
149 151 }
150 152 }
  153 + }
151 154  
152   - OpenCVUtils::group(rects, confidences, confidenceThreshold, minNeighbors, eps);
  155 + OpenCVUtils::group(rects, confidences, confidenceThreshold, minNeighbors, eps);
153 156  
154   - if (!enrollAll && rects.empty()) {
155   - rects.append(Rect(0, 0, m.cols, m.rows));
156   - confidences.append(-std::numeric_limits<float>::max());
157   - }
  157 + if (!enrollAll && rects.empty()) {
  158 + rects.append(Rect(0, 0, m.cols, m.rows));
  159 + confidences.append(-std::numeric_limits<float>::max());
  160 + }
158 161  
159   - for (int j=0; j<rects.size(); j++) {
160   - Template u(t.file, m);
161   - u.file.set("Confidence", confidences[j]);
162   - const QRectF rect = OpenCVUtils::fromRect(rects[j]);
163   - u.file.appendRect(rect);
164   - u.file.set("Face", rect);
165   - dst.append(u);
166   - }
  162 + for (int j=0; j<rects.size(); j++) {
  163 + Template u(t.file, m);
  164 + u.file.set("Confidence", confidences[j]);
  165 + const QRectF rect = OpenCVUtils::fromRect(rects[j]);
  166 + u.file.appendRect(rect);
  167 + u.file.set("Face", rect);
  168 + dst.append(u);
167 169 }
168 170 }
169 171 }
... ...