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,14 +13,14 @@ namespace br
13 13
14 struct Miner 14 struct Miner
15 { 15 {
16 - Mat src;  
17 - Mat scaledSrc; 16 + Template src;
  17 + Template scaledSrc;
18 Size windowSize; 18 Size windowSize;
19 Point offset, point; 19 Point offset, point;
20 float scale, scaleFactor, stepFactor; 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 windowSize(windowSize), 24 windowSize(windowSize),
25 offset(offset), 25 offset(offset),
26 point(offset) 26 point(offset)
@@ -29,43 +29,57 @@ struct Miner @@ -29,43 +29,57 @@ struct Miner
29 scaleFactor = 1.4142135623730950488016887242097F; 29 scaleFactor = 1.4142135623730950488016887242097F;
30 stepFactor = 0.5F; 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 point.x += (int)(stepFactor * windowSize.width); 63 point.x += (int)(stepFactor * windowSize.width);
50 else { 64 else {
51 point.x = offset.x; 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 point.y += (int)(stepFactor * windowSize.height); 67 point.y += (int)(stepFactor * windowSize.height);
54 else { 68 else {
55 point.y = offset.y; 69 point.y = offset.y;
56 scale *= scaleFactor; 70 scale *= scaleFactor;
57 if (scale <= 1.0F) { 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 } else { 74 } else {
61 *newImg = true; 75 *newImg = true;
62 - return sample; 76 + return dst;
63 } 77 }
64 } 78 }
65 } 79 }
66 80
67 *newImg = false; 81 *newImg = false;
68 - return sample; 82 + return dst;
69 } 83 }
70 }; 84 };
71 85
@@ -156,10 +170,10 @@ class CascadeClassifier : public Classifier @@ -156,10 +170,10 @@ class CascadeClassifier : public Classifier
156 negative = getNegative(offset); 170 negative = getNegative(offset);
157 samplingLocker.unlock(); 171 samplingLocker.unlock();
158 172
159 - Miner miner(negative.m(), windowSize(), offset); 173 + Miner miner(negative, windowSize(), offset);
160 forever { 174 forever {
161 bool newImg; 175 bool newImg;
162 - Template sample(negative.file, miner.mine(&newImg)); 176 + Template sample = miner.mine(&newImg);
163 if (!newImg) { 177 if (!newImg) {
164 if (negSamples.size() >= numNegs) 178 if (negSamples.size() >= numNegs)
165 return passedNegatives; 179 return passedNegatives;
@@ -169,7 +183,6 @@ class CascadeClassifier : public Classifier @@ -169,7 +183,6 @@ class CascadeClassifier : public Classifier
169 QMutexLocker miningLocker(&miningMutex); 183 QMutexLocker miningLocker(&miningMutex);
170 if (negSamples.size() >= numNegs) 184 if (negSamples.size() >= numNegs)
171 return passedNegatives; 185 return passedNegatives;
172 -  
173 negSamples.append(sample); 186 negSamples.append(sample);
174 printf("Negative samples: %d\r", negSamples.size()); 187 printf("Negative samples: %d\r", negSamples.size());
175 } 188 }
@@ -198,7 +211,7 @@ class CascadeClassifier : public Classifier @@ -198,7 +211,7 @@ class CascadeClassifier : public Classifier
198 stages.append(next_stage); 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 qDebug() << "===== TRAINING" << i << "stage ====="; 215 qDebug() << "===== TRAINING" << i << "stage =====";
203 qDebug() << "<BEGIN"; 216 qDebug() << "<BEGIN";
204 217
openbr/plugins/imgproc/slidingwindow.cpp
@@ -95,75 +95,77 @@ class SlidingWindowTransform : public MetaTransform @@ -95,75 +95,77 @@ class SlidingWindowTransform : public MetaTransform
95 Size minObjectSize(minSize, minSize); 95 Size minObjectSize(minSize, minSize);
96 Size maxObjectSize; 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 }