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 131  
132 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 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 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 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 146 //----------------------------- CascadeBoostParams -------------------------------------------------
... ...
openbr/core/boost.h
... ... @@ -2,7 +2,6 @@
2 2 #define _BOOST_H_
3 3  
4 4 #include "ml.h"
5   -#include <time.h>
6 5 #include <openbr/openbr_plugin.h>
7 6  
8 7 #ifdef _WIN32
... ... @@ -17,9 +16,9 @@ namespace br
17 16 struct FeatureEvaluator
18 17 {
19 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 23 int getNumFeatures() const { return representation->numFeatures(); }
25 24 int getMaxCatCount() const { return representation->maxCatCount(); }
... ... @@ -27,7 +26,8 @@ struct FeatureEvaluator
27 26 const cv::Mat& getCls() const { return cls; }
28 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 31 Representation *representation;
32 32 };
33 33  
... ...
openbr/openbr_plugin.h
... ... @@ -882,13 +882,11 @@ public:
882 882  
883 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 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 892 virtual int numChannels() const { return 1; }
... ... @@ -905,13 +903,13 @@ public:
905 903  
906 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 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 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 125 QList<Node*> classifiers;
126 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 132 CascadeBoostParams params(type, minTAR, maxFAR, trimRate, maxDepth, maxWeakCount);
133 133  
134 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 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 143 threshold = boost.getThreshold();
144 144  
... ... @@ -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 156 float sum = 0;
161 157 for (int i = 0; i < classifiers.size(); i++) {
... ... @@ -163,10 +159,10 @@ private:
163 159  
164 160 while (node->left) {
165 161 if (representation->maxCatCount() > 0) {
166   - int c = (int)representation->evaluate(m, node->featureIdx);
  162 + int c = (int)representation->evaluate(t, node->featureIdx);
167 163 node = (node->subset[c >> 5] & (1 << (c & 31))) ? node->left : node->right;
168 164 } else {
169   - double val = representation->evaluate(m, node->featureIdx);
  165 + double val = representation->evaluate(t, node->featureIdx);
170 166 node = val <= node->threshold ? node->left : node->right;
171 167 }
172 168 }
... ... @@ -184,11 +180,9 @@ private:
184 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 188 Size windowSize(int *dx, int *dy) const
... ...
openbr/plugins/classification/cascade.cpp
1 1 #include <opencv2/imgproc/imgproc.hpp>
2   -#include <opencv2/highgui/highgui.hpp>
  2 +
3 3 #include <openbr/plugins/openbr_internal.h>
4 4 #include <openbr/core/common.h>
5 5  
... ... @@ -100,8 +100,8 @@ class CascadeClassifier : public Classifier
100 100 BR_PROPERTY(bool, requireAllStages, false)
101 101  
102 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 106 QList<int> indices;
107 107 int negIndex, posIndex, samplingRound;
... ... @@ -113,18 +113,17 @@ class CascadeClassifier : public Classifier
113 113 negIndex = posIndex = samplingRound = 0;
114 114 }
115 115  
116   - bool getPositive(Mat &img)
  116 + bool getPositive(Template &img)
117 117 {
118 118 if (posIndex >= posImages.size())
119 119 return false;
120   -
121   - posImages[indices[posIndex++]].copyTo(img);
  120 + img = posImages[indices[posIndex++]];
122 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 128 const Size size = windowSize();
130 129 // Grab negative from list
... ... @@ -136,9 +135,9 @@ class CascadeClassifier : public Classifier
136 135 samplingRound = samplingRound % (size.width * size.height);
137 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 141 && offset.x >= 0 && offset.y >= 0)
143 142 break;
144 143 }
... ... @@ -150,16 +149,16 @@ class CascadeClassifier : public Classifier
150 149 {
151 150 uint64 passedNegatives = 0;
152 151 forever {
153   - Mat negative;
  152 + Template negative;
154 153 Point offset;
155 154 QMutexLocker samplingLocker(&samplingMutex);
156 155 negative = getNegative(offset);
157 156 samplingLocker.unlock();
158 157  
159   - Miner miner(negative, windowSize(), offset);
  158 + Miner miner(negative.m(), windowSize(), offset);
160 159 forever {
161 160 bool newImg;
162   - Mat sample = miner.mine(&newImg);
  161 + Template sample(negative.file, miner.mine(&newImg));
163 162 if (!newImg) {
164 163 if (negSamples.size() >= numNegs)
165 164 return passedNegatives;
... ... @@ -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 189 << "\nTotal positive images:" << posImages.size()
191 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 194 stages.reserve(numStages);
196 195 for (int i = 0; i < numStages; i++) {
... ... @@ -209,27 +208,17 @@ class CascadeClassifier : public Classifier
209 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 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 219 float stageConf = 0.0f;
231 220 foreach (const Classifier *stage, stages) {
232   - float result = stage->classify(image, process, &stageConf);
  221 + float result = stage->classify(src, process, &stageConf);
233 222 if (confidence)
234 223 *confidence += stageConf;
235 224 if (result == 0.0f)
... ... @@ -243,9 +232,9 @@ class CascadeClassifier : public Classifier
243 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 240 Size windowSize(int *dx = NULL, int *dy = NULL) const
... ... @@ -273,16 +262,13 @@ class CascadeClassifier : public Classifier
273 262 private:
274 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 267 posIndex = 0;
281 268  
282 269 float confidence;
283 270 while (posSamples.size() < numPos) {
284   - Mat pos(windowSize(), CV_8UC1);
285   -
  271 + Template pos;
286 272 if (!getPositive(pos))
287 273 qFatal("Cannot get another positive sample!");
288 274  
... ...
openbr/plugins/classification/liblinear.cpp
... ... @@ -138,7 +138,7 @@ private:
138 138 param.weight = NULL;
139 139 }
140 140  
141   - m = *train_svm(&prob, &param);
  141 + //m = *train_svm(&prob, &param);
142 142  
143 143 delete[] param.weight;
144 144 delete[] param.weight_label;
... ...
openbr/plugins/imgproc/slidingwindow.cpp
... ... @@ -17,7 +17,6 @@
17 17 #include <openbr/plugins/openbr_internal.h>
18 18 #include <openbr/core/opencvutils.h>
19 19 #include <openbr/core/qtutils.h>
20   -#include <opencv2/highgui/highgui.hpp>
21 20  
22 21 #include <opencv2/imgproc/imgproc.hpp>
23 22  
... ... @@ -35,7 +34,6 @@ namespace br
35 34 * \br_property int minSize The smallest sized object to detect in pixels
36 35 * \br_property int maxSize The largest sized object to detect in pixels. A negative value will set maxSize == image size
37 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 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 38 * \br_property float eps Parameter for non-maximum supression
41 39 */
... ... @@ -60,7 +58,7 @@ class SlidingWindowTransform : public MetaTransform
60 58  
61 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 64 void project(const Template &src, Template &dst) const
... ... @@ -123,15 +121,18 @@ class SlidingWindowTransform : public MetaTransform
123 121  
124 122 Mat scaledImage(scaledImageSize, CV_8U, imageBuffer.data);
125 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 128 int step = factor > 2. ? 1 : 2;
129 129 for (int y = 0; y < processingRectSize.height; y += step) {
130 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 134 float confidence = 0;
134   - int result = classifier->classify(window, false, &confidence);
  135 + int result = classifier->classify(t, false, &confidence);
135 136  
136 137 if (result == 1) {
137 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 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 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 97 int size = indices.empty() ? numFeatures() : indices.size();
96 98  
97 99 Mat result(1, size, CV_32FC1);
98 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 102 return result;
101 103 }
102 104  
... ...
openbr/plugins/representation/mblbp.cpp
... ... @@ -39,32 +39,36 @@ class MBLBPRepresentation : public Representation
39 39  
40 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 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 67 int size = indices.empty() ? numFeatures() : indices.size();
64 68  
65 69 Mat result(1, size, CV_32FC1);
66 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 72 return result;
69 73 }
70 74  
... ...
openbr/plugins/representation/npd.cpp
... ... @@ -16,23 +16,25 @@ class NPDRepresentation : public Representation
16 16  
17 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 33 int size = indices.empty() ? numFeatures() : indices.size();
32 34  
33 35 Mat result(1, size, CV_32FC1);
34 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 38 return result;
37 39 }
38 40  
... ... @@ -49,10 +51,10 @@ class NPDRepresentation : public Representation
49 51 struct Feature
50 52 {
51 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 55 float calc(const Mat &image) const;
54 56  
55   - int p[2];
  57 + int p0, p1;
56 58 };
57 59 QList<Feature> features;
58 60 };
... ... @@ -61,9 +63,9 @@ BR_REGISTER(Representation, NPDRepresentation)
61 63  
62 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 71 } // namespace br
... ...
openbr/plugins/representation/random.cpp
... ... @@ -28,9 +28,9 @@ class RandomRepresentation : public Representation
28 28  
29 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 35 const int nFeatures = representation->numFeatures();
36 36  
... ... @@ -40,17 +40,17 @@ class RandomRepresentation : public Representation
40 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 55 QList<int> newIndices;
56 56 if (indices.empty())
... ... @@ -59,7 +59,7 @@ class RandomRepresentation : public Representation
59 59 for (int i = 0; i < indices.size(); i++)
60 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 65 int numFeatures() const
... ... @@ -108,6 +108,3 @@ BR_REGISTER(Representation, RandomRepresentation)
108 108 } // namespace br
109 109  
110 110 #include "representation/random.moc"
111   -
112   -
113   -
... ...