Commit 835f64e8324bfcb148202dbecaf8a29a591bfff0

Authored by JordanCheney
2 parents e6fbbaa6 81829816

Merge pull request #433 from biometrics/detection_api_update

Detection api update
openbr/core/boost.cpp
@@ -131,23 +131,16 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b @@ -131,23 +131,16 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b
131 131
132 //------------------------------------- FeatureEvaluator --------------------------------------- 132 //------------------------------------- FeatureEvaluator ---------------------------------------
133 133
134 -void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount, int channels) 134 +void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount)
135 { 135 {
136 representation = _representation; 136 representation = _representation;
137 -  
138 - int dx, dy;  
139 - Size windowSize = representation->windowSize(&dx, &dy);  
140 - data.create((int)_maxSampleCount, (windowSize.width + dx) * (windowSize.height + dy), CV_32SC(channels));  
141 cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); 137 cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
142 } 138 }
143 139
144 -void FeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) 140 +void FeatureEvaluator::setImage(const Template &src, uchar clsLabel, int idx)
145 { 141 {
146 cls.ptr<float>(idx)[0] = clsLabel; 142 cls.ptr<float>(idx)[0] = clsLabel;
147 -  
148 - Mat pp;  
149 - representation->preprocess(img, pp);  
150 - pp.reshape(0, 1).copyTo(data.row(idx)); 143 + data.append(representation->preprocess(src));
151 } 144 }
152 145
153 //----------------------------- CascadeBoostParams ------------------------------------------------- 146 //----------------------------- CascadeBoostParams -------------------------------------------------
openbr/core/boost.h
@@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
2 #define _BOOST_H_ 2 #define _BOOST_H_
3 3
4 #include "ml.h" 4 #include "ml.h"
5 -#include <time.h>  
6 #include <openbr/openbr_plugin.h> 5 #include <openbr/openbr_plugin.h>
7 6
8 #ifdef _WIN32 7 #ifdef _WIN32
@@ -17,9 +16,9 @@ namespace br @@ -17,9 +16,9 @@ namespace br
17 struct FeatureEvaluator 16 struct FeatureEvaluator
18 { 17 {
19 ~FeatureEvaluator() {} 18 ~FeatureEvaluator() {}
20 - void init(Representation *_representation, int _maxSampleCount, int channels);  
21 - void setImage(const cv::Mat& img, uchar clsLabel, int idx);  
22 - float operator()(int featureIdx, int sampleIdx) const { return representation->evaluate(data.row(sampleIdx), featureIdx); } 19 + void init(Representation *_representation, int _maxSampleCount);
  20 + void setImage(const Template &src, uchar clsLabel, int idx);
  21 + float operator()(int featureIdx, int sampleIdx) const { return representation->evaluate(data[sampleIdx], featureIdx); }
23 22
24 int getNumFeatures() const { return representation->numFeatures(); } 23 int getNumFeatures() const { return representation->numFeatures(); }
25 int getMaxCatCount() const { return representation->maxCatCount(); } 24 int getMaxCatCount() const { return representation->maxCatCount(); }
@@ -27,7 +26,8 @@ struct FeatureEvaluator @@ -27,7 +26,8 @@ struct FeatureEvaluator
27 const cv::Mat& getCls() const { return cls; } 26 const cv::Mat& getCls() const { return cls; }
28 float getCls(int si) const { return cls.at<float>(si, 0); } 27 float getCls(int si) const { return cls.at<float>(si, 0); }
29 28
30 - cv::Mat data, cls; 29 + cv::Mat cls;
  30 + TemplateList data;
31 Representation *representation; 31 Representation *representation;
32 }; 32 };
33 33
openbr/openbr_plugin.h
@@ -882,13 +882,11 @@ public: @@ -882,13 +882,11 @@ public:
882 882
883 static Representation *make(QString str, QObject *parent); /*!< \brief Make a representation from a string. */ 883 static Representation *make(QString str, QObject *parent); /*!< \brief Make a representation from a string. */
884 884
885 - virtual void preprocess(const cv::Mat &src, cv::Mat &dst) const { dst = src; }  
886 - virtual void train(const QList<cv::Mat> &images, const QList<float> &labels) { (void) images; (void)labels; }  
887 -  
888 - virtual float evaluate(const cv::Mat &image, int idx) const = 0;  
889 - // By convention, an empty indices list will result in all feature responses being calculated  
890 - // and returned.  
891 - virtual cv::Mat evaluate(const cv::Mat &image, const QList<int> &indices = QList<int>()) const = 0; 885 + virtual Template preprocess(const Template &src) const { return src; }
  886 + virtual void train(const TemplateList &data) { (void)data; }
  887 + virtual float evaluate(const Template &src, int idx) const = 0;
  888 + // By convention passing an empty list evaluates all features in the representation
  889 + virtual cv::Mat evaluate(const Template &src, const QList<int> &indices = QList<int>()) const = 0;
892 890
893 virtual cv::Size windowSize(int *dx = NULL, int *dy = NULL) const = 0; // dx and dy should indicate the change to the original window size after preprocessing 891 virtual cv::Size windowSize(int *dx = NULL, int *dy = NULL) const = 0; // dx and dy should indicate the change to the original window size after preprocessing
894 virtual int numChannels() const { return 1; } 892 virtual int numChannels() const { return 1; }
@@ -905,13 +903,13 @@ public: @@ -905,13 +903,13 @@ public:
905 903
906 static Classifier *make(QString str, QObject *parent); 904 static Classifier *make(QString str, QObject *parent);
907 905
908 - virtual void train(const QList<cv::Mat> &images, const QList<float> &labels) = 0;  
909 - virtual float classify(const cv::Mat &image, bool process = true, float *confidence = NULL) const = 0; 906 + virtual void train(const TemplateList &data) { (void)data; }
  907 + virtual float classify(const Template &src, bool process = true, float *confidence = NULL) const = 0;
910 908
911 // Slots for representations 909 // Slots for representations
912 - virtual cv::Mat preprocess(const cv::Mat &image) const = 0; 910 + virtual Template preprocess(const Template &src) const { return src; }
913 virtual cv::Size windowSize(int *dx = NULL, int *dy = NULL) const = 0; 911 virtual cv::Size windowSize(int *dx = NULL, int *dy = NULL) const = 0;
914 - virtual int numFeatures() const = 0; 912 + virtual int numFeatures() const { return 0; }
915 }; 913 };
916 914
917 915
openbr/plugins/classification/boostedforest.cpp
@@ -125,20 +125,20 @@ private: @@ -125,20 +125,20 @@ private:
125 QList<Node*> classifiers; 125 QList<Node*> classifiers;
126 float threshold; 126 float threshold;
127 127
128 - void train(const QList<Mat> &images, const QList<float> &labels) 128 + void train(const TemplateList &data)
129 { 129 {
130 - representation->train(images, labels); 130 + representation->train(data);
131 131
132 CascadeBoostParams params(type, minTAR, maxFAR, trimRate, maxDepth, maxWeakCount); 132 CascadeBoostParams params(type, minTAR, maxFAR, trimRate, maxDepth, maxWeakCount);
133 133
134 FeatureEvaluator featureEvaluator; 134 FeatureEvaluator featureEvaluator;
135 - featureEvaluator.init(representation, images.size(), representation->numChannels()); 135 + featureEvaluator.init(representation, data.size());
136 136
137 - for (int i = 0; i < images.size(); i++)  
138 - featureEvaluator.setImage(images[i], labels[i], i); 137 + for (int i = 0; i < data.size(); i++)
  138 + featureEvaluator.setImage(data[i], data[i].file.get<float>("Label"), i);
139 139
140 CascadeBoost boost; 140 CascadeBoost boost;
141 - boost.train(&featureEvaluator, images.size(), 1024, 1024, representation->numChannels(), params); 141 + boost.train(&featureEvaluator, data.size(), 1024, 1024, representation->numChannels(), params);
142 142
143 threshold = boost.getThreshold(); 143 threshold = boost.getThreshold();
144 144
@@ -149,13 +149,9 @@ private: @@ -149,13 +149,9 @@ private:
149 } 149 }
150 } 150 }
151 151
152 - float classify(const Mat &image, bool process, float *confidence) const 152 + float classify(const Template &src, bool process, float *confidence) const
153 { 153 {
154 - Mat m;  
155 - if (process)  
156 - m = preprocess(image);  
157 - else  
158 - m = image; 154 + Template t = process ? preprocess(src) : src;
159 155
160 float sum = 0; 156 float sum = 0;
161 for (int i = 0; i < classifiers.size(); i++) { 157 for (int i = 0; i < classifiers.size(); i++) {
@@ -163,10 +159,10 @@ private: @@ -163,10 +159,10 @@ private:
163 159
164 while (node->left) { 160 while (node->left) {
165 if (representation->maxCatCount() > 0) { 161 if (representation->maxCatCount() > 0) {
166 - int c = (int)representation->evaluate(m, node->featureIdx); 162 + int c = (int)representation->evaluate(t, node->featureIdx);
167 node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right; 163 node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right;
168 } else { 164 } else {
169 - double val = representation->evaluate(m, node->featureIdx); 165 + double val = representation->evaluate(t, node->featureIdx);
170 node = val <= node->threshold ? node->left : node->right; 166 node = val <= node->threshold ? node->left : node->right;
171 } 167 }
172 } 168 }
@@ -184,11 +180,9 @@ private: @@ -184,11 +180,9 @@ private:
184 return representation->numFeatures(); 180 return representation->numFeatures();
185 } 181 }
186 182
187 - Mat preprocess(const Mat &image) const 183 + Template preprocess(const Template &src) const
188 { 184 {
189 - Mat dst;  
190 - representation->preprocess(image, dst);  
191 - return dst; 185 + return representation->preprocess(src);
192 } 186 }
193 187
194 Size windowSize(int *dx, int *dy) const 188 Size windowSize(int *dx, int *dy) const
openbr/plugins/classification/cascade.cpp
1 #include <opencv2/imgproc/imgproc.hpp> 1 #include <opencv2/imgproc/imgproc.hpp>
2 -#include <opencv2/highgui/highgui.hpp> 2 +
3 #include <openbr/plugins/openbr_internal.h> 3 #include <openbr/plugins/openbr_internal.h>
4 #include <openbr/core/common.h> 4 #include <openbr/core/common.h>
5 5
@@ -100,8 +100,8 @@ class CascadeClassifier : public Classifier @@ -100,8 +100,8 @@ class CascadeClassifier : public Classifier
100 BR_PROPERTY(bool, requireAllStages, false) 100 BR_PROPERTY(bool, requireAllStages, false)
101 101
102 QList<Classifier *> stages; 102 QList<Classifier *> stages;
103 - QList<Mat> posImages, negImages;  
104 - QList<Mat> posSamples, negSamples; 103 + TemplateList posImages, negImages;
  104 + TemplateList posSamples, negSamples;
105 105
106 QList<int> indices; 106 QList<int> indices;
107 int negIndex, posIndex, samplingRound; 107 int negIndex, posIndex, samplingRound;
@@ -113,18 +113,17 @@ class CascadeClassifier : public Classifier @@ -113,18 +113,17 @@ class CascadeClassifier : public Classifier
113 negIndex = posIndex = samplingRound = 0; 113 negIndex = posIndex = samplingRound = 0;
114 } 114 }
115 115
116 - bool getPositive(Mat &img) 116 + bool getPositive(Template &img)
117 { 117 {
118 if (posIndex >= posImages.size()) 118 if (posIndex >= posImages.size())
119 return false; 119 return false;
120 -  
121 - posImages[indices[posIndex++]].copyTo(img); 120 + img = posImages[indices[posIndex++]];
122 return true; 121 return true;
123 } 122 }
124 123
125 - Mat getNegative(Point &offset) 124 + Template getNegative(Point &offset)
126 { 125 {
127 - Mat negative; 126 + Template negative;
128 127
129 const Size size = windowSize(); 128 const Size size = windowSize();
130 // Grab negative from list 129 // Grab negative from list
@@ -136,9 +135,9 @@ class CascadeClassifier : public Classifier @@ -136,9 +135,9 @@ class CascadeClassifier : public Classifier
136 samplingRound = samplingRound % (size.width * size.height); 135 samplingRound = samplingRound % (size.width * size.height);
137 negIndex %= count; 136 negIndex %= count;
138 137
139 - offset.x = qMin( (int)samplingRound % size.width, negative.cols - size.width);  
140 - offset.y = qMin( (int)samplingRound / size.width, negative.rows - size.height);  
141 - if (!negative.empty() && negative.type() == CV_8UC1 138 + offset.x = qMin( (int)samplingRound % size.width, negative.m().cols - size.width);
  139 + offset.y = qMin( (int)samplingRound / size.width, negative.m().rows - size.height);
  140 + if (!negative.m().empty() && negative.m().type() == CV_8UC1
142 && offset.x >= 0 && offset.y >= 0) 141 && offset.x >= 0 && offset.y >= 0)
143 break; 142 break;
144 } 143 }
@@ -150,16 +149,16 @@ class CascadeClassifier : public Classifier @@ -150,16 +149,16 @@ class CascadeClassifier : public Classifier
150 { 149 {
151 uint64 passedNegatives = 0; 150 uint64 passedNegatives = 0;
152 forever { 151 forever {
153 - Mat negative; 152 + Template negative;
154 Point offset; 153 Point offset;
155 QMutexLocker samplingLocker(&samplingMutex); 154 QMutexLocker samplingLocker(&samplingMutex);
156 negative = getNegative(offset); 155 negative = getNegative(offset);
157 samplingLocker.unlock(); 156 samplingLocker.unlock();
158 157
159 - Miner miner(negative, windowSize(), offset); 158 + Miner miner(negative.m(), windowSize(), offset);
160 forever { 159 forever {
161 bool newImg; 160 bool newImg;
162 - Mat sample = miner.mine(&newImg); 161 + Template sample(negative.file, miner.mine(&newImg));
163 if (!newImg) { 162 if (!newImg) {
164 if (negSamples.size() >= numNegs) 163 if (negSamples.size() >= numNegs)
165 return passedNegatives; 164 return passedNegatives;
@@ -181,16 +180,16 @@ class CascadeClassifier : public Classifier @@ -181,16 +180,16 @@ class CascadeClassifier : public Classifier
181 } 180 }
182 } 181 }
183 182
184 - void train(const QList<Mat> &images, const QList<float> &labels) 183 + void train(const TemplateList &data)
185 { 184 {
186 - for (int i = 0; i < images.size(); i++)  
187 - labels[i] == 1 ? posImages.append(images[i]) : negImages.append(images[i]); 185 + foreach (const Template &t, data)
  186 + t.file.get<float>("Label") == 1.0f ? posImages.append(t) : negImages.append(t);
188 187
189 - qDebug() << "Total images:" << images.size() 188 + qDebug() << "Total images:" << data.size()
190 << "\nTotal positive images:" << posImages.size() 189 << "\nTotal positive images:" << posImages.size()
191 << "\nTotal negative images:" << negImages.size(); 190 << "\nTotal negative images:" << negImages.size();
192 191
193 - indices = Common::RandSample(posImages.size(),posImages.size(),true); 192 + indices = Common::RandSample(posImages.size(), posImages.size(), true);
194 193
195 stages.reserve(numStages); 194 stages.reserve(numStages);
196 for (int i = 0; i < numStages; i++) { 195 for (int i = 0; i < numStages; i++) {
@@ -209,27 +208,17 @@ class CascadeClassifier : public Classifier @@ -209,27 +208,17 @@ class CascadeClassifier : public Classifier
209 return; 208 return;
210 } 209 }
211 210
212 - QList<float> posLabels;  
213 - posLabels.reserve(posSamples.size());  
214 - for (int j=0; j<posSamples.size(); j++)  
215 - posLabels.append(1);  
216 -  
217 - QList<float> negLabels;  
218 - negLabels.reserve(negSamples.size());  
219 - for (int j=0; j<negSamples.size(); j++)  
220 - negLabels.append(0);  
221 -  
222 - stages[i]->train(posSamples+negSamples, posLabels+negLabels); 211 + stages[i]->train(posSamples + negSamples);
223 212
224 qDebug() << "END>"; 213 qDebug() << "END>";
225 } 214 }
226 } 215 }
227 216
228 - float classify(const Mat &image, bool process, float *confidence) const 217 + float classify(const Template &src, bool process, float *confidence) const
229 { 218 {
230 float stageConf = 0.0f; 219 float stageConf = 0.0f;
231 foreach (const Classifier *stage, stages) { 220 foreach (const Classifier *stage, stages) {
232 - float result = stage->classify(image, process, &stageConf); 221 + float result = stage->classify(src, process, &stageConf);
233 if (confidence) 222 if (confidence)
234 *confidence += stageConf; 223 *confidence += stageConf;
235 if (result == 0.0f) 224 if (result == 0.0f)
@@ -243,9 +232,9 @@ class CascadeClassifier : public Classifier @@ -243,9 +232,9 @@ class CascadeClassifier : public Classifier
243 return stages.first()->numFeatures(); 232 return stages.first()->numFeatures();
244 } 233 }
245 234
246 - Mat preprocess(const Mat &image) const 235 + Template preprocess(const Template &src) const
247 { 236 {
248 - return stages.first()->preprocess(image); 237 + return stages.first()->preprocess(src);
249 } 238 }
250 239
251 Size windowSize(int *dx = NULL, int *dy = NULL) const 240 Size windowSize(int *dx = NULL, int *dy = NULL) const
@@ -273,16 +262,13 @@ class CascadeClassifier : public Classifier @@ -273,16 +262,13 @@ class CascadeClassifier : public Classifier
273 private: 262 private:
274 float getSamples() 263 float getSamples()
275 { 264 {
276 - posSamples.clear();  
277 - posSamples.reserve(numPos);  
278 - negSamples.clear();  
279 - negSamples.reserve(numNegs); 265 + posSamples.clear(); posSamples.reserve(numPos);
  266 + negSamples.clear(); negSamples.reserve(numNegs);
280 posIndex = 0; 267 posIndex = 0;
281 268
282 float confidence; 269 float confidence;
283 while (posSamples.size() < numPos) { 270 while (posSamples.size() < numPos) {
284 - Mat pos(windowSize(), CV_8UC1);  
285 - 271 + Template pos;
286 if (!getPositive(pos)) 272 if (!getPositive(pos))
287 qFatal("Cannot get another positive sample!"); 273 qFatal("Cannot get another positive sample!");
288 274
openbr/plugins/classification/liblinear.cpp
@@ -138,7 +138,7 @@ private: @@ -138,7 +138,7 @@ private:
138 param.weight = NULL; 138 param.weight = NULL;
139 } 139 }
140 140
141 - m = *train_svm(&prob, &param); 141 + //m = *train_svm(&prob, &param);
142 142
143 delete[] param.weight; 143 delete[] param.weight;
144 delete[] param.weight_label; 144 delete[] param.weight_label;
openbr/plugins/imgproc/slidingwindow.cpp
@@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
17 #include <openbr/plugins/openbr_internal.h> 17 #include <openbr/plugins/openbr_internal.h>
18 #include <openbr/core/opencvutils.h> 18 #include <openbr/core/opencvutils.h>
19 #include <openbr/core/qtutils.h> 19 #include <openbr/core/qtutils.h>
20 -#include <opencv2/highgui/highgui.hpp>  
21 20
22 #include <opencv2/imgproc/imgproc.hpp> 21 #include <opencv2/imgproc/imgproc.hpp>
23 22
@@ -35,7 +34,6 @@ namespace br @@ -35,7 +34,6 @@ namespace br
35 * \br_property int minSize The smallest sized object to detect in pixels 34 * \br_property int minSize The smallest sized object to detect in pixels
36 * \br_property int maxSize The largest sized object to detect in pixels. A negative value will set maxSize == image size 35 * \br_property int maxSize The largest sized object to detect in pixels. A negative value will set maxSize == image size
37 * \br_property float scaleFactor The factor to scale the image by during each resize. 36 * \br_property float scaleFactor The factor to scale the image by during each resize.
38 - * \br_property int minNeighbors Parameter for non-maximum supression  
39 * \br_property float confidenceThreshold A threshold for positive detections. Positive detections returned by the classifier that have confidences below this threshold are considered negative detections. 37 * \br_property float confidenceThreshold A threshold for positive detections. Positive detections returned by the classifier that have confidences below this threshold are considered negative detections.
40 * \br_property float eps Parameter for non-maximum supression 38 * \br_property float eps Parameter for non-maximum supression
41 */ 39 */
@@ -60,7 +58,7 @@ class SlidingWindowTransform : public MetaTransform @@ -60,7 +58,7 @@ class SlidingWindowTransform : public MetaTransform
60 58
61 void train(const TemplateList &data) 59 void train(const TemplateList &data)
62 { 60 {
63 - classifier->train(data.data(), File::get<float>(data, "Label", -1)); 61 + classifier->train(data);
64 } 62 }
65 63
66 void project(const Template &src, Template &dst) const 64 void project(const Template &src, Template &dst) const
@@ -123,15 +121,18 @@ class SlidingWindowTransform : public MetaTransform @@ -123,15 +121,18 @@ class SlidingWindowTransform : public MetaTransform
123 121
124 Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data); 122 Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data);
125 resize(m, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR); 123 resize(m, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR);
126 - Mat repImage = classifier->preprocess(scaledImage); 124 +
  125 + Template repImage(t.file, scaledImage);
  126 + repImage = classifier->preprocess(repImage);
127 127
128 int step = factor > 2. ? 1 : 2; 128 int step = factor > 2. ? 1 : 2;
129 for (int y = 0; y < processingRectSize.height; y += step) { 129 for (int y = 0; y < processingRectSize.height; y += step) {
130 for (int x = 0; x < processingRectSize.width; x += step) { 130 for (int x = 0; x < processingRectSize.width; x += step) {
131 - Mat window = repImage(Rect(Point(x, y), Size(originalWindowSize.width + dx, originalWindowSize.height + dy))).clone(); 131 + Mat window = repImage.m()(Rect(Point(x, y), Size(originalWindowSize.width + dx, originalWindowSize.height + dy))).clone();
  132 + Template t(window);
132 133
133 float confidence = 0; 134 float confidence = 0;
134 - int result = classifier->classify(window, false, &confidence); 135 + int result = classifier->classify(t, false, &confidence);
135 136
136 if (result == 1) { 137 if (result == 1) {
137 rects.append(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height)); 138 rects.append(Rect(cvRound(x*factor), cvRound(y*factor), windowSize.width, windowSize.height));
openbr/plugins/representation/haar.cpp
@@ -80,23 +80,25 @@ class HaarRepresentation : public Representation @@ -80,23 +80,25 @@ class HaarRepresentation : public Representation
80 } 80 }
81 } 81 }
82 82
83 - void preprocess(const Mat &src, Mat &dst) const 83 + Template preprocess(const Template &src) const
84 { 84 {
  85 + Template dst;
85 integral(src, dst); 86 integral(src, dst);
  87 + return dst;
86 } 88 }
87 89
88 - float evaluate(const Mat &image, int idx) const 90 + float evaluate(const Template &src, int idx) const
89 { 91 {
90 - return (float)features[idx].calc(image); 92 + return (float)features[idx].calc(src.m());
91 } 93 }
92 94
93 - Mat evaluate(const Mat &image, const QList<int> &indices) const 95 + Mat evaluate(const Template &src, const QList<int> &indices) const
94 { 96 {
95 int size = indices.empty() ? numFeatures() : indices.size(); 97 int size = indices.empty() ? numFeatures() : indices.size();
96 98
97 Mat result(1, size, CV_32FC1); 99 Mat result(1, size, CV_32FC1);
98 for (int i = 0; i < size; i++) 100 for (int i = 0; i < size; i++)
99 - result.at<float>(i) = evaluate(image, indices.empty() ? i : indices[i]); 101 + result.at<float>(i) = evaluate(src, indices.empty() ? i : indices[i]);
100 return result; 102 return result;
101 } 103 }
102 104
openbr/plugins/representation/mblbp.cpp
@@ -39,32 +39,36 @@ class MBLBPRepresentation : public Representation @@ -39,32 +39,36 @@ class MBLBPRepresentation : public Representation
39 39
40 void init() 40 void init()
41 { 41 {
42 - int offset = winWidth + 1;  
43 - for (int x = 0; x < winWidth; x++ )  
44 - for (int y = 0; y < winHeight; y++ )  
45 - for (int w = 1; w <= winWidth / 3; w++ )  
46 - for (int h = 1; h <= winHeight / 3; h++ )  
47 - if ((x+3*w <= winWidth) && (y+3*h <= winHeight) )  
48 - features.append(Feature(offset, x, y, w, h ) ); 42 + if (features.isEmpty()) {
  43 + int offset = winWidth + 1;
  44 + for (int x = 0; x < winWidth; x++ )
  45 + for (int y = 0; y < winHeight; y++ )
  46 + for (int w = 1; w <= winWidth / 3; w++ )
  47 + for (int h = 1; h <= winHeight / 3; h++ )
  48 + if ((x+3*w <= winWidth) && (y+3*h <= winHeight) )
  49 + features.append(Feature(offset, x, y, w, h ) );
  50 + }
49 } 51 }
50 52
51 - void preprocess(const Mat &src, Mat &dst) const 53 + Template preprocess(const Template &src) const
52 { 54 {
  55 + Template dst;
53 integral(src, dst); 56 integral(src, dst);
  57 + return dst;
54 } 58 }
55 59
56 - float evaluate(const Mat &image, int idx) const 60 + float evaluate(const Template &src, int idx) const
57 { 61 {
58 - return (float)features[idx].calc(image); 62 + return (float)features[idx].calc(src.m());
59 } 63 }
60 64
61 - Mat evaluate(const Mat &image, const QList<int> &indices) const 65 + Mat evaluate(const Template &src, const QList<int> &indices) const
62 { 66 {
63 int size = indices.empty() ? numFeatures() : indices.size(); 67 int size = indices.empty() ? numFeatures() : indices.size();
64 68
65 Mat result(1, size, CV_32FC1); 69 Mat result(1, size, CV_32FC1);
66 for (int i = 0; i < size; i++) 70 for (int i = 0; i < size; i++)
67 - result.at<float>(i) = evaluate(image, indices.empty() ? i : indices[i]); 71 + result.at<float>(i) = evaluate(src, indices.empty() ? i : indices[i]);
68 return result; 72 return result;
69 } 73 }
70 74
openbr/plugins/representation/npd.cpp
@@ -16,23 +16,25 @@ class NPDRepresentation : public Representation @@ -16,23 +16,25 @@ class NPDRepresentation : public Representation
16 16
17 void init() 17 void init()
18 { 18 {
19 - for (int p1 = 0; p1 < (winWidth * winHeight); p1++)  
20 - for (int p2 = p1; p2 < (winWidth * winHeight); p2++)  
21 - features.append(Feature(p1, p2)); 19 + if (features.isEmpty()) {
  20 + for (int p1 = 0; p1 < (winWidth * winHeight); p1++)
  21 + for (int p2 = p1; p2 < (winWidth * winHeight); p2++)
  22 + features.append(Feature(p1, p2));
  23 + }
22 } 24 }
23 25
24 - float evaluate(const Mat &image, int idx) const 26 + float evaluate(const Template &src, int idx) const
25 { 27 {
26 - return features[idx].calc(image); 28 + return features[idx].calc(src.m());
27 } 29 }
28 30
29 - Mat evaluate(const Mat &image, const QList<int> &indices) const 31 + Mat evaluate(const Template &src, const QList<int> &indices) const
30 { 32 {
31 int size = indices.empty() ? numFeatures() : indices.size(); 33 int size = indices.empty() ? numFeatures() : indices.size();
32 34
33 Mat result(1, size, CV_32FC1); 35 Mat result(1, size, CV_32FC1);
34 for (int i = 0; i < size; i++) 36 for (int i = 0; i < size; i++)
35 - result.at<float>(i) = evaluate(image, indices.empty() ? i : indices[i]); 37 + result.at<float>(i) = evaluate(src, indices.empty() ? i : indices[i]);
36 return result; 38 return result;
37 } 39 }
38 40
@@ -49,10 +51,10 @@ class NPDRepresentation : public Representation @@ -49,10 +51,10 @@ class NPDRepresentation : public Representation
49 struct Feature 51 struct Feature
50 { 52 {
51 Feature() {} 53 Feature() {}
52 - Feature(int p1, int p2) { p[0] = p1; p[1] = p2; } 54 + Feature(int p0, int p1) : p0(p0), p1(p1) {}
53 float calc(const Mat &image) const; 55 float calc(const Mat &image) const;
54 56
55 - int p[2]; 57 + int p0, p1;
56 }; 58 };
57 QList<Feature> features; 59 QList<Feature> features;
58 }; 60 };
@@ -61,9 +63,9 @@ BR_REGISTER(Representation, NPDRepresentation) @@ -61,9 +63,9 @@ BR_REGISTER(Representation, NPDRepresentation)
61 63
62 inline float NPDRepresentation::Feature::calc(const Mat &image) const 64 inline float NPDRepresentation::Feature::calc(const Mat &image) const
63 { 65 {
64 - const int *ptr = image.ptr<int>();  
65 - int v1 = ptr[p[0]], v2 = ptr[p[1]];  
66 - return v1 == 0 && v2 == 0 ? 0 : ((float)(v1 - v2)) / (v1 + v2); 66 + const uchar *ptr = image.ptr();
  67 + int v1 = (int)ptr[p0], v2 = (int)ptr[p1];
  68 + return (v1 + v2) == 0 ? 0 : (1.0 * (v1 - v2)) / (v1 + v2);
67 } 69 }
68 70
69 } // namespace br 71 } // namespace br
openbr/plugins/representation/random.cpp
@@ -28,9 +28,9 @@ class RandomRepresentation : public Representation @@ -28,9 +28,9 @@ class RandomRepresentation : public Representation
28 28
29 QList<int> features; 29 QList<int> features;
30 30
31 - void train(const QList<Mat> &images, const QList<float> &labels) 31 + void train(const TemplateList &data)
32 { 32 {
33 - representation->train(images, labels); 33 + representation->train(data);
34 34
35 const int nFeatures = representation->numFeatures(); 35 const int nFeatures = representation->numFeatures();
36 36
@@ -40,17 +40,17 @@ class RandomRepresentation : public Representation @@ -40,17 +40,17 @@ class RandomRepresentation : public Representation
40 features = Common::RandSample(count,nFeatures,0,true); 40 features = Common::RandSample(count,nFeatures,0,true);
41 } 41 }
42 42
43 - void preprocess(const Mat &src, Mat &dst) const 43 + Template preprocess(const Template &src) const
44 { 44 {
45 - representation->preprocess(src,dst); 45 + return representation->preprocess(src);
46 } 46 }
47 47
48 - float evaluate(const Mat &image, int idx) const 48 + float evaluate(const Template &src, int idx) const
49 { 49 {
50 - return representation->evaluate(image,features[idx]); 50 + return representation->evaluate(src, features[idx]);
51 } 51 }
52 52
53 - Mat evaluate(const Mat &image, const QList<int> &indices) const 53 + Mat evaluate(const Template &src, const QList<int> &indices) const
54 { 54 {
55 QList<int> newIndices; 55 QList<int> newIndices;
56 if (indices.empty()) 56 if (indices.empty())
@@ -59,7 +59,7 @@ class RandomRepresentation : public Representation @@ -59,7 +59,7 @@ class RandomRepresentation : public Representation
59 for (int i = 0; i < indices.size(); i++) 59 for (int i = 0; i < indices.size(); i++)
60 newIndices.append(features[indices[i]]); 60 newIndices.append(features[indices[i]]);
61 61
62 - return representation->evaluate(image,newIndices); 62 + return representation->evaluate(src, newIndices);
63 } 63 }
64 64
65 int numFeatures() const 65 int numFeatures() const
@@ -108,6 +108,3 @@ BR_REGISTER(Representation, RandomRepresentation) @@ -108,6 +108,3 @@ BR_REGISTER(Representation, RandomRepresentation)
108 } // namespace br 108 } // namespace br
109 109
110 #include "representation/random.moc" 110 #include "representation/random.moc"
111 -  
112 -  
113 -