Commit e4d4166cfff76ae8a0241253713a8ad3c5f2d412

Authored by Jordan Cheney
2 parents 8fde04e6 f213e68c

Merge branch 'reorg'

Showing 317 changed files with 19149 additions and 13709 deletions

Too many changes.

To preserve performance only 100 of 317 files are displayed.

openbr/plugins/classification/adaboost.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/opencvutils.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup transforms
  27 + * \brief Wraps OpenCV's Ada Boost framework
  28 + * \author Scott Klum \cite sklum
  29 + * \brief http://docs.opencv.org/modules/ml/doc/boosting.html
  30 + */
  31 +class AdaBoostTransform : public Transform
  32 +{
  33 + Q_OBJECT
  34 + Q_ENUMS(Type)
  35 + Q_ENUMS(SplitCriteria)
  36 +
  37 + Q_PROPERTY(Type type READ get_type WRITE set_type RESET reset_type STORED false)
  38 + Q_PROPERTY(SplitCriteria splitCriteria READ get_splitCriteria WRITE set_splitCriteria RESET reset_splitCriteria STORED false)
  39 + Q_PROPERTY(int weakCount READ get_weakCount WRITE set_weakCount RESET reset_weakCount STORED false)
  40 + Q_PROPERTY(float trimRate READ get_trimRate WRITE set_trimRate RESET reset_trimRate STORED false)
  41 + Q_PROPERTY(int folds READ get_folds WRITE set_folds RESET reset_folds STORED false)
  42 + Q_PROPERTY(int maxDepth READ get_maxDepth WRITE set_maxDepth RESET reset_maxDepth STORED false)
  43 + Q_PROPERTY(bool returnConfidence READ get_returnConfidence WRITE set_returnConfidence RESET reset_returnConfidence STORED false)
  44 + Q_PROPERTY(bool overwriteMat READ get_overwriteMat WRITE set_overwriteMat RESET reset_overwriteMat STORED false)
  45 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  46 + Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false)
  47 +
  48 +public:
  49 + enum Type { Discrete = CvBoost::DISCRETE,
  50 + Real = CvBoost::REAL,
  51 + Logit = CvBoost::LOGIT,
  52 + Gentle = CvBoost::GENTLE};
  53 +
  54 + enum SplitCriteria { Default = CvBoost::DEFAULT,
  55 + Gini = CvBoost::GINI,
  56 + Misclass = CvBoost::MISCLASS,
  57 + Sqerr = CvBoost::SQERR};
  58 +
  59 +private:
  60 + BR_PROPERTY(Type, type, Real)
  61 + BR_PROPERTY(SplitCriteria, splitCriteria, Default)
  62 + BR_PROPERTY(int, weakCount, 100)
  63 + BR_PROPERTY(float, trimRate, .95)
  64 + BR_PROPERTY(int, folds, 0)
  65 + BR_PROPERTY(int, maxDepth, 1)
  66 + BR_PROPERTY(bool, returnConfidence, true)
  67 + BR_PROPERTY(bool, overwriteMat, true)
  68 + BR_PROPERTY(QString, inputVariable, "Label")
  69 + BR_PROPERTY(QString, outputVariable, "")
  70 +
  71 + CvBoost boost;
  72 +
  73 + void train(const TemplateList &data)
  74 + {
  75 + Mat samples = OpenCVUtils::toMat(data.data());
  76 + Mat labels = OpenCVUtils::toMat(File::get<float>(data, inputVariable));
  77 +
  78 + Mat types = Mat(samples.cols + 1, 1, CV_8U);
  79 + types.setTo(Scalar(CV_VAR_NUMERICAL));
  80 + types.at<char>(samples.cols, 0) = CV_VAR_CATEGORICAL;
  81 +
  82 + CvBoostParams params;
  83 + params.boost_type = type;
  84 + params.split_criteria = splitCriteria;
  85 + params.weak_count = weakCount;
  86 + params.weight_trim_rate = trimRate;
  87 + params.cv_folds = folds;
  88 + params.max_depth = maxDepth;
  89 +
  90 + boost.train( samples, CV_ROW_SAMPLE, labels, Mat(), Mat(), types, Mat(),
  91 + params);
  92 + }
  93 +
  94 + void project(const Template &src, Template &dst) const
  95 + {
  96 + dst = src;
  97 + float response;
  98 + if (returnConfidence) {
  99 + response = boost.predict(src.m().reshape(1,1),Mat(),Range::all(),false,true)/weakCount;
  100 + } else {
  101 + response = boost.predict(src.m().reshape(1,1));
  102 + }
  103 +
  104 + if (overwriteMat) {
  105 + dst.m() = Mat(1, 1, CV_32F);
  106 + dst.m().at<float>(0, 0) = response;
  107 + } else {
  108 + dst.file.set(outputVariable, response);
  109 + }
  110 + }
  111 +
  112 + void load(QDataStream &stream)
  113 + {
  114 + OpenCVUtils::loadModel(boost,stream);
  115 + }
  116 +
  117 + void store(QDataStream &stream) const
  118 + {
  119 + OpenCVUtils::storeModel(boost,stream);
  120 + }
  121 +
  122 +
  123 + void init()
  124 + {
  125 + if (outputVariable.isEmpty())
  126 + outputVariable = inputVariable;
  127 + }
  128 +};
  129 +
  130 +BR_REGISTER(Transform, AdaBoostTransform)
  131 +
  132 +} // namespace br
  133 +
  134 +#include "classification/adaboost.moc"
openbr/plugins/ebif.cpp renamed to openbr/plugins/classification/ebif.cpp
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
1 #include <opencv2/imgproc/imgproc.hpp> 17 #include <opencv2/imgproc/imgproc.hpp>
2 18
3 -#include "openbr_internal.h"  
4 -#include "openbr/core/common.h"  
5 -#include "openbr/core/opencvutils.h" 19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/common.h>
  21 +#include <openbr/core/opencvutils.h>
6 22
7 using namespace cv; 23 using namespace cv;
8 24
@@ -128,4 +144,4 @@ BR_REGISTER(Transform, EBIFTransform) @@ -128,4 +144,4 @@ BR_REGISTER(Transform, EBIFTransform)
128 144
129 } // namespace br 145 } // namespace br
130 146
131 -#include "ebif.moc" 147 +#include "classification/ebif.moc"
openbr/plugins/tree.cpp renamed to openbr/plugins/classification/forest.cpp
1 -#include "openbr_internal.h"  
2 -#include "openbr/core/opencvutils.h" 1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/opencvutils.h>
3 19
4 -using namespace std;  
5 using namespace cv; 20 using namespace cv;
6 21
7 namespace br 22 namespace br
@@ -250,113 +265,6 @@ class ForestInductionTransform : public ForestTransform @@ -250,113 +265,6 @@ class ForestInductionTransform : public ForestTransform
250 265
251 BR_REGISTER(Transform, ForestInductionTransform) 266 BR_REGISTER(Transform, ForestInductionTransform)
252 267
253 -/*!  
254 - * \ingroup transforms  
255 - * \brief Wraps OpenCV's Ada Boost framework  
256 - * \author Scott Klum \cite sklum  
257 - * \brief http://docs.opencv.org/modules/ml/doc/boosting.html  
258 - */  
259 -class AdaBoostTransform : public Transform  
260 -{  
261 - Q_OBJECT  
262 - Q_ENUMS(Type)  
263 - Q_ENUMS(SplitCriteria)  
264 -  
265 - Q_PROPERTY(Type type READ get_type WRITE set_type RESET reset_type STORED false)  
266 - Q_PROPERTY(SplitCriteria splitCriteria READ get_splitCriteria WRITE set_splitCriteria RESET reset_splitCriteria STORED false)  
267 - Q_PROPERTY(int weakCount READ get_weakCount WRITE set_weakCount RESET reset_weakCount STORED false)  
268 - Q_PROPERTY(float trimRate READ get_trimRate WRITE set_trimRate RESET reset_trimRate STORED false)  
269 - Q_PROPERTY(int folds READ get_folds WRITE set_folds RESET reset_folds STORED false)  
270 - Q_PROPERTY(int maxDepth READ get_maxDepth WRITE set_maxDepth RESET reset_maxDepth STORED false)  
271 - Q_PROPERTY(bool returnConfidence READ get_returnConfidence WRITE set_returnConfidence RESET reset_returnConfidence STORED false)  
272 - Q_PROPERTY(bool overwriteMat READ get_overwriteMat WRITE set_overwriteMat RESET reset_overwriteMat STORED false)  
273 - Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)  
274 - Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false)  
275 -  
276 -public:  
277 - enum Type { Discrete = CvBoost::DISCRETE,  
278 - Real = CvBoost::REAL,  
279 - Logit = CvBoost::LOGIT,  
280 - Gentle = CvBoost::GENTLE};  
281 -  
282 - enum SplitCriteria { Default = CvBoost::DEFAULT,  
283 - Gini = CvBoost::GINI,  
284 - Misclass = CvBoost::MISCLASS,  
285 - Sqerr = CvBoost::SQERR};  
286 -  
287 -private:  
288 - BR_PROPERTY(Type, type, Real)  
289 - BR_PROPERTY(SplitCriteria, splitCriteria, Default)  
290 - BR_PROPERTY(int, weakCount, 100)  
291 - BR_PROPERTY(float, trimRate, .95)  
292 - BR_PROPERTY(int, folds, 0)  
293 - BR_PROPERTY(int, maxDepth, 1)  
294 - BR_PROPERTY(bool, returnConfidence, true)  
295 - BR_PROPERTY(bool, overwriteMat, true)  
296 - BR_PROPERTY(QString, inputVariable, "Label")  
297 - BR_PROPERTY(QString, outputVariable, "")  
298 -  
299 - CvBoost boost;  
300 -  
301 - void train(const TemplateList &data)  
302 - {  
303 - Mat samples = OpenCVUtils::toMat(data.data());  
304 - Mat labels = OpenCVUtils::toMat(File::get<float>(data, inputVariable));  
305 -  
306 - Mat types = Mat(samples.cols + 1, 1, CV_8U);  
307 - types.setTo(Scalar(CV_VAR_NUMERICAL));  
308 - types.at<char>(samples.cols, 0) = CV_VAR_CATEGORICAL;  
309 -  
310 - CvBoostParams params;  
311 - params.boost_type = type;  
312 - params.split_criteria = splitCriteria;  
313 - params.weak_count = weakCount;  
314 - params.weight_trim_rate = trimRate;  
315 - params.cv_folds = folds;  
316 - params.max_depth = maxDepth;  
317 -  
318 - boost.train( samples, CV_ROW_SAMPLE, labels, Mat(), Mat(), types, Mat(),  
319 - params);  
320 - }  
321 -  
322 - void project(const Template &src, Template &dst) const  
323 - {  
324 - dst = src;  
325 - float response;  
326 - if (returnConfidence) {  
327 - response = boost.predict(src.m().reshape(1,1),Mat(),Range::all(),false,true)/weakCount;  
328 - } else {  
329 - response = boost.predict(src.m().reshape(1,1));  
330 - }  
331 -  
332 - if (overwriteMat) {  
333 - dst.m() = Mat(1, 1, CV_32F);  
334 - dst.m().at<float>(0, 0) = response;  
335 - } else {  
336 - dst.file.set(outputVariable, response);  
337 - }  
338 - }  
339 -  
340 - void load(QDataStream &stream)  
341 - {  
342 - OpenCVUtils::loadModel(boost,stream);  
343 - }  
344 -  
345 - void store(QDataStream &stream) const  
346 - {  
347 - OpenCVUtils::storeModel(boost,stream);  
348 - }  
349 -  
350 -  
351 - void init()  
352 - {  
353 - if (outputVariable.isEmpty())  
354 - outputVariable = inputVariable;  
355 - }  
356 -};  
357 -  
358 -BR_REGISTER(Transform, AdaBoostTransform)  
359 -  
360 } // namespace br 268 } // namespace br
361 269
362 -#include "tree.moc" 270 +#include "classification/forest.moc"
openbr/plugins/ipc2013.cpp renamed to openbr/plugins/classification/ipc2013.cpp
1 -#include "openbr_internal.h"  
2 #include <pxcaccelerator.h> 1 #include <pxcaccelerator.h>
3 #include <pxcface.h> 2 #include <pxcface.h>
4 #include <pxcimage.h> 3 #include <pxcimage.h>
5 #include <pxcsession.h> 4 #include <pxcsession.h>
6 5
  6 +#include <openbr/plugins/openbr_internal.h>
  7 +
7 using namespace br; 8 using namespace br;
8 9
9 static PXCSession *pxcSession = NULL; 10 static PXCSession *pxcSession = NULL;
openbr/plugins/eigen3.cpp renamed to openbr/plugins/classification/lda.cpp
@@ -16,11 +16,11 @@ @@ -16,11 +16,11 @@
16 16
17 #include <Eigen/Dense> 17 #include <Eigen/Dense>
18 18
19 -#include "openbr_internal.h" 19 +#include <openbr/plugins/openbr_internal.h>
20 20
21 -#include "openbr/core/common.h"  
22 -#include "openbr/core/eigenutils.h"  
23 -#include "openbr/core/opencvutils.h" 21 +#include <openbr/core/common.h>
  22 +#include <openbr/core/eigenutils.h>
  23 +#include <openbr/core/opencvutils.h>
24 24
25 namespace br 25 namespace br
26 { 26 {
@@ -652,46 +652,6 @@ class SparseLDATransform : public Transform @@ -652,46 +652,6 @@ class SparseLDATransform : public Transform
652 652
653 BR_REGISTER(Transform, SparseLDATransform) 653 BR_REGISTER(Transform, SparseLDATransform)
654 654
655 -/*!  
656 - * \ingroup distances  
657 - * \brief L1 distance computed using eigen.  
658 - * \author Josh Klontz \cite jklontz  
659 - */  
660 -class L1Distance : public UntrainableDistance  
661 -{  
662 - Q_OBJECT  
663 -  
664 - float compare(const cv::Mat &a, const cv::Mat &b) const  
665 - {  
666 - const int size = a.rows * a.cols;  
667 - Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size);  
668 - Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size);  
669 - return (aMap-bMap).cwiseAbs().sum();  
670 - }  
671 -};  
672 -  
673 -BR_REGISTER(Distance, L1Distance)  
674 -  
675 -/*!  
676 - * \ingroup distances  
677 - * \brief L2 distance computed using eigen.  
678 - * \author Josh Klontz \cite jklontz  
679 - */  
680 -class L2Distance : public UntrainableDistance  
681 -{  
682 - Q_OBJECT  
683 -  
684 - float compare(const cv::Mat &a, const cv::Mat &b) const  
685 - {  
686 - const int size = a.rows * a.cols;  
687 - Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size);  
688 - Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size);  
689 - return (aMap-bMap).squaredNorm();  
690 - }  
691 -};  
692 -  
693 -BR_REGISTER(Distance, L2Distance)  
694 -  
695 } // namespace br 655 } // namespace br
696 656
697 -#include "eigen3.moc" 657 +#include "classification/lda.moc"
openbr/plugins/liblinear.cpp renamed to openbr/plugins/classification/liblinear.cpp
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 #include <opencv2/core/core.hpp> 2 #include <opencv2/core/core.hpp>
3 #include <opencv2/ml/ml.hpp> 3 #include <opencv2/ml/ml.hpp>
4 4
5 -#include "openbr_internal.h"  
6 -#include "openbr/core/opencvutils.h" 5 +#include <openbr/plugins/openbr_internal.h>
  6 +#include <openbr/core/opencvutils.h>
7 7
8 #include <linear.h> 8 #include <linear.h>
9 9
openbr/plugins/nn.cpp renamed to openbr/plugins/classification/mlp.cpp
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
1 #include <opencv2/ml/ml.hpp> 17 #include <opencv2/ml/ml.hpp>
2 18
3 -#include "openbr_internal.h"  
4 -#include "openbr/core/qtutils.h"  
5 -#include "openbr/core/opencvutils.h"  
6 -#include "openbr/core/eigenutils.h"  
7 -#include <QString>  
8 -#include <QTemporaryFile> 19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/opencvutils.h>
9 21
10 -using namespace std;  
11 using namespace cv; 22 using namespace cv;
12 23
13 namespace br 24 namespace br
14 { 25 {
15 26
16 -static void storeMLP(const CvANN_MLP &mlp, QDataStream &stream)  
17 -{  
18 - // Create local file  
19 - QTemporaryFile tempFile;  
20 - tempFile.open();  
21 - tempFile.close();  
22 -  
23 - // Save MLP to local file  
24 - mlp.save(qPrintable(tempFile.fileName()));  
25 -  
26 - // Copy local file contents to stream  
27 - tempFile.open();  
28 - QByteArray data = tempFile.readAll();  
29 - tempFile.close();  
30 - stream << data;  
31 -}  
32 -  
33 -static void loadMLP(CvANN_MLP &mlp, QDataStream &stream)  
34 -{  
35 - // Copy local file contents from stream  
36 - QByteArray data;  
37 - stream >> data;  
38 -  
39 - // Create local file  
40 - QTemporaryFile tempFile(QDir::tempPath()+"/MLP");  
41 - tempFile.open();  
42 - tempFile.write(data);  
43 - tempFile.close();  
44 -  
45 - // Load MLP from local file  
46 - mlp.load(qPrintable(tempFile.fileName()));  
47 -}  
48 -  
49 /*! 27 /*!
50 * \ingroup transforms 28 * \ingroup transforms
51 * \brief Wraps OpenCV's multi-layer perceptron framework 29 * \brief Wraps OpenCV's multi-layer perceptron framework
@@ -124,12 +102,12 @@ private: @@ -124,12 +102,12 @@ private:
124 102
125 void load(QDataStream &stream) 103 void load(QDataStream &stream)
126 { 104 {
127 - loadMLP(mlp,stream); 105 + OpenCVUtils::loadModel(mlp, stream);
128 } 106 }
129 107
130 void store(QDataStream &stream) const 108 void store(QDataStream &stream) const
131 { 109 {
132 - storeMLP(mlp,stream); 110 + OpenCVUtils::storeModel(mlp, stream);
133 } 111 }
134 }; 112 };
135 113
@@ -137,4 +115,4 @@ BR_REGISTER(Transform, MLPTransform) @@ -137,4 +115,4 @@ BR_REGISTER(Transform, MLPTransform)
137 115
138 } // namespace br 116 } // namespace br
139 117
140 -#include "nn.moc" 118 +#include "classification/mlp.moc"
openbr/plugins/nt4.cpp renamed to openbr/plugins/classification/nt4.cpp
@@ -457,4 +457,4 @@ class NT4Compare : public Distance @@ -457,4 +457,4 @@ class NT4Compare : public Distance
457 457
458 BR_REGISTER(Distance, NT4Compare) 458 BR_REGISTER(Distance, NT4Compare)
459 459
460 -#include "nt4.moc" 460 +#include "classification/nt4.moc"
openbr/plugins/pp4.cpp renamed to openbr/plugins/classification/pp4.cpp
openbr/plugins/pp5.cpp renamed to openbr/plugins/classification/pp5.cpp
@@ -593,4 +593,4 @@ class PP5GalleryTransform: public UntrainableMetaTransform @@ -593,4 +593,4 @@ class PP5GalleryTransform: public UntrainableMetaTransform
593 593
594 BR_REGISTER(Transform, PP5GalleryTransform) 594 BR_REGISTER(Transform, PP5GalleryTransform)
595 595
596 -#include "plugins/pp5.moc" 596 +#include "classification/pp5.moc"
openbr/plugins/svm.cpp renamed to openbr/plugins/classification/svm.cpp
@@ -18,8 +18,8 @@ @@ -18,8 +18,8 @@
18 #include <opencv2/core/core.hpp> 18 #include <opencv2/core/core.hpp>
19 #include <opencv2/ml/ml.hpp> 19 #include <opencv2/ml/ml.hpp>
20 20
21 -#include "openbr_internal.h"  
22 -#include "openbr/core/opencvutils.h" 21 +#include <openbr/plugins/openbr_internal.h>
  22 +#include <openbr/core/opencvutils.h>
23 23
24 using namespace cv; 24 using namespace cv;
25 25
@@ -261,4 +261,4 @@ BR_REGISTER(Distance, SVMDistance) @@ -261,4 +261,4 @@ BR_REGISTER(Distance, SVMDistance)
261 261
262 } // namespace br 262 } // namespace br
263 263
264 -#include "svm.moc" 264 +#include "classification/svm.moc"
openbr/plugins/classification/turk.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Convenience class for training turk attribute regressors
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class TurkClassifierTransform : public Transform
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false)
  31 + Q_PROPERTY(QStringList values READ get_values WRITE set_values RESET reset_values STORED false)
  32 + Q_PROPERTY(bool isMeta READ get_isMeta WRITE set_isMeta RESET reset_isMeta STORED false)
  33 + BR_PROPERTY(QString, key, QString())
  34 + BR_PROPERTY(QStringList, values, QStringList())
  35 + BR_PROPERTY(bool, isMeta, false)
  36 +
  37 + Transform *child;
  38 +
  39 + void init()
  40 + {
  41 + QStringList classifiers;
  42 + foreach (const QString &value, values)
  43 + classifiers.append(QString("(SVM(RBF,EPS_SVR,returnDFVal=true,inputVariable=%1,outputVariable=predicted_%1)%2)").arg(key + "_" + value, isMeta ? QString("+Average+SaveMat(predicted_%1)").arg(value) : QString()));
  44 + child = Transform::make(classifiers.join("/") + (classifiers.size() > 1 ? "+Cat" : ""));
  45 + }
  46 +
  47 + void train(const QList<TemplateList> &data)
  48 + {
  49 + child->train(data);
  50 + }
  51 +
  52 + void project(const Template &src, Template &dst) const
  53 + {
  54 + child->project(src, dst);
  55 + }
  56 +
  57 + void store(QDataStream &stream) const
  58 + {
  59 + child->store(stream);
  60 + }
  61 +
  62 + void load(QDataStream &stream)
  63 + {
  64 + child->load(stream);
  65 + }
  66 +};
  67 +
  68 +BR_REGISTER(Transform, TurkClassifierTransform)
  69 +
  70 +} // namespace br
  71 +
  72 +#include "classification/turk.moc"
openbr/plugins/cluster/collectnn.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Collect nearest neighbors and append them to metadata.
  25 + * \author Charles Otto \cite caotto
  26 + */
  27 +class CollectNNTransform : public UntrainableMetaTransform
  28 +{
  29 + Q_OBJECT
  30 +
  31 + Q_PROPERTY(int keep READ get_keep WRITE set_keep RESET reset_keep STORED false)
  32 + BR_PROPERTY(int, keep, 20)
  33 +
  34 + void project(const Template &src, Template &dst) const
  35 + {
  36 + dst.file = src.file;
  37 + dst.clear();
  38 + dst.m() = cv::Mat();
  39 + Neighbors neighbors;
  40 + for (int i=0; i < src.m().cols;i++) {
  41 + // skip self compares
  42 + if (i == src.file.get<int>("FrameNumber"))
  43 + continue;
  44 + neighbors.append(Neighbor(i, src.m().at<float>(0,i)));
  45 + }
  46 + int actuallyKeep = std::min(keep, neighbors.size());
  47 + std::partial_sort(neighbors.begin(), neighbors.begin()+actuallyKeep, neighbors.end(), compareNeighbors);
  48 +
  49 + Neighbors selected = neighbors.mid(0, actuallyKeep);
  50 + dst.file.set("neighbors", QVariant::fromValue(selected));
  51 + }
  52 +};
  53 +
  54 +BR_REGISTER(Transform, CollectNNTransform)
  55 +
  56 +} // namespace br
  57 +
  58 +#include "cluster/collectnn.moc"
openbr/plugins/cluster/kmeans.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <opencv2/flann/flann.hpp>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/opencvutils.h>
  21 +
  22 +using namespace cv;
  23 +
  24 +namespace br
  25 +{
  26 +
  27 +/*!
  28 + * \ingroup transforms
  29 + * \brief Wraps OpenCV kmeans and flann.
  30 + * \author Josh Klontz \cite jklontz
  31 + */
  32 +class KMeansTransform : public Transform
  33 +{
  34 + Q_OBJECT
  35 + Q_PROPERTY(int kTrain READ get_kTrain WRITE set_kTrain RESET reset_kTrain STORED false)
  36 + Q_PROPERTY(int kSearch READ get_kSearch WRITE set_kSearch RESET reset_kSearch STORED false)
  37 + BR_PROPERTY(int, kTrain, 256)
  38 + BR_PROPERTY(int, kSearch, 1)
  39 +
  40 + Mat centers;
  41 + mutable QScopedPointer<flann::Index> index;
  42 + mutable QMutex mutex;
  43 +
  44 + void reindex()
  45 + {
  46 + index.reset(new flann::Index(centers, flann::LinearIndexParams()));
  47 + }
  48 +
  49 + void train(const TemplateList &data)
  50 + {
  51 + Mat bestLabels;
  52 + const double compactness = kmeans(OpenCVUtils::toMatByRow(data.data()), kTrain, bestLabels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, centers);
  53 + qDebug("KMeans compactness = %f", compactness);
  54 + reindex();
  55 + }
  56 +
  57 + void project(const Template &src, Template &dst) const
  58 + {
  59 + QMutexLocker locker(&mutex);
  60 + Mat dists, indicies;
  61 + index->knnSearch(src, indicies, dists, kSearch);
  62 + dst = indicies.reshape(1, 1);
  63 + }
  64 +
  65 + void load(QDataStream &stream)
  66 + {
  67 + stream >> centers;
  68 + reindex();
  69 + }
  70 +
  71 + void store(QDataStream &stream) const
  72 + {
  73 + stream << centers;
  74 + }
  75 +};
  76 +
  77 +BR_REGISTER(Transform, KMeansTransform)
  78 +
  79 +} // namespace br
  80 +
  81 +#include "cluster/kmeans.moc"
openbr/plugins/cluster.cpp renamed to openbr/plugins/cluster/knn.cpp
@@ -14,12 +14,8 @@ @@ -14,12 +14,8 @@
14 * limitations under the License. * 14 * limitations under the License. *
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16
17 -#include <opencv2/flann/flann.hpp>  
18 -  
19 -#include "openbr_internal.h"  
20 -#include "openbr/core/common.h"  
21 -#include "openbr/core/opencvutils.h"  
22 -#include <fstream> 17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/common.h>
23 19
24 using namespace cv; 20 using namespace cv;
25 21
@@ -28,58 +24,6 @@ namespace br @@ -28,58 +24,6 @@ namespace br
28 24
29 /*! 25 /*!
30 * \ingroup transforms 26 * \ingroup transforms
31 - * \brief Wraps OpenCV kmeans and flann.  
32 - * \author Josh Klontz \cite jklontz  
33 - */  
34 -class KMeansTransform : public Transform  
35 -{  
36 - Q_OBJECT  
37 - Q_PROPERTY(int kTrain READ get_kTrain WRITE set_kTrain RESET reset_kTrain STORED false)  
38 - Q_PROPERTY(int kSearch READ get_kSearch WRITE set_kSearch RESET reset_kSearch STORED false)  
39 - BR_PROPERTY(int, kTrain, 256)  
40 - BR_PROPERTY(int, kSearch, 1)  
41 -  
42 - Mat centers;  
43 - mutable QScopedPointer<flann::Index> index;  
44 - mutable QMutex mutex;  
45 -  
46 - void reindex()  
47 - {  
48 - index.reset(new flann::Index(centers, flann::LinearIndexParams()));  
49 - }  
50 -  
51 - void train(const TemplateList &data)  
52 - {  
53 - Mat bestLabels;  
54 - const double compactness = kmeans(OpenCVUtils::toMatByRow(data.data()), kTrain, bestLabels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, centers);  
55 - qDebug("KMeans compactness = %f", compactness);  
56 - reindex();  
57 - }  
58 -  
59 - void project(const Template &src, Template &dst) const  
60 - {  
61 - QMutexLocker locker(&mutex);  
62 - Mat dists, indicies;  
63 - index->knnSearch(src, indicies, dists, kSearch);  
64 - dst = indicies.reshape(1, 1);  
65 - }  
66 -  
67 - void load(QDataStream &stream)  
68 - {  
69 - stream >> centers;  
70 - reindex();  
71 - }  
72 -  
73 - void store(QDataStream &stream) const  
74 - {  
75 - stream << centers;  
76 - }  
77 -};  
78 -  
79 -BR_REGISTER(Transform, KMeansTransform)  
80 -  
81 -/*!  
82 - * \ingroup transforms  
83 * \brief K nearest neighbors classifier. 27 * \brief K nearest neighbors classifier.
84 * \author Josh Klontz \cite jklontz 28 * \author Josh Klontz \cite jklontz
85 */ 29 */
@@ -151,148 +95,6 @@ class KNNTransform : public Transform @@ -151,148 +95,6 @@ class KNNTransform : public Transform
151 95
152 BR_REGISTER(Transform, KNNTransform) 96 BR_REGISTER(Transform, KNNTransform)
153 97
154 -/*!  
155 - * \ingroup transforms  
156 - * \brief Chooses k random points to be centroids.  
157 - * \author Austin Blanton \cite imaus10  
158 - * \see KMeansTransform  
159 - */  
160 -class RandomCentroidsTransform : public Transform  
161 -{  
162 - Q_OBJECT  
163 - Q_PROPERTY(int kTrain READ get_kTrain WRITE set_kTrain RESET reset_kTrain STORED false)  
164 - Q_PROPERTY(int kSearch READ get_kSearch WRITE set_kSearch RESET reset_kSearch STORED false)  
165 - BR_PROPERTY(int, kTrain, 256)  
166 - BR_PROPERTY(int, kSearch, 1)  
167 -  
168 - Mat centers;  
169 - mutable QScopedPointer<flann::Index> index;  
170 - mutable QMutex mutex;  
171 -  
172 - void reindex()  
173 - {  
174 - index.reset(new flann::Index(centers, flann::LinearIndexParams()));  
175 - }  
176 -  
177 - void train(const TemplateList &data)  
178 - {  
179 - Mat flat = OpenCVUtils::toMatByRow(data.data());  
180 - QList<int> sample = Common::RandSample(kTrain, flat.rows, 0, true);  
181 - foreach (const int &idx, sample)  
182 - centers.push_back(flat.row(idx));  
183 - reindex();  
184 - }  
185 -  
186 - void project(const Template &src, Template &dst) const  
187 - {  
188 - QMutexLocker locker(&mutex);  
189 - Mat dists, indicies;  
190 - index->knnSearch(src, indicies, dists, kSearch);  
191 - dst = indicies.reshape(1, 1);  
192 - }  
193 -  
194 - void load(QDataStream &stream)  
195 - {  
196 - stream >> centers;  
197 - reindex();  
198 - }  
199 -  
200 - void store(QDataStream &stream) const  
201 - {  
202 - stream << centers;  
203 - }  
204 -};  
205 -  
206 -BR_REGISTER(Transform, RandomCentroidsTransform)  
207 -  
208 -class RegInitializer : public Initializer  
209 -{  
210 - Q_OBJECT  
211 -  
212 - void initialize() const  
213 - {  
214 - qRegisterMetaType<br::Neighbors>();  
215 - }  
216 -};  
217 -BR_REGISTER(Initializer, RegInitializer)  
218 -  
219 -class CollectNNTransform : public UntrainableMetaTransform  
220 -{  
221 - Q_OBJECT  
222 -  
223 - Q_PROPERTY(int keep READ get_keep WRITE set_keep RESET reset_keep STORED false)  
224 - BR_PROPERTY(int, keep, 20)  
225 -  
226 - void project(const Template &src, Template &dst) const  
227 - {  
228 - dst.file = src.file;  
229 - dst.clear();  
230 - dst.m() = cv::Mat();  
231 - Neighbors neighbors;  
232 - for (int i=0; i < src.m().cols;i++) {  
233 - // skip self compares  
234 - if (i == src.file.get<int>("FrameNumber"))  
235 - continue;  
236 - neighbors.append(Neighbor(i, src.m().at<float>(0,i)));  
237 - }  
238 - int actuallyKeep = std::min(keep, neighbors.size());  
239 - std::partial_sort(neighbors.begin(), neighbors.begin()+actuallyKeep, neighbors.end(), compareNeighbors);  
240 -  
241 - Neighbors selected = neighbors.mid(0, actuallyKeep);  
242 - dst.file.set("neighbors", QVariant::fromValue(selected));  
243 - }  
244 -};  
245 -BR_REGISTER(Transform, CollectNNTransform)  
246 -  
247 -class LogNNTransform : public TimeVaryingTransform  
248 -{  
249 - Q_OBJECT  
250 -  
251 - Q_PROPERTY(QString fileName READ get_fileName WRITE set_fileName RESET reset_fileName STORED false)  
252 - BR_PROPERTY(QString, fileName, "")  
253 -  
254 - std::fstream fout;  
255 -  
256 - void projectUpdate(const Template &src, Template &dst)  
257 - {  
258 - dst = src;  
259 -  
260 - if (!dst.file.contains("neighbors")) {  
261 - fout << std::endl;  
262 - return;  
263 - }  
264 -  
265 - Neighbors neighbors = dst.file.get<Neighbors>("neighbors");  
266 - if (neighbors.isEmpty() ) {  
267 - fout << std::endl;  
268 - return;  
269 - }  
270 -  
271 - QString aLine;  
272 - aLine.append(QString::number(neighbors[0].first)+":"+QString::number(neighbors[0].second));  
273 - for (int i=1; i < neighbors.size();i++)  
274 - aLine.append(","+QString::number(neighbors[i].first)+":"+QString::number(neighbors[i].second));  
275 -  
276 - fout << qPrintable(aLine) << std::endl;  
277 - }  
278 -  
279 - void init()  
280 - {  
281 - if (!fileName.isEmpty())  
282 - fout.open(qPrintable(fileName), std::ios_base::out);  
283 - }  
284 -  
285 - void finalize(TemplateList &output)  
286 - {  
287 - (void) output;  
288 - fout.close();  
289 - }  
290 -  
291 -public:  
292 - LogNNTransform() : TimeVaryingTransform(false, false) {}  
293 -};  
294 -BR_REGISTER(Transform, LogNNTransform)  
295 -  
296 } // namespace br 98 } // namespace br
297 99
298 -#include "cluster.moc" 100 +#include "cluster/knn.moc"
openbr/plugins/cluster/lognn.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <fstream>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup transforms
  26 + * \brief Log nearest neighbors to specified file.
  27 + * \author Charles Otto \cite caotto
  28 + */
  29 +class LogNNTransform : public TimeVaryingTransform
  30 +{
  31 + Q_OBJECT
  32 +
  33 + Q_PROPERTY(QString fileName READ get_fileName WRITE set_fileName RESET reset_fileName STORED false)
  34 + BR_PROPERTY(QString, fileName, "")
  35 +
  36 + std::fstream fout;
  37 +
  38 + void projectUpdate(const Template &src, Template &dst)
  39 + {
  40 + dst = src;
  41 +
  42 + if (!dst.file.contains("neighbors")) {
  43 + fout << std::endl;
  44 + return;
  45 + }
  46 +
  47 + Neighbors neighbors = dst.file.get<Neighbors>("neighbors");
  48 + if (neighbors.isEmpty() ) {
  49 + fout << std::endl;
  50 + return;
  51 + }
  52 +
  53 + QString aLine;
  54 + aLine.append(QString::number(neighbors[0].first)+":"+QString::number(neighbors[0].second));
  55 + for (int i=1; i < neighbors.size();i++)
  56 + aLine.append(","+QString::number(neighbors[i].first)+":"+QString::number(neighbors[i].second));
  57 +
  58 + fout << qPrintable(aLine) << std::endl;
  59 + }
  60 +
  61 + void init()
  62 + {
  63 + if (!fileName.isEmpty())
  64 + fout.open(qPrintable(fileName), std::ios_base::out);
  65 + }
  66 +
  67 + void finalize(TemplateList &output)
  68 + {
  69 + (void) output;
  70 + fout.close();
  71 + }
  72 +
  73 +public:
  74 + LogNNTransform() : TimeVaryingTransform(false, false) {}
  75 +};
  76 +
  77 +BR_REGISTER(Transform, LogNNTransform)
  78 +
  79 +} // namespace br
  80 +
  81 +#include "cluster/lognn.moc"
openbr/plugins/cluster/randomcentroids.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <opencv2/flann/flann.hpp>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/common.h>
  21 +#include <openbr/core/opencvutils.h>
  22 +
  23 +using namespace cv;
  24 +
  25 +namespace br
  26 +{
  27 +
  28 +/*!
  29 + * \ingroup transforms
  30 + * \brief Chooses k random points to be centroids.
  31 + * \author Austin Blanton \cite imaus10
  32 + * \see KMeansTransform
  33 + */
  34 +class RandomCentroidsTransform : public Transform
  35 +{
  36 + Q_OBJECT
  37 + Q_PROPERTY(int kTrain READ get_kTrain WRITE set_kTrain RESET reset_kTrain STORED false)
  38 + Q_PROPERTY(int kSearch READ get_kSearch WRITE set_kSearch RESET reset_kSearch STORED false)
  39 + BR_PROPERTY(int, kTrain, 256)
  40 + BR_PROPERTY(int, kSearch, 1)
  41 +
  42 + Mat centers;
  43 + mutable QScopedPointer<flann::Index> index;
  44 + mutable QMutex mutex;
  45 +
  46 + void reindex()
  47 + {
  48 + index.reset(new flann::Index(centers, flann::LinearIndexParams()));
  49 + }
  50 +
  51 + void train(const TemplateList &data)
  52 + {
  53 + Mat flat = OpenCVUtils::toMatByRow(data.data());
  54 + QList<int> sample = Common::RandSample(kTrain, flat.rows, 0, true);
  55 + foreach (const int &idx, sample)
  56 + centers.push_back(flat.row(idx));
  57 + reindex();
  58 + }
  59 +
  60 + void project(const Template &src, Template &dst) const
  61 + {
  62 + QMutexLocker locker(&mutex);
  63 + Mat dists, indicies;
  64 + index->knnSearch(src, indicies, dists, kSearch);
  65 + dst = indicies.reshape(1, 1);
  66 + }
  67 +
  68 + void load(QDataStream &stream)
  69 + {
  70 + stream >> centers;
  71 + reindex();
  72 + }
  73 +
  74 + void store(QDataStream &stream) const
  75 + {
  76 + stream << centers;
  77 + }
  78 +};
  79 +
  80 +BR_REGISTER(Transform, RandomCentroidsTransform)
  81 +
  82 +} //namespace br
  83 +
  84 +#include "cluster/randomcentroids.moc"
openbr/plugins/cmake/eigen3.cmake 0 → 100644
  1 +set(BR_WITH_EIGEN3 ON CACHE BOOL "Build Eigen3 plugins")
  2 +
  3 +if(${BR_WITH_EIGEN3})
  4 + find_package(Eigen3 REQUIRED)
  5 + install(FILES ${EIGEN3_LICENSE} RENAME Eigen3 DESTINATION share/openbr/licenses)
  6 +else()
  7 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/lda.cpp)
  8 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/distance/L1.cpp)
  9 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/distance/L2.cpp)
  10 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/imgproc/revertaffine.cpp)
  11 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/imgproc/integralsampler.cpp)
  12 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/imgproc/recursiveintegralsampler.cpp)
  13 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/metadata/consolidatedetections.cpp)
  14 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/metadata/delaunay.cpp)
  15 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/metadata/procrustes.cpp)
  16 +endif()
openbr/plugins/ipc2013.cmake renamed to openbr/plugins/cmake/ipc2013.cmake
@@ -2,7 +2,8 @@ set(BR_WITH_IPC2013 OFF CACHE BOOL &quot;Build with Intel Perceptual Computing SDK 20 @@ -2,7 +2,8 @@ set(BR_WITH_IPC2013 OFF CACHE BOOL &quot;Build with Intel Perceptual Computing SDK 20
2 2
3 if(${BR_WITH_IPC2013}) 3 if(${BR_WITH_IPC2013})
4 find_package(IPC2013 REQUIRED) 4 find_package(IPC2013 REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/ipc2013.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${IPC2013_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${IPC2013_LIBS})
7 install(DIRECTORY ${IPC2013_DIR}/bin/x64/ DESTINATION bin) 6 install(DIRECTORY ${IPC2013_DIR}/bin/x64/ DESTINATION bin)
  7 +else()
  8 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/ipc2013.cpp)
8 endif() 9 endif()
openbr/plugins/jni.cmake renamed to openbr/plugins/cmake/jni.cmake
@@ -3,10 +3,10 @@ set(BR_WITH_JAVA OFF CACHE BOOL &quot;Use Java Code&quot;) @@ -3,10 +3,10 @@ set(BR_WITH_JAVA OFF CACHE BOOL &quot;Use Java Code&quot;)
3 if (${BR_WITH_JAVA}) 3 if (${BR_WITH_JAVA})
4 find_package(JNI REQUIRED) 4 find_package(JNI REQUIRED)
5 find_package(JAVA REQUIRED) 5 find_package(JAVA REQUIRED)
6 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/jni.cpp)  
7 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${JNI_LIBRARIES}) 6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${JNI_LIBRARIES})
8 7
9 include_directories(${JAVA_INCLUDE_PATH}) 8 include_directories(${JAVA_INCLUDE_PATH})
10 include_directories(${JAVA_INCLUDE_PATH2}) 9 include_directories(${JAVA_INCLUDE_PATH2})
11 - 10 +else()
  11 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/core/jni.cpp)
12 endif() 12 endif()
openbr/plugins/liblinear.cmake renamed to openbr/plugins/cmake/liblinear.cmake
@@ -3,5 +3,6 @@ set(BR_WITH_LIBLINEAR OFF CACHE BOOL &quot;Build with LibLinear&quot;) @@ -3,5 +3,6 @@ set(BR_WITH_LIBLINEAR OFF CACHE BOOL &quot;Build with LibLinear&quot;)
3 if(${BR_WITH_LIBLINEAR}) 3 if(${BR_WITH_LIBLINEAR})
4 find_package(LibLinear REQUIRED) 4 find_package(LibLinear REQUIRED)
5 set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${LibLinear_SRC}) 5 set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${LibLinear_SRC})
6 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/liblinear.cpp) 6 +else()
  7 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/liblinear.cpp)
7 endif() 8 endif()
openbr/plugins/likely.cmake renamed to openbr/plugins/cmake/likely.cmake
@@ -2,6 +2,9 @@ set(BR_WITH_LIKELY OFF CACHE BOOL &quot;Build with Likely&quot;) @@ -2,6 +2,9 @@ set(BR_WITH_LIKELY OFF CACHE BOOL &quot;Build with Likely&quot;)
2 2
3 if(${BR_WITH_LIKELY}) 3 if(${BR_WITH_LIKELY})
4 find_package(Likely REQUIRED) 4 find_package(Likely REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/likely.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Likely_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Likely_LIBS})
  6 +else()
  7 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/core/likely.cpp)
  8 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/format/lmat.cpp)
  9 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/gallery/lmat.cpp)
7 endif() 10 endif()
openbr/plugins/mongoose.cmake renamed to openbr/plugins/cmake/mongoose.cmake
1 set(BR_WITH_MONGOOSE OFF CACHE BOOL "Build with Mongoose") 1 set(BR_WITH_MONGOOSE OFF CACHE BOOL "Build with Mongoose")
2 if(${BR_WITH_MONGOOSE}) 2 if(${BR_WITH_MONGOOSE})
3 find_package(Mongoose) 3 find_package(Mongoose)
4 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/mongoose.cpp ${MONGOOSE_SRC}) 4 + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${MONGOOSE_SRC})
5 install(FILES ${MONGOOSE_LICENSE} RENAME mongoose DESTINATION share/openbr/licenses) 5 install(FILES ${MONGOOSE_LICENSE} RENAME mongoose DESTINATION share/openbr/licenses)
  6 +else()
  7 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/metadata/mongoose.cpp)
6 endif() 8 endif()
openbr/plugins/qtnetwork.cmake renamed to openbr/plugins/cmake/network.cmake
@@ -3,6 +3,10 @@ if(${BR_WITH_QTNETWORK}) @@ -3,6 +3,10 @@ if(${BR_WITH_QTNETWORK})
3 find_package(Qt5Network) 3 find_package(Qt5Network)
4 find_package(HttpParser) 4 find_package(HttpParser)
5 set(QT_DEPENDENCIES ${QT_DEPENDENCIES} Network) 5 set(QT_DEPENDENCIES ${QT_DEPENDENCIES} Network)
6 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/qtnetwork.cpp ${HTTPPARSER_SRC}) 6 + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${HTTPPARSER_SRC})
7 install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser DESTINATION share/openbr/licenses) 7 install(FILES ${HTTPPARSER_LICENSE} RENAME http-parser DESTINATION share/openbr/licenses)
  8 +else()
  9 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/format/urlformat.cpp)
  10 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/format/postformat.cpp)
  11 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/gallery/postgallery.cpp)
8 endif() 12 endif()
openbr/plugins/nt4.cmake renamed to openbr/plugins/cmake/nt4.cmake
@@ -2,7 +2,8 @@ set(BR_WITH_NT4 OFF CACHE BOOL &quot;Build with Neurotec Biometric 4&quot;) @@ -2,7 +2,8 @@ set(BR_WITH_NT4 OFF CACHE BOOL &quot;Build with Neurotec Biometric 4&quot;)
2 2
3 if(${BR_WITH_NT4}) 3 if(${BR_WITH_NT4})
4 find_package(NT4 REQUIRED) 4 find_package(NT4 REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/nt4.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${NT4_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${NT4_LIBS})
7 install(DIRECTORY ${NT4_DIR_LIB}/ DESTINATION lib) 6 install(DIRECTORY ${NT4_DIR_LIB}/ DESTINATION lib)
  7 +else()
  8 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/nt4.cpp)
8 endif() 9 endif()
openbr/plugins/pp4.cmake renamed to openbr/plugins/cmake/pp4.cmake
@@ -2,8 +2,9 @@ set(BR_WITH_PP4 OFF CACHE BOOL &quot;Build with PittPatt 4&quot;) @@ -2,8 +2,9 @@ set(BR_WITH_PP4 OFF CACHE BOOL &quot;Build with PittPatt 4&quot;)
2 2
3 if(${BR_WITH_PP4}) 3 if(${BR_WITH_PP4})
4 find_package(PP4 REQUIRED) 4 find_package(PP4 REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/pp4.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP4_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP4_LIBS})
7 install(DIRECTORY ${PP4_DIR}/lib/ DESTINATION lib) 6 install(DIRECTORY ${PP4_DIR}/lib/ DESTINATION lib)
8 install(DIRECTORY ${PP4_DIR}/models/ DESTINATION models/pp4) 7 install(DIRECTORY ${PP4_DIR}/models/ DESTINATION models/pp4)
  8 +else()
  9 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/pp4.cpp)
9 endif() 10 endif()
openbr/plugins/pp5.cmake renamed to openbr/plugins/cmake/pp5.cmake
@@ -2,7 +2,6 @@ set(BR_WITH_PP5 OFF CACHE BOOL &quot;Build with PittPatt 5&quot;) @@ -2,7 +2,6 @@ set(BR_WITH_PP5 OFF CACHE BOOL &quot;Build with PittPatt 5&quot;)
2 2
3 if(${BR_WITH_PP5}) 3 if(${BR_WITH_PP5})
4 find_package(PP5 REQUIRED) 4 find_package(PP5 REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/pp5.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP5_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP5_LIBS})
7 6
8 if(WIN32) 7 if(WIN32)
@@ -12,4 +11,6 @@ if(${BR_WITH_PP5}) @@ -12,4 +11,6 @@ if(${BR_WITH_PP5})
12 endif() 11 endif()
13 12
14 install(DIRECTORY ${PP5_DIR}/models/ DESTINATION share/openbr/models/pp5) 13 install(DIRECTORY ${PP5_DIR}/models/ DESTINATION share/openbr/models/pp5)
  14 +else()
  15 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/pp5.cpp)
15 endif() 16 endif()
openbr/plugins/cmake/show.cmake 0 → 100644
  1 +if(${BR_EMBEDDED})
  2 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/gui/show.cpp)
  3 +endif()
openbr/plugins/stasm4.cmake renamed to openbr/plugins/cmake/stasm4.cmake
1 -set(BR_WITH_STASM4 ON CACHE BOOL "Build with Stasm") 1 +set(BR_WITH_STASM4 OFF CACHE BOOL "Build with Stasm")
2 2
3 if(${BR_WITH_STASM4}) 3 if(${BR_WITH_STASM4})
4 find_package(Stasm4 REQUIRED) 4 find_package(Stasm4 REQUIRED)
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/stasm4.cpp)  
6 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Stasm4_LIBS}) 5 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${Stasm4_LIBS})
7 6
8 if(WIN32) 7 if(WIN32)
@@ -12,4 +11,7 @@ if(${BR_WITH_STASM4}) @@ -12,4 +11,7 @@ if(${BR_WITH_STASM4})
12 endif() 11 endif()
13 12
14 install(DIRECTORY ${Stasm_DIR}/data/ DESTINATION share/openbr/models/stasm) 13 install(DIRECTORY ${Stasm_DIR}/data/ DESTINATION share/openbr/models/stasm)
  14 +else()
  15 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/metadata/stasm4.cpp)
  16 + set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/imgproc/revertaffine.cpp)
15 endif() 17 endif()
openbr/plugins/algorithms.cpp renamed to openbr/plugins/core/algorithms.cpp
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 * limitations under the License. * 14 * limitations under the License. *
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16
17 -#include "openbr_internal.h" 17 +#include <openbr/plugins/openbr_internal.h>
18 18
19 namespace br 19 namespace br
20 { 20 {
@@ -108,4 +108,4 @@ BR_REGISTER(Initializer, AlgorithmsInitializer) @@ -108,4 +108,4 @@ BR_REGISTER(Initializer, AlgorithmsInitializer)
108 108
109 } // namespace br 109 } // namespace br
110 110
111 -#include "algorithms.moc" 111 +#include "core/algorithms.moc"
openbr/plugins/core/attributealgorithms.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup initializers
  24 + * \brief Initializes global abbreviations with implemented algorithms for attributes
  25 + * \author Babatunde Ogunfemi \cite baba1472
  26 + */
  27 +class AttributeAlgorithmsInitializer : public Initializer
  28 +{
  29 + Q_OBJECT
  30 +
  31 + void initialize() const
  32 + {
  33 + // Constants
  34 + QString BASE="Open+PP5Register+Rename(PP5_Landmark0_Right_Eye,Affine_0)+Rename(PP5_Landmark1_Left_Eye,Affine_1)+Affine(192,240,.345,.475)+Cvt(Gray)+Stasm(false,true,[(66.24,114),(125.76,114)])";
  35 + QString SUBSPACE ="Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,4,4)+Hist(59)+Cat+PCA(0.95)";
  36 +
  37 + QString NOSE="RectFromStasmNoseWithBridge+ROI+Resize(36,24)+" + SUBSPACE;
  38 + QString MOUTH="RectFromStasmMouth+ROI+Resize(24,36)+" + SUBSPACE;
  39 + QString EYES="RectFromStasmEyes+ROI+Resize(24,36)+" + SUBSPACE;
  40 + QString HAIR="RectFromStasmHair+ROI+Resize(24,36)+" + SUBSPACE;
  41 + QString BROW="RectFromStasmBrow+ROI+Resize(24,36)+" + SUBSPACE;
  42 + QString JAW="RectFromStasmJaw+ROI+Resize(36,36)+" + SUBSPACE;
  43 + QString FACE = "Crop(24,30,144,190)+Resize(36,36)+" + SUBSPACE;
  44 +
  45 + // All Attributes
  46 + Globals->abbreviations.insert("AllAttributes", "AttributeBrow/AttributeMouth/AttributeEyes/AttributeFace/AttributeHair/AttributeNose/AttributeJaw");
  47 + Globals->abbreviations.insert("AllAttributesMatching", "(AttributeBrow)/(AttributeMouth)/(AttributeEyes)/(AttributeFace)/(AttributeHair)/(AttributeNose)/(AttributeJaw):AttributeMatch");
  48 +
  49 + //Individual Attributes
  50 + Globals->abbreviations.insert("AttributeBrow", "(" + BASE+ "+" + BROW + "+"
  51 + "TurkClassifier(eyebrowposition,[closebrows,highbrows],3)/"
  52 + "TurkClassifier(unibrow,[unibrow],3)/"
  53 + "TurkClassifier(eyebroworientation,[eyebrowsdown,eyebrowsuptodown],3)/"
  54 + "TurkClassifier(thickeyebrows,[thickeyebrows,lighteyebrows],3))");
  55 + Globals->abbreviations.insert("AttributeMouth", "(" + BASE + "+" + MOUTH + "+"
  56 + "TurkClassifier(smiling,[smiling],3)/"
  57 + "TurkClassifier(lipthickness,[cherry,big,small],3)/"
  58 + "TurkClassifier(mouthbite,[underbite,overbite],3)/"
  59 + "TurkClassifier(mouthopen,[closed,noteeth,halfteeth,allteeth],3)/"
  60 + "TurkClassifier(mouthwidth,[small,wide],3)/"
  61 + "TurkClassifier(mustache,[nomustache,linemustache,lightmustache,normalmustache,down],3)/"
  62 + "TurkClassifier(mouthasymmetry,[asymmetrical],3))");
  63 + Globals->abbreviations.insert("AttributeEyes", "(" + BASE + "+" + EYES + "+ "
  64 + "TurkClassifier(eyeseparation,[close,wide],3)/"
  65 + "TurkClassifier(eyeslant,[slant2,slant1,wild],3)/"
  66 + "TurkClassifier(benteyes,[bent])/"
  67 + "TurkClassifier(eyecolor,[darkeyes,lighteyes],3)/"
  68 + "TurkClassifier(baggyeyes,[baggy],3)/"
  69 + "TurkClassifier(almondeyes,[almond],3)/"
  70 + "TurkClassifier(buriedeyes,[buriedeyes],3)/"
  71 + "TurkClassifier(sleepyeyes,[sleepy],3)/"
  72 + "TurkClassifier(lineeyes,[line],3)/"
  73 + "TurkClassifier(roundeyes,[round],3)/"
  74 + "TurkClassifier(sharpeyes,[sharp],3)/"
  75 + "TurkClassifier(smalleyes,[smalleyes],3)/"
  76 + "TurkClassifier(glasses,[glasses],3)/"
  77 + "TurkClassifier(eyelashvisibility,[feweyelashes],3))");
  78 + Globals->abbreviations.insert("AttributeFace", "(" + BASE + "+" + FACE + "+"
  79 + "TurkClassifier(gender,[male],3)/"
  80 + "TurkClassifier(faceshape,[round,triangular,rectangular],3)/"
  81 + "TurkClassifier(cheekdensity,[puffy,in,normal],3)/"
  82 + "TurkClassifier(facemarks,[scars,moles,normal],3)/"
  83 + "TurkClassifier(facelength,[long],3)/"
  84 + "TurkClassifier(nosetoeyedist,[short,long],3)/"
  85 + "TurkClassifier(nosetomouthdist,[long,small],3))");
  86 + Globals->abbreviations.insert("AttributeHair", "(" + BASE + "+" + HAIR + "+"
  87 + "TurkClassifier(foreheadwrinkles,[wrinkled],3)/"
  88 + "TurkClassifier(foreheadsize,[smallforehead,largeforehead],3)/"
  89 + "TurkClassifier(haircolor,[darkhair,lighthair,greyhair],3)/"
  90 + "TurkClassifier(hairdensity,[thick,bald,thin,halfbald],3)/"
  91 + "TurkClassifier(widowspeak,[widowspeak],3)/"
  92 + "TurkClassifier(hairstyle,[curlyhair],3))");
  93 + Globals->abbreviations.insert("AttributeNose", "(" + BASE + "+" + NOSE + "+"
  94 + "TurkClassifier(noseorientation,[upnose,downnose],3)/"
  95 + "TurkClassifier(nosewidth,[small,thick],3)/"
  96 + "TurkClassifier(nosesize,[smallnose,bignose],3)/"
  97 + "TurkClassifier(brokennose,[broken],3))");
  98 + Globals->abbreviations.insert("AttributeJaw", "(" + BASE + "+" + JAW + "+"
  99 + "TurkClassifier(beard,[nobeard,bigbeard,lightbeard,goatee,linebeard,normalbeard,lincolnbeard],3)/"
  100 + "TurkClassifier(chinsize,[shortchin,longchin],3))");
  101 + Globals->abbreviations.insert("AttributeMatch", "Fuse(["
  102 + "Turk(eyebrowposition,[closebrows,highbrows],3),"
  103 + "Turk(unibrow,[unibrow],3),"
  104 + "Turk(eyebroworientation,[eyebrowsdown,eyebrowsuptodown],3),"
  105 + "Turk(thickeyebrows,[thickeyebrows,lighteyebrows],3),"
  106 + "Turk(smiling,[smiling],3),"
  107 + "Turk(lipthickness,[cherry,big,small],3),"
  108 + "Turk(mouthbite,[underbite,overbite],3),"
  109 + "Turk(mouthopen,[closed,noteeth,halfteeth,allteeth],3),"
  110 + "Turk(mouthwidth,[small,wide],3),"
  111 + "Turk(mustache,[nomustache,linemustache,lightmustache,normalmustache,down],3),"
  112 + "Turk(mouthasymmetry,[asymmetrical],3),"
  113 + "Turk(eyeseparation,[close,wide],3),"
  114 + "Turk(eyeslant,[slant2,slant1,wild],3),"
  115 + "Turk(benteyes,[bent],3),"
  116 + "Turk(eyecolor,[darkeyes,lighteyes],3),"
  117 + "Turk(baggyeyes,[baggy],3),"
  118 + "Turk(almondeyes,[almond],3),"
  119 + "Turk(buriedeyes,[buriedeyes],3),"
  120 + "Turk(sleepyeyes,[sleepy],3),"
  121 + "Turk(lineeyes,[line],3),"
  122 + "Turk(roundeyes,[round],3),"
  123 + "Turk(sharpeyes,[sharp],3),"
  124 + "Turk(smalleyes,[smalleyes],3),"
  125 + "Turk(glasses,[glasses],3),"
  126 + "Turk(eyelashvisibility,[feweyelashes],3),"
  127 + "Turk(gender,[male],3),"
  128 + "Turk(faceshape,[round,triangular,rectangular],3),"
  129 + "Turk(cheekdensity,[puffy,in,normal],3),"
  130 + "Turk(facemarks,[scars,moles,normal],3),"
  131 + "Turk(facelength,[long],3),"
  132 + "Turk(nosetoeyedist,[short,long],3),"
  133 + "Turk(nosetomouthdist,[long,small],3),"
  134 + "Turk(foreheadwrinkles,[wrinkled],3),"
  135 + "Turk(foreheadsize,[smallforehead,largeforehead],3),"
  136 + "Turk(haircolor,[darkhair,lighthair,greyhair],3),"
  137 + "Turk(hairdensity,[thick,bald,thin,halfbald],3),"
  138 + "Turk(widowspeak,[widowspeak],3),"
  139 + "Turk(hairstyle,[curlyhair],3),"
  140 + "Turk(noseorientation,[upnose,downnose],3),"
  141 + "Turk(nosewidth,[small,thick],3),"
  142 + "Turk(nosesize,[smallnose,bignose],3),"
  143 + "Turk(brokennose,[broken],3),"
  144 + "Turk(beard,[nobeard,bigbeard,lightbeard,goatee,linebeard,normalbeard,lincolnbeard],3),"
  145 + "Turk(chinsize,[shortchin,longchin],3)])");
  146 + }
  147 +};
  148 +
  149 +BR_REGISTER(Initializer, AttributeAlgorithmsInitializer)
  150 +
  151 +} // namespace br
  152 +
  153 +#include "core/attributealgorithms.moc"
openbr/plugins/core/cache.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Caches br::Transform::project() results.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class CacheTransform : public MetaTransform
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  31 + BR_PROPERTY(br::Transform*, transform, NULL)
  32 +
  33 + static QHash<QString, Template> cache;
  34 + static QMutex cacheLock;
  35 +
  36 +public:
  37 + ~CacheTransform()
  38 + {
  39 + if (cache.isEmpty()) return;
  40 +
  41 + // Write to cache
  42 + QFile file("Cache");
  43 + if (!file.open(QFile::WriteOnly))
  44 + qFatal("Unable to open %s for writing.", qPrintable(file.fileName()));
  45 + QDataStream stream(&file);
  46 + stream << cache;
  47 + file.close();
  48 + }
  49 +
  50 +private:
  51 + void init()
  52 + {
  53 + if (!transform) return;
  54 +
  55 + trainable = transform->trainable;
  56 + if (!cache.isEmpty()) return;
  57 +
  58 + // Read from cache
  59 + QFile file("Cache");
  60 + if (file.exists()) {
  61 + if (!file.open(QFile::ReadOnly))
  62 + qFatal("Unable to open %s for reading.", qPrintable(file.fileName()));
  63 + QDataStream stream(&file);
  64 + stream >> cache;
  65 + file.close();
  66 + }
  67 + }
  68 +
  69 + void train(const QList<TemplateList> &data)
  70 + {
  71 + transform->train(data);
  72 + }
  73 +
  74 + void project(const Template &src, Template &dst) const
  75 + {
  76 + const QString &file = src.file;
  77 + if (cache.contains(file)) {
  78 + dst = cache[file];
  79 + } else {
  80 + transform->project(src, dst);
  81 + cacheLock.lock();
  82 + cache[file] = dst;
  83 + cacheLock.unlock();
  84 + }
  85 + }
  86 +};
  87 +
  88 +QHash<QString, Template> CacheTransform::cache;
  89 +QMutex CacheTransform::cacheLock;
  90 +
  91 +BR_REGISTER(Transform, CacheTransform)
  92 +
  93 +} // namespace br
  94 +
  95 +#include "core/cache.moc"
openbr/plugins/core/contract.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief It's like the opposite of ExpandTransform, but not really
  25 + * \author Charles Otto \cite caotto
  26 + *
  27 + * Given a set of templatelists as input, concatenate them onto a single Template
  28 + */
  29 +class ContractTransform : public UntrainableMetaTransform
  30 +{
  31 + Q_OBJECT
  32 +
  33 + virtual void project(const TemplateList &src, TemplateList &dst) const
  34 + {
  35 + if (src.empty()) return;
  36 + Template out;
  37 +
  38 + foreach (const Template &t, src) {
  39 + out.merge(t);
  40 + }
  41 + out.file.clearRects();
  42 + foreach (const Template &t, src) {
  43 + if (!t.file.rects().empty())
  44 + out.file.appendRects(t.file.rects());
  45 + }
  46 + dst.clear();
  47 + dst.append(out);
  48 + }
  49 +
  50 + virtual void project(const Template &src, Template &dst) const
  51 + {
  52 + qFatal("this has gone bad");
  53 + (void) src; (void) dst;
  54 + }
  55 +};
  56 +
  57 +BR_REGISTER(Transform, ContractTransform)
  58 +
  59 +} // namespace br
  60 +
  61 +#include "core/contract.moc"
openbr/plugins/validate.cpp renamed to openbr/plugins/core/crossvalidate.cpp
1 -#include <QFutureSynchronizer>  
2 -#include <QtConcurrentRun>  
3 -#include "openbr_internal.h"  
4 -#include "openbr/core/common.h"  
5 -#include <openbr/core/qtutils.h> 1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/common.h>
6 21
7 namespace br 22 namespace br
8 { 23 {
@@ -134,138 +149,6 @@ class CrossValidateTransform : public MetaTransform @@ -134,138 +149,6 @@ class CrossValidateTransform : public MetaTransform
134 149
135 BR_REGISTER(Transform, CrossValidateTransform) 150 BR_REGISTER(Transform, CrossValidateTransform)
136 151
137 -/*!  
138 - * \ingroup distances  
139 - * \brief Cross validate a distance metric.  
140 - * \author Josh Klontz \cite jklontz  
141 - */  
142 -class CrossValidateDistance : public UntrainableDistance  
143 -{  
144 - Q_OBJECT  
145 -  
146 - float compare(const Template &a, const Template &b) const  
147 - {  
148 - static const QString key("Partition"); // More efficient to preallocate this  
149 - const int partitionA = a.file.get<int>(key, 0);  
150 - const int partitionB = b.file.get<int>(key, 0);  
151 - return (partitionA != partitionB) ? -std::numeric_limits<float>::max() : 0;  
152 - }  
153 -};  
154 -  
155 -BR_REGISTER(Distance, CrossValidateDistance)  
156 -  
157 -/*!  
158 - * \ingroup distances  
159 - * \brief Checks target metadata against filters.  
160 - * \author Josh Klontz \cite jklontz  
161 - */  
162 -class FilterDistance : public UntrainableDistance  
163 -{  
164 - Q_OBJECT  
165 -  
166 - float compare(const Template &a, const Template &b) const  
167 - {  
168 - (void) b; // Query template isn't checked  
169 - foreach (const QString &key, Globals->filters.keys()) {  
170 - bool keep = false;  
171 - const QString metadata = a.file.get<QString>(key, "");  
172 - if (Globals->filters[key].isEmpty()) continue;  
173 - if (metadata.isEmpty()) return -std::numeric_limits<float>::max();  
174 - foreach (const QString &value, Globals->filters[key]) {  
175 - if (metadata == value) {  
176 - keep = true;  
177 - break;  
178 - }  
179 - }  
180 - if (!keep) return -std::numeric_limits<float>::max();  
181 - }  
182 - return 0;  
183 - }  
184 -};  
185 -  
186 -BR_REGISTER(Distance, FilterDistance)  
187 -  
188 -/*!  
189 - * \ingroup distances  
190 - * \brief Checks target metadata against query metadata.  
191 - * \author Scott Klum \cite sklum  
192 - */  
193 -class MetadataDistance : public UntrainableDistance  
194 -{  
195 - Q_OBJECT  
196 -  
197 - Q_PROPERTY(QStringList filters READ get_filters WRITE set_filters RESET reset_filters STORED false)  
198 - BR_PROPERTY(QStringList, filters, QStringList())  
199 -  
200 - float compare(const Template &a, const Template &b) const  
201 - {  
202 - foreach (const QString &key, filters) {  
203 - QString aValue = a.file.get<QString>(key, QString());  
204 - QString bValue = b.file.get<QString>(key, QString());  
205 -  
206 - // The query value may be a range. Let's check.  
207 - if (bValue.isEmpty()) bValue = QtUtils::toString(b.file.get<QPointF>(key, QPointF()));  
208 -  
209 - if (aValue.isEmpty() || bValue.isEmpty()) continue;  
210 -  
211 - bool keep = false;  
212 - bool ok;  
213 -  
214 - QPointF range = QtUtils::toPoint(bValue,&ok);  
215 -  
216 - if (ok) /* Range */ {  
217 - int value = range.x();  
218 - int upperBound = range.y();  
219 -  
220 - while (value <= upperBound) {  
221 - if (aValue == QString::number(value)) {  
222 - keep = true;  
223 - break;  
224 - }  
225 - value++;  
226 - }  
227 - }  
228 - else if (aValue == bValue) keep = true;  
229 -  
230 - if (!keep) return -std::numeric_limits<float>::max();  
231 - }  
232 - return 0;  
233 - }  
234 -};  
235 -  
236 -  
237 -BR_REGISTER(Distance, MetadataDistance)  
238 -  
239 -/*!  
240 - * \ingroup distances  
241 - * \brief Sets distance to -FLOAT_MAX if a target template has/doesn't have a key.  
242 - * \author Scott Klum \cite sklum  
243 - */  
244 -class RejectDistance : public UntrainableDistance  
245 -{  
246 - Q_OBJECT  
247 -  
248 - Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false)  
249 - BR_PROPERTY(QStringList, keys, QStringList())  
250 - Q_PROPERTY(bool rejectIfContains READ get_rejectIfContains WRITE set_rejectIfContains RESET reset_rejectIfContains STORED false)  
251 - BR_PROPERTY(bool, rejectIfContains, false)  
252 -  
253 - float compare(const Template &a, const Template &b) const  
254 - {  
255 - // We don't look at the query  
256 - (void) b;  
257 -  
258 - foreach (const QString &key, keys)  
259 - if ((rejectIfContains && a.file.contains(key)) || (!rejectIfContains && !a.file.contains(key)))  
260 - return -std::numeric_limits<float>::max();  
261 -  
262 - return 0;  
263 - }  
264 -};  
265 -  
266 -  
267 -BR_REGISTER(Distance, RejectDistance)  
268 -  
269 } // namespace br 152 } // namespace br
270 153
271 -#include "validate.moc" 154 +#include "core/crossvalidate.moc"
openbr/plugins/core/discard.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Removes all template's matrices.
  25 + * \see IdentityTransform FirstTransform RestTransform RemoveTransform
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class DiscardTransform : public UntrainableMetaTransform
  29 +{
  30 + Q_OBJECT
  31 +
  32 + void project(const Template &src, Template &dst) const
  33 + {
  34 + dst.file = src.file;
  35 + }
  36 +};
  37 +
  38 +BR_REGISTER(Transform, DiscardTransform)
  39 +
  40 +} // namespace br
  41 +
  42 +#include "core/discard.moc"
openbr/plugins/core/discardtemplates.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +class DiscardTemplatesTransform : public UntrainableMetaTransform
  23 +{
  24 + Q_OBJECT
  25 +
  26 + void project(const Template &src, Template &dst) const
  27 + {
  28 + (void) src; (void) dst;
  29 + qFatal("Incorrect project called on DiscardTemplatesTransform");
  30 + }
  31 + void project(const TemplateList &src, TemplateList &dst) const
  32 + {
  33 + (void) src;
  34 + dst.clear();
  35 + }
  36 +};
  37 +
  38 +BR_REGISTER(Transform, DiscardTemplatesTransform)
  39 +
  40 +} // namespace br
  41 +
  42 +#include "core/discardtemplates.moc"
openbr/plugins/core/distributetemplate.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +static void _projectList(const Transform *transform, const TemplateList *src, TemplateList *dst)
  25 +{
  26 + transform->project(*src, *dst);
  27 +}
  28 +
  29 +class DistributeTemplateTransform : public MetaTransform
  30 +{
  31 + Q_OBJECT
  32 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  33 + BR_PROPERTY(br::Transform*, transform, NULL)
  34 +
  35 +public:
  36 +
  37 + Transform *smartCopy(bool &newTransform)
  38 + {
  39 + if (!transform->timeVarying()) {
  40 + newTransform = false;
  41 + return this;
  42 + }
  43 + newTransform = true;
  44 +
  45 + DistributeTemplateTransform *output = new DistributeTemplateTransform;
  46 + bool newChild = false;
  47 + output->transform = transform->smartCopy(newChild);
  48 + if (newChild)
  49 + output->transform->setParent(output);
  50 +
  51 + return output;
  52 + }
  53 +
  54 + void train(const QList<TemplateList> &data)
  55 + {
  56 + if (!transform->trainable) {
  57 + qWarning("Attempted to train untrainable transform, nothing will happen.");
  58 + return;
  59 + }
  60 +
  61 + QList<TemplateList> separated;
  62 + foreach (const TemplateList &list, data) {
  63 + foreach (const Template &t, list) {
  64 + separated.append(TemplateList());
  65 + separated.last().append(t);
  66 + }
  67 + }
  68 +
  69 + transform->train(separated);
  70 + }
  71 +
  72 + void project(const Template &src, Template &dst) const
  73 + {
  74 + TemplateList input;
  75 + input.append(src);
  76 + TemplateList output;
  77 + project(input, output);
  78 +
  79 + if (output.size() != 1) qFatal("output contains more than 1 template");
  80 + else dst = output[0];
  81 + }
  82 +
  83 + // For each input template, form a single element TemplateList, push all those
  84 + // lists through transform, and form dst by concatenating the results.
  85 + // Process the single elemnt templates in parallel if parallelism is enabled.
  86 + void project(const TemplateList &src, TemplateList &dst) const
  87 + {
  88 + // Pre-allocate output for each template
  89 + QList<TemplateList> output_buffer;
  90 + output_buffer.reserve(src.size());
  91 +
  92 + // Can't declare this local to the loop because it would go out of scope
  93 + QList<TemplateList> input_buffer;
  94 + input_buffer.reserve(src.size());
  95 +
  96 + QFutureSynchronizer<void> futures;
  97 +
  98 + for (int i =0; i < src.size();i++) {
  99 + input_buffer.append(TemplateList());
  100 + output_buffer.append(TemplateList());
  101 + }
  102 + QList<QFuture<void> > temp;
  103 + temp.reserve(src.size());
  104 + for (int i=0; i<src.size(); i++) {
  105 + input_buffer[i].append(src[i]);
  106 +
  107 + if (Globals->parallelism > 1) temp.append(QtConcurrent::run(_projectList, transform, &input_buffer[i], &output_buffer[i]));
  108 + else _projectList(transform, &input_buffer[i], &output_buffer[i]);
  109 + }
  110 + // We add the futures in reverse order, since in Qt 5.1 at least the
  111 + // waiting thread will wait on them in the order added (which for uniform priority
  112 + // threads is the order of execution), and we want the waiting thread to go in the opposite order
  113 + // so that it can steal runnables and do something besides wait.
  114 + for (int i = temp.size() - 1; i >= 0; i--) {
  115 + futures.addFuture(temp[i]);
  116 + }
  117 +
  118 + futures.waitForFinished();
  119 +
  120 + for (int i=0; i<src.size(); i++) dst.append(output_buffer[i]);
  121 + }
  122 +
  123 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  124 + {
  125 + this->project(src, dst);
  126 + return;
  127 + }
  128 +
  129 + void init()
  130 + {
  131 + if (!transform)
  132 + return;
  133 +
  134 + trainable = transform->trainable;
  135 + }
  136 +
  137 +};
  138 +BR_REGISTER(Transform, DistributeTemplateTransform)
  139 +
  140 +} // namespace br
  141 +
  142 +#include "core/distributetemplate.moc"
openbr/plugins/core/downsampletraining.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +static TemplateList Downsample(const TemplateList &templates, int classes, int instances, float fraction, const QString &inputVariable, const QStringList &gallery, const QStringList &subjects)
  23 +{
  24 + // Return early when no downsampling is required
  25 + if ((classes == std::numeric_limits<int>::max()) &&
  26 + (instances == std::numeric_limits<int>::max()) &&
  27 + (fraction >= 1) &&
  28 + (gallery.isEmpty()) &&
  29 + (subjects.isEmpty()))
  30 + return templates;
  31 +
  32 + const bool atLeast = instances < 0;
  33 + instances = abs(instances);
  34 +
  35 + QList<QString> allLabels = File::get<QString>(templates, inputVariable);
  36 +
  37 + QList<QString> uniqueLabels = allLabels.toSet().toList();
  38 + qSort(uniqueLabels);
  39 +
  40 + QMap<QString,int> counts = templates.countValues<QString>(inputVariable, instances != std::numeric_limits<int>::max());
  41 +
  42 + if ((instances != std::numeric_limits<int>::max()) && (classes != std::numeric_limits<int>::max()))
  43 + foreach (const QString &label, counts.keys())
  44 + if (counts[label] < instances)
  45 + counts.remove(label);
  46 +
  47 + uniqueLabels = counts.keys();
  48 + if ((classes != std::numeric_limits<int>::max()) && (uniqueLabels.size() < classes))
  49 + qWarning("Downsample requested %d classes but only %d are available.", classes, uniqueLabels.size());
  50 +
  51 + QList<QString> selectedLabels = uniqueLabels;
  52 + if (classes < uniqueLabels.size()) {
  53 + std::random_shuffle(selectedLabels.begin(), selectedLabels.end());
  54 + selectedLabels = selectedLabels.mid(0, classes);
  55 + }
  56 +
  57 + TemplateList downsample;
  58 + for (int i=0; i<selectedLabels.size(); i++) {
  59 + const QString selectedLabel = selectedLabels[i];
  60 + QList<int> indices;
  61 + for (int j=0; j<allLabels.size(); j++)
  62 + if ((allLabels[j] == selectedLabel) && (!templates.value(j).file.get<bool>("FTE", false)) && (!templates.value(j).file.get<bool>("PossibleFTE", false)))
  63 + indices.append(j);
  64 +
  65 + std::random_shuffle(indices.begin(), indices.end());
  66 + const int max = atLeast ? indices.size() : std::min(indices.size(), instances);
  67 + for (int j=0; j<max; j++)
  68 + downsample.append(templates.value(indices[j]));
  69 + }
  70 +
  71 + if (fraction < 1) {
  72 + std::random_shuffle(downsample.begin(), downsample.end());
  73 + downsample = downsample.mid(0, downsample.size()*fraction);
  74 + }
  75 +
  76 + if (!gallery.isEmpty())
  77 + for (int i=downsample.size()-1; i>=0; i--)
  78 + if (!gallery.contains(downsample[i].file.get<QString>("Gallery")))
  79 + downsample.removeAt(i);
  80 +
  81 + if (!subjects.isEmpty())
  82 + for (int i=downsample.size()-1; i>=0; i--)
  83 + if (subjects.contains(downsample[i].file.get<QString>(inputVariable)))
  84 + downsample.removeAt(i);
  85 +
  86 + return downsample;
  87 +}
  88 +
  89 +class DownsampleTrainingTransform : public Transform
  90 +{
  91 + Q_OBJECT
  92 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform STORED true)
  93 + Q_PROPERTY(int classes READ get_classes WRITE set_classes RESET reset_classes STORED false)
  94 + Q_PROPERTY(int instances READ get_instances WRITE set_instances RESET reset_instances STORED false)
  95 + Q_PROPERTY(float fraction READ get_fraction WRITE set_fraction RESET reset_fraction STORED false)
  96 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  97 + Q_PROPERTY(QStringList gallery READ get_gallery WRITE set_gallery RESET reset_gallery STORED false)
  98 + Q_PROPERTY(QStringList subjects READ get_subjects WRITE set_subjects RESET reset_subjects STORED false)
  99 + BR_PROPERTY(br::Transform*, transform, NULL)
  100 + BR_PROPERTY(int, classes, std::numeric_limits<int>::max())
  101 + BR_PROPERTY(int, instances, std::numeric_limits<int>::max())
  102 + BR_PROPERTY(float, fraction, 1)
  103 + BR_PROPERTY(QString, inputVariable, "Label")
  104 + BR_PROPERTY(QStringList, gallery, QStringList())
  105 + BR_PROPERTY(QStringList, subjects, QStringList())
  106 +
  107 +
  108 + Transform *simplify(bool &newTForm)
  109 + {
  110 + Transform *res = transform->simplify(newTForm);
  111 + return res;
  112 + }
  113 +
  114 + void project(const Template &src, Template &dst) const
  115 + {
  116 + transform->project(src,dst);
  117 + }
  118 +
  119 +
  120 + void train(const TemplateList &data)
  121 + {
  122 + if (!transform || !transform->trainable)
  123 + return;
  124 +
  125 + TemplateList downsampled = Downsample(data, classes, instances, fraction, inputVariable, gallery, subjects);
  126 +
  127 + transform->train(downsampled);
  128 + }
  129 +};
  130 +
  131 +BR_REGISTER(Transform, DownsampleTrainingTransform)
  132 +
  133 +} // namespace br
  134 +
  135 +#include "core/downsampletraining.moc"
openbr/plugins/core/event.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +class EventTransform : public UntrainableMetaTransform
  23 +{
  24 + Q_OBJECT
  25 + Q_PROPERTY(QString eventName READ get_eventName WRITE set_eventName RESET reset_eventName STORED false)
  26 + BR_PROPERTY(QString, eventName, "")
  27 +
  28 + TemplateEvent event;
  29 +
  30 + void project(const Template &src, Template &dst) const
  31 + {
  32 + dst = src;
  33 + event.pulseSignal(dst);
  34 + }
  35 +
  36 + TemplateEvent *getEvent(const QString &name)
  37 + {
  38 + return name == eventName ? &event : NULL;
  39 + }
  40 +};
  41 +
  42 +BR_REGISTER(Transform, EventTransform)
  43 +
  44 +} // namespace br
  45 +
  46 +#include "core/event.moc"
openbr/plugins/core/expand.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +static TemplateList Expanded(const TemplateList &templates)
  23 +{
  24 + TemplateList expanded;
  25 + foreach (const Template &t, templates) {
  26 + const bool enrollAll = t.file.get<bool>("enrollAll");
  27 + if (t.isEmpty()) {
  28 + if (!enrollAll)
  29 + expanded.append(t);
  30 + continue;
  31 + }
  32 +
  33 + const QList<QPointF> points = t.file.points();
  34 + const QList<QRectF> rects = t.file.rects();
  35 + if (points.size() % t.size() != 0) qFatal("Uneven point count.");
  36 + if (rects.size() % t.size() != 0) qFatal("Uneven rect count.");
  37 + const int pointStep = points.size() / t.size();
  38 + const int rectStep = rects.size() / t.size();
  39 +
  40 + for (int i=0; i<t.size(); i++) {
  41 + expanded.append(Template(t.file, t[i]));
  42 + expanded.last().file.setRects(rects.mid(i*rectStep, rectStep));
  43 + expanded.last().file.setPoints(points.mid(i*pointStep, pointStep));
  44 + }
  45 + }
  46 + return expanded;
  47 +}
  48 +
  49 +/*!
  50 + * \ingroup transforms
  51 + * \brief Performs an expansion step on input templatelists
  52 + * \author Josh Klontz \cite jklontz
  53 + *
  54 + * Each matrix in an input Template is expanded into its own template.
  55 + *
  56 + * \see PipeTransform
  57 + */
  58 +class ExpandTransform : public UntrainableMetaTransform
  59 +{
  60 + Q_OBJECT
  61 +
  62 + virtual void project(const TemplateList &src, TemplateList &dst) const
  63 + {
  64 + dst = Expanded(src);
  65 + }
  66 +
  67 + virtual void project(const Template &src, Template &dst) const
  68 + {
  69 + dst = src;
  70 + qDebug("Called Expand project(Template,Template), nothing will happen");
  71 + }
  72 +};
  73 +
  74 +BR_REGISTER(Transform, ExpandTransform)
  75 +
  76 +} // namespace br
  77 +
  78 +#include "core/expand.moc"
openbr/plugins/core/first.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Removes all but the first matrix from the template.
  25 + * \see IdentityTransform DiscardTransform RestTransform RemoveTransform
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class FirstTransform : public UntrainableMetaTransform
  29 +{
  30 + Q_OBJECT
  31 +
  32 + void project(const Template &src, Template &dst) const
  33 + {
  34 + // AggregateFrames will leave the Template empty
  35 + // if it hasn't filled up the buffer
  36 + // so we gotta anticipate an empty Template
  37 + if (src.empty()) return;
  38 + dst.file = src.file;
  39 + dst = src.m();
  40 + }
  41 +};
  42 +
  43 +BR_REGISTER(Transform, FirstTransform)
  44 +
  45 +} // namespace br
  46 +
  47 +#include "core/first.moc"
openbr/plugins/core/fork.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +static void _train(Transform *transform, const QList<TemplateList> *data)
  25 +{
  26 + transform->train(*data);
  27 +}
  28 +
  29 +/*!
  30 + * \ingroup transforms
  31 + * \brief Transforms in parallel.
  32 + * \author Josh Klontz \cite jklontz
  33 + *
  34 + * The source br::Template is seperately given to each transform and the results are appended together.
  35 + *
  36 + * \see PipeTransform
  37 + */
  38 +class ForkTransform : public CompositeTransform
  39 +{
  40 + Q_OBJECT
  41 +
  42 + void train(const QList<TemplateList> &data)
  43 + {
  44 + if (!trainable) return;
  45 + QFutureSynchronizer<void> futures;
  46 + for (int i=0; i<transforms.size(); i++)
  47 + futures.addFuture(QtConcurrent::run(_train, transforms[i], &data));
  48 + futures.waitForFinished();
  49 + }
  50 +
  51 + // same as _project, but calls projectUpdate on sub-transforms
  52 + void projectupdate(const Template &src, Template &dst)
  53 + {
  54 + foreach (Transform *f, transforms) {
  55 + try {
  56 + Template res;
  57 + f->projectUpdate(src, res);
  58 + dst.merge(res);
  59 + } catch (...) {
  60 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  61 + dst = Template(src.file);
  62 + dst.file.fte = true;
  63 + break;
  64 + }
  65 + }
  66 + }
  67 +
  68 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  69 + {
  70 + dst.reserve(src.size());
  71 + for (int i=0; i<src.size(); i++) dst.append(Template(src[i].file));
  72 + foreach (Transform *f, transforms) {
  73 + TemplateList m;
  74 + f->projectUpdate(src, m);
  75 + if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
  76 + for (int i=0; i<src.size(); i++) dst[i].merge(m[i]);
  77 + }
  78 + }
  79 +
  80 + // this is probably going to go bad, fork transform probably won't work well in a variable
  81 + // input/output scenario
  82 + virtual void finalize(TemplateList &output)
  83 + {
  84 + output.clear();
  85 + // For each transform,
  86 + for (int i = 0; i < transforms.size(); i++)
  87 + {
  88 + // Collect any final templates
  89 + TemplateList last_set;
  90 + transforms[i]->finalize(last_set);
  91 + if (last_set.empty())
  92 + continue;
  93 +
  94 + if (output.empty()) output = last_set;
  95 + else
  96 + {
  97 + // is the number of templates received from this transform consistent with the number
  98 + // received previously? If not we can't do anything coherent here.
  99 + if (last_set.size() != output.size())
  100 + qFatal("mismatched template list sizes in ForkTransform");
  101 + for (int j = 0; j < output.size(); j++) {
  102 + output[j].append(last_set[j]);
  103 + }
  104 + }
  105 + }
  106 + }
  107 +
  108 +protected:
  109 +
  110 + // Apply each transform to src, concatenate the results
  111 + void _project(const Template &src, Template &dst) const
  112 + {
  113 + foreach (const Transform *f, transforms) {
  114 + try {
  115 + dst.merge((*f)(src));
  116 + } catch (...) {
  117 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  118 + dst = Template(src.file);
  119 + dst.file.fte = true;
  120 + break;
  121 + }
  122 + }
  123 + }
  124 +
  125 + void _project(const TemplateList &src, TemplateList &dst) const
  126 + {
  127 + dst.reserve(src.size());
  128 + for (int i=0; i<src.size(); i++) dst.append(Template(src[i].file));
  129 + foreach (const Transform *f, transforms) {
  130 + TemplateList m;
  131 + f->project(src, m);
  132 + if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
  133 + for (int i=0; i<src.size(); i++) dst[i].merge(m[i]);
  134 + }
  135 + }
  136 +
  137 +};
  138 +
  139 +BR_REGISTER(Transform, ForkTransform)
  140 +
  141 +} // namespace br
  142 +
  143 +#include "core/fork.moc"
openbr/plugins/core/fte.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/common.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup transforms
  25 + * \brief Flags images that failed to enroll based on the specified transform.
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class FTETransform : public Transform
  29 +{
  30 + Q_OBJECT
  31 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  32 + Q_PROPERTY(float min READ get_min WRITE set_min RESET reset_min)
  33 + Q_PROPERTY(float max READ get_max WRITE set_max RESET reset_max)
  34 + BR_PROPERTY(br::Transform*, transform, NULL)
  35 + BR_PROPERTY(float, min, -std::numeric_limits<float>::max())
  36 + BR_PROPERTY(float, max, std::numeric_limits<float>::max())
  37 +
  38 + void train(const TemplateList &data)
  39 + {
  40 + transform->train(data);
  41 +
  42 + TemplateList projectedData;
  43 + transform->project(data, projectedData);
  44 +
  45 + QList<float> vals;
  46 + foreach (const Template &t, projectedData) {
  47 + if (!t.file.contains(transform->objectName()))
  48 + qFatal("Matrix metadata missing key %s.", qPrintable(transform->objectName()));
  49 + vals.append(t.file.get<float>(transform->objectName()));
  50 + }
  51 + float q1, q3;
  52 + Common::Median(vals, &q1, &q3);
  53 + min = q1 - 1.5 * (q3 - q1);
  54 + max = q3 + 1.5 * (q3 - q1);
  55 + }
  56 +
  57 + void project(const Template &src, Template &dst) const
  58 + {
  59 + Template projectedSrc;
  60 + transform->project(src, projectedSrc);
  61 + const float val = projectedSrc.file.get<float>(transform->objectName());
  62 +
  63 + dst = src;
  64 + dst.file.set(transform->objectName(), val);
  65 + dst.file.set("PossibleFTE", (val < min) || (val > max));
  66 + }
  67 +};
  68 +
  69 +BR_REGISTER(Transform, FTETransform)
  70 +
  71 +} // namespace br
  72 +
  73 +#include "core/fte.moc"
openbr/plugins/core/gallerycompare.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/opencvutils.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup transforms
  25 + * \brief Compare each template to a fixed gallery (with name = galleryName), using the specified distance.
  26 + * dst will contain a 1 by n vector of scores.
  27 + * \author Charles Otto \cite caotto
  28 + */
  29 +class GalleryCompareTransform : public Transform
  30 +{
  31 + Q_OBJECT
  32 + Q_PROPERTY(br::Distance *distance READ get_distance WRITE set_distance RESET reset_distance STORED true)
  33 + Q_PROPERTY(QString galleryName READ get_galleryName WRITE set_galleryName RESET reset_galleryName STORED false)
  34 + BR_PROPERTY(br::Distance*, distance, NULL)
  35 + BR_PROPERTY(QString, galleryName, "")
  36 +
  37 + TemplateList gallery;
  38 +
  39 + void project(const Template &src, Template &dst) const
  40 + {
  41 + dst = src;
  42 + if (gallery.isEmpty())
  43 + return;
  44 +
  45 + QList<float> line = distance->compare(gallery, src);
  46 + dst.m() = OpenCVUtils::toMat(line, 1);
  47 + }
  48 +
  49 + void init()
  50 + {
  51 + if (!galleryName.isEmpty())
  52 + gallery = TemplateList::fromGallery(galleryName);
  53 + }
  54 +
  55 + void train(const TemplateList &data)
  56 + {
  57 + gallery = data;
  58 + }
  59 +
  60 + void store(QDataStream &stream) const
  61 + {
  62 + br::Object::store(stream);
  63 + stream << gallery;
  64 + }
  65 +
  66 + void load(QDataStream &stream)
  67 + {
  68 + br::Object::load(stream);
  69 + stream >> gallery;
  70 + }
  71 +
  72 +public:
  73 + GalleryCompareTransform() : Transform(false, true) {}
  74 +};
  75 +
  76 +BR_REGISTER(Transform, GalleryCompareTransform)
  77 +
  78 +} // namespace br
  79 +
  80 +#include "core/gallerycompare.moc"
openbr/plugins/core/identity.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief A no-op transform.
  25 + * \see DiscardTransform FirstTransform RestTransform RemoveTransform
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class IdentityTransform : public UntrainableMetaTransform
  29 +{
  30 + Q_OBJECT
  31 +
  32 + void project(const Template &src, Template &dst) const
  33 + {
  34 + dst = src;
  35 + }
  36 +};
  37 +
  38 +BR_REGISTER(Transform, IdentityTransform)
  39 +
  40 +} // namespace br
  41 +
  42 +#include "core/identity.moc"
openbr/plugins/core/independent.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +using namespace cv;
  22 +
  23 +namespace br
  24 +{
  25 +
  26 +/*!
  27 + * \ingroup transforms
  28 + * \brief Clones the transform so that it can be applied independently.
  29 + * \author Josh Klontz \cite jklontz
  30 + * \em Independent transforms expect single-matrix templates.
  31 + */
  32 +class IndependentTransform : public MetaTransform
  33 +{
  34 + Q_OBJECT
  35 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform STORED false)
  36 + BR_PROPERTY(br::Transform*, transform, NULL)
  37 +
  38 + QList<Transform*> transforms;
  39 +
  40 + QString description(bool expanded) const
  41 + {
  42 + return transform->description(expanded);
  43 + }
  44 +
  45 + // can't use general setPropertyRecursive because of transforms oddness
  46 + bool setPropertyRecursive(const QString &name, QVariant value)
  47 + {
  48 + if (br::Object::setExistingProperty(name, value))
  49 + return true;
  50 +
  51 + if (!transform->setPropertyRecursive(name, value))
  52 + return false;
  53 +
  54 + for (int i=0;i < transforms.size();i++)
  55 + transforms[i]->setPropertyRecursive(name, value);
  56 +
  57 + return true;
  58 + }
  59 +
  60 + Transform *simplify(bool &newTransform)
  61 + {
  62 + newTransform = false;
  63 + bool newChild = false;
  64 + Transform *temp = transform->simplify(newChild);
  65 + if (temp == transform) {
  66 + return this;
  67 + }
  68 + IndependentTransform* indep = new IndependentTransform();
  69 + indep->transform = temp;
  70 +
  71 + IndependentTransform *test = dynamic_cast<IndependentTransform *> (temp);
  72 + if (test) {
  73 + // child was independent? this changes things...
  74 + indep->transform = test->transform;
  75 + for (int i=0; i < transforms.size(); i++) {
  76 + bool newThing = false;
  77 + IndependentTransform *probe = dynamic_cast<IndependentTransform *> (transforms[i]->simplify(newThing));
  78 + indep->transforms.append(probe->transform);
  79 + if (newThing)
  80 + probe->setParent(indep);
  81 + }
  82 + indep->file = indep->transform->file;
  83 + indep->trainable = indep->transform->trainable;
  84 + indep->setObjectName(indep->transform->objectName());
  85 +
  86 + return indep;
  87 + }
  88 +
  89 + if (newChild)
  90 + indep->transform->setParent(indep);
  91 +
  92 + for (int i=0; i < transforms.size();i++) {
  93 + bool subTform = false;
  94 + indep->transforms.append(transforms[i]->simplify(subTform));
  95 + if (subTform)
  96 + indep->transforms[i]->setParent(indep);
  97 + }
  98 +
  99 + indep->file = indep->transform->file;
  100 + indep->trainable = indep->transform->trainable;
  101 + indep->setObjectName(indep->transform->objectName());
  102 +
  103 + return indep;
  104 + }
  105 +
  106 + void init()
  107 + {
  108 + transforms.clear();
  109 + if (transform == NULL)
  110 + return;
  111 +
  112 + transform->setParent(this);
  113 + transforms.append(transform);
  114 + file = transform->file;
  115 + trainable = transform->trainable;
  116 + setObjectName(transform->objectName());
  117 + }
  118 +
  119 + Transform *clone() const
  120 + {
  121 + IndependentTransform *independentTransform = new IndependentTransform();
  122 + independentTransform->transform = transform->clone();
  123 + independentTransform->init();
  124 + return independentTransform;
  125 + }
  126 +
  127 + bool timeVarying() const { return transform->timeVarying(); }
  128 +
  129 + static void _train(Transform *transform, const TemplateList *data)
  130 + {
  131 + transform->train(*data);
  132 + }
  133 +
  134 + void train(const TemplateList &data)
  135 + {
  136 + // Don't bother if the transform is untrainable
  137 + if (!trainable) return;
  138 +
  139 + QList<TemplateList> templatesList;
  140 + foreach (const Template &t, data) {
  141 + if ((templatesList.size() != t.size()) && !templatesList.isEmpty())
  142 + qWarning("Independent::train (%s) template %s of size %d differs from expected size %d.", qPrintable(objectName()), qPrintable(t.file.name), t.size(), templatesList.size());
  143 + while (templatesList.size() < t.size())
  144 + templatesList.append(TemplateList());
  145 + for (int i=0; i<t.size(); i++)
  146 + templatesList[i].append(Template(t.file, t[i]));
  147 + }
  148 +
  149 + while (transforms.size() < templatesList.size())
  150 + transforms.append(transform->clone());
  151 +
  152 + QFutureSynchronizer<void> futures;
  153 + for (int i=0; i<templatesList.size(); i++)
  154 + futures.addFuture(QtConcurrent::run(_train, transforms[i], &templatesList[i]));
  155 + futures.waitForFinished();
  156 + }
  157 +
  158 + void project(const Template &src, Template &dst) const
  159 + {
  160 + dst.file = src.file;
  161 + QList<Mat> mats;
  162 + for (int i=0; i<src.size(); i++) {
  163 + transforms[i%transforms.size()]->project(Template(src.file, src[i]), dst);
  164 + mats.append(dst);
  165 + dst.clear();
  166 + }
  167 + dst.append(mats);
  168 + }
  169 +
  170 + void projectUpdate(const Template &src, Template &dst)
  171 + {
  172 + dst.file = src.file;
  173 + QList<Mat> mats;
  174 + for (int i=0; i<src.size(); i++) {
  175 + transforms[i%transforms.size()]->projectUpdate(Template(src.file, src[i]), dst);
  176 + mats.append(dst);
  177 + dst.clear();
  178 + }
  179 + dst.append(mats);
  180 + }
  181 +
  182 + void finalize(TemplateList &out)
  183 + {
  184 + if (transforms.empty())
  185 + return;
  186 +
  187 + transforms[0]->finalize(out);
  188 + for (int i=1; i < transforms.size(); i++) {
  189 + TemplateList temp;
  190 + transforms[i]->finalize(temp);
  191 +
  192 + for (int j=0; j < out.size(); j++)
  193 + out[j].append(temp[j]);
  194 + }
  195 + }
  196 +
  197 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  198 + {
  199 + dst.reserve(src.size());
  200 + foreach (const Template &t, src) {
  201 + dst.append(Template());
  202 + projectUpdate(t, dst.last());
  203 + }
  204 + }
  205 +
  206 + void store(QDataStream &stream) const
  207 + {
  208 + const int size = transforms.size();
  209 + stream << size;
  210 + for (int i=0; i<size; i++)
  211 + transforms[i]->store(stream);
  212 + }
  213 +
  214 + void load(QDataStream &stream)
  215 + {
  216 + int size;
  217 + stream >> size;
  218 + while (transforms.size() < size)
  219 + transforms.append(transform->clone());
  220 + for (int i=0; i<size; i++)
  221 + transforms[i]->load(stream);
  222 + }
  223 +};
  224 +
  225 +BR_REGISTER(Transform, IndependentTransform)
  226 +
  227 +} // namespace br
  228 +
  229 +#include "core/independent.moc"
openbr/plugins/jni.cpp renamed to openbr/plugins/core/jni.cpp
1 //Need to include location of jvm.dll (jdk version) and its parent directory in the environment variables 1 //Need to include location of jvm.dll (jdk version) and its parent directory in the environment variables
2 2
3 #include <limits> 3 #include <limits>
4 -#include "openbr_internal.h"  
5 -#include "openbr/core/resource.h" 4 +#include <openbr/plugins/openbr_internal.h>
  5 +#include <openbr/core/resource.h>
6 #include <jni.h> 6 #include <jni.h>
7 7
8 namespace br 8 namespace br
openbr/plugins/likely.cpp renamed to openbr/plugins/core/likely.cpp
1 -#include <likely.h>  
2 -#include <likely/opencv.hpp>  
3 -  
4 -#include "openbr/core/opencvutils.h"  
5 -#include "openbr_internal.h" 1 +#include <openbr/plugins/openbr_internal.h>
6 2
7 namespace br 3 namespace br
8 { 4 {
@@ -57,68 +53,6 @@ public: @@ -57,68 +53,6 @@ public:
57 53
58 BR_REGISTER(Transform, LikelyTransform) 54 BR_REGISTER(Transform, LikelyTransform)
59 55
60 -/*!  
61 - * \ingroup formats  
62 - * \brief Likely matrix format  
63 - *  
64 - * www.liblikely.org  
65 - * \author Josh Klontz \cite jklontz  
66 - */  
67 -class lmatFormat : public Format  
68 -{  
69 - Q_OBJECT  
70 -  
71 - Template read() const  
72 - {  
73 - const likely_const_mat m = likely_read(qPrintable(file.name), likely_file_guess);  
74 - const Template result(likelyToOpenCVMat(m));  
75 - likely_release_mat(m);  
76 - return result;  
77 - }  
78 -  
79 - void write(const Template &t) const  
80 - {  
81 - const likely_const_mat m = likelyFromOpenCVMat(t);  
82 - likely_write(m, qPrintable(file.name));  
83 - likely_release_mat(m);  
84 - }  
85 -};  
86 -  
87 -BR_REGISTER(Format, lmatFormat)  
88 -  
89 -/*!  
90 - * \ingroup formats  
91 - * \brief Likely matrix format  
92 - *  
93 - * www.liblikely.org  
94 - * \author Josh Klontz \cite jklontz  
95 - */  
96 -class lmatGallery : public Gallery  
97 -{  
98 - Q_OBJECT  
99 - QList<cv::Mat> mats;  
100 -  
101 - ~lmatGallery()  
102 - {  
103 - const likely_const_mat m = likelyFromOpenCVMat(OpenCVUtils::toMatByRow(mats));  
104 - likely_write(m, qPrintable(file.name));  
105 - likely_release_mat(m);  
106 - }  
107 -  
108 - TemplateList readBlock(bool *done)  
109 - {  
110 - *done = true;  
111 - qFatal("Not supported.");  
112 - }  
113 -  
114 - void write(const Template &t)  
115 - {  
116 - mats.append(t);  
117 - }  
118 -};  
119 -  
120 -BR_REGISTER(Gallery, lmatGallery)  
121 -  
122 } // namespace br 56 } // namespace br
123 57
124 -#include "likely.moc" 58 +#include "core/likely.moc"
openbr/plugins/core/loadstore.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup transforms
  25 + * \brief Caches transform training.
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class LoadStoreTransform : public MetaTransform
  29 +{
  30 + Q_OBJECT
  31 + Q_PROPERTY(QString transformString READ get_transformString WRITE set_transformString RESET reset_transformString STORED false)
  32 + Q_PROPERTY(QString fileName READ get_fileName WRITE set_fileName RESET reset_fileName STORED false)
  33 + BR_PROPERTY(QString, transformString, "Identity")
  34 + BR_PROPERTY(QString, fileName, QString())
  35 +
  36 +public:
  37 + Transform *transform;
  38 +
  39 + LoadStoreTransform() : transform(NULL) {}
  40 +
  41 + QString description(bool expanded = false) const
  42 + {
  43 + if (expanded) {
  44 + QString res = transform->description(expanded);
  45 + return res;
  46 + }
  47 + return br::Object::description(expanded);
  48 + }
  49 +
  50 + Transform *simplify(bool &newTForm)
  51 + {
  52 + Transform *res = transform->simplify(newTForm);
  53 + return res;
  54 + }
  55 +
  56 + QList<Object *> getChildren() const
  57 + {
  58 + QList<Object *> rval;
  59 + rval.append(transform);
  60 + return rval;
  61 + }
  62 +private:
  63 +
  64 + void init()
  65 + {
  66 + if (transform != NULL) return;
  67 + if (fileName.isEmpty()) fileName = QRegExp("^[_a-zA-Z0-9]+$").exactMatch(transformString) ? transformString : QtUtils::shortTextHash(transformString);
  68 +
  69 + if (!tryLoad())
  70 + transform = make(transformString);
  71 + else
  72 + trainable = false;
  73 + }
  74 +
  75 + bool timeVarying() const
  76 + {
  77 + return transform->timeVarying();
  78 + }
  79 +
  80 + void train(const QList<TemplateList> &data)
  81 + {
  82 + if (QFileInfo(getFileName()).exists())
  83 + return;
  84 +
  85 + transform->train(data);
  86 +
  87 + qDebug("Storing %s", qPrintable(fileName));
  88 + QtUtils::BlockCompression compressedOut;
  89 + QFile fout(fileName);
  90 + QtUtils::touchDir(fout);
  91 + compressedOut.setBasis(&fout);
  92 +
  93 + QDataStream stream(&compressedOut);
  94 + QString desc = transform->description();
  95 +
  96 + if (!compressedOut.open(QFile::WriteOnly))
  97 + qFatal("Failed to open %s for writing.", qPrintable(file));
  98 +
  99 + stream << desc;
  100 + transform->store(stream);
  101 + compressedOut.close();
  102 + }
  103 +
  104 + void project(const Template &src, Template &dst) const
  105 + {
  106 + transform->project(src, dst);
  107 + }
  108 +
  109 + void project(const TemplateList &src, TemplateList &dst) const
  110 + {
  111 + transform->project(src, dst);
  112 + }
  113 +
  114 + void projectUpdate(const Template &src, Template &dst)
  115 + {
  116 + transform->projectUpdate(src, dst);
  117 + }
  118 +
  119 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  120 + {
  121 + transform->projectUpdate(src, dst);
  122 + }
  123 +
  124 + void finalize(TemplateList &output)
  125 + {
  126 + transform->finalize(output);
  127 + }
  128 +
  129 + QString getFileName() const
  130 + {
  131 + if (QFileInfo(fileName).exists()) return fileName;
  132 + const QString file = Globals->sdkPath + "/share/openbr/models/transforms/" + fileName;
  133 + return QFileInfo(file).exists() ? file : QString();
  134 + }
  135 +
  136 + bool tryLoad()
  137 + {
  138 + const QString file = getFileName();
  139 + if (file.isEmpty()) return false;
  140 +
  141 + qDebug("Loading %s", qPrintable(file));
  142 + QFile fin(file);
  143 + QtUtils::BlockCompression reader(&fin);
  144 + if (!reader.open(QIODevice::ReadOnly)) {
  145 + if (QFileInfo(file).exists()) qFatal("Unable to open %s for reading. Check file permissions.", qPrintable(file));
  146 + else qFatal("Unable to open %s for reading. File does not exist.", qPrintable(file));
  147 + }
  148 +
  149 + QDataStream stream(&reader);
  150 + stream >> transformString;
  151 +
  152 + transform = Transform::make(transformString);
  153 + transform->load(stream);
  154 +
  155 + return true;
  156 + }
  157 +};
  158 +
  159 +BR_REGISTER(Transform, LoadStoreTransform)
  160 +
  161 +} // namespace br
  162 +
  163 +#include "core/loadstore.moc"
openbr/plugins/core/pipe.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup Transforms
  26 + * \brief Transforms in series.
  27 + * \author Josh Klontz \cite jklontz
  28 + *
  29 + * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
  30 + *
  31 + * \see ExpandTransform
  32 + * \see ForkTransform
  33 + */
  34 +class PipeTransform : public CompositeTransform
  35 +{
  36 + Q_OBJECT
  37 +
  38 + void _projectPartial(TemplateList *srcdst, int startIndex, int stopIndex)
  39 + {
  40 + TemplateList ftes;
  41 + for (int i=startIndex; i<stopIndex; i++) {
  42 + TemplateList res;
  43 + transforms[i]->project(*srcdst, res);
  44 +
  45 + splitFTEs(res, ftes);
  46 + *srcdst = res;
  47 + }
  48 + }
  49 +
  50 + void train(const QList<TemplateList> &data)
  51 + {
  52 + if (!trainable) return;
  53 +
  54 + QList<TemplateList> dataLines(data);
  55 +
  56 + int i = 0;
  57 + while (i < transforms.size()) {
  58 + // Conditional statement covers likely case that first transform is untrainable
  59 + if (transforms[i]->trainable) {
  60 + qDebug() << "Training " << transforms[i]->description() << "\n...";
  61 + transforms[i]->train(dataLines);
  62 + }
  63 +
  64 + // if the transform is time varying, we can't project it in parallel
  65 + if (transforms[i]->timeVarying()) {
  66 + qDebug() << "Projecting " << transforms[i]->description() << "\n...";
  67 + for (int j=0; j < dataLines.size();j++) {
  68 + TemplateList junk;
  69 + splitFTEs(dataLines[j], junk);
  70 +
  71 + transforms[i]->projectUpdate(dataLines[j], dataLines[j]);
  72 + }
  73 +
  74 + // advance i since we already projected for this stage.
  75 + i++;
  76 +
  77 + // the next stage might be trainable, so continue to evaluate it.
  78 + continue;
  79 + }
  80 +
  81 + // We project through any subsequent untrainable transforms at once
  82 + // as a memory optimization in case any of these intermediate
  83 + // transforms allocate a lot of memory (like OpenTransform)
  84 + // then we don't want all the training templates to be processed
  85 + // by that transform at once if we can avoid it.
  86 + int nextTrainableTransform = i+1;
  87 + while ((nextTrainableTransform < transforms.size()) &&
  88 + !transforms[nextTrainableTransform]->trainable &&
  89 + !transforms[nextTrainableTransform]->timeVarying())
  90 + nextTrainableTransform++;
  91 +
  92 + // No more trainable transforms? Don't need any more projects then
  93 + if (nextTrainableTransform == transforms.size())
  94 + break;
  95 +
  96 + fprintf(stderr, "Projecting %s", qPrintable(transforms[i]->description()));
  97 + for (int j=i+1; j < nextTrainableTransform; j++)
  98 + fprintf(stderr,"+%s", qPrintable(transforms[j]->description()));
  99 + fprintf(stderr, "\n...\n");
  100 + fflush(stderr);
  101 +
  102 + QFutureSynchronizer<void> futures;
  103 + for (int j=0; j < dataLines.size(); j++)
  104 + futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &dataLines[j], i, nextTrainableTransform));
  105 + futures.waitForFinished();
  106 +
  107 + i = nextTrainableTransform;
  108 + }
  109 + }
  110 +
  111 + void projectUpdate(const Template &src, Template &dst)
  112 + {
  113 + dst = src;
  114 + foreach (Transform *f, transforms) {
  115 + try {
  116 + f->projectUpdate(dst);
  117 + if (dst.file.fte)
  118 + break;
  119 + } catch (...) {
  120 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  121 + dst = Template(src.file);
  122 + dst.file.fte = true;
  123 + break;
  124 + }
  125 + }
  126 + }
  127 +
  128 + // For time varying transforms, parallel execution over individual templates
  129 + // won't work.
  130 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  131 + {
  132 + TemplateList ftes;
  133 + dst = src;
  134 + foreach (Transform *f, transforms) {
  135 + TemplateList res;
  136 + f->projectUpdate(dst, res);
  137 + splitFTEs(res, ftes);
  138 + dst = res;
  139 + }
  140 + dst.append(ftes);
  141 + }
  142 +
  143 + virtual void finalize(TemplateList &output)
  144 + {
  145 + output.clear();
  146 + // For each transform,
  147 + for (int i = 0; i < transforms.size(); i++)
  148 + {
  149 +
  150 + // Collect any final templates
  151 + TemplateList last_set;
  152 + transforms[i]->finalize(last_set);
  153 + if (last_set.empty())
  154 + continue;
  155 + // Push any templates received through the remaining transforms in the sequence
  156 + for (int j = (i+1); j < transforms.size();j++)
  157 + {
  158 + transforms[j]->projectUpdate(last_set);
  159 + }
  160 + // append the result to the output set
  161 + output.append(last_set);
  162 + }
  163 + }
  164 +
  165 + void init()
  166 + {
  167 + QList<Transform *> flattened;
  168 + for (int i=0;i < transforms.size(); i++)
  169 + {
  170 + PipeTransform *probe = dynamic_cast<PipeTransform *> (transforms[i]);
  171 + if (!probe) {
  172 + flattened.append(transforms[i]);
  173 + continue;
  174 + }
  175 + for (int j=0; j < probe->transforms.size(); j++)
  176 + flattened.append(probe->transforms[j]);
  177 + }
  178 + transforms = flattened;
  179 +
  180 + CompositeTransform::init();
  181 + }
  182 +
  183 +protected:
  184 + // Template list project -- process templates in parallel through Transform::project
  185 + // or if parallelism is disabled, handle them sequentially
  186 + void _project(const TemplateList &src, TemplateList &dst) const
  187 + {
  188 + TemplateList ftes;
  189 + dst = src;
  190 + foreach (const Transform *f, transforms) {
  191 + TemplateList res;
  192 + f->project(dst, res);
  193 + splitFTEs(res, ftes);
  194 + dst = res;
  195 + }
  196 + dst.append(ftes);
  197 + }
  198 +
  199 + // Single template const project, pass the template through each sub-transform, one after the other
  200 + virtual void _project(const Template &src, Template &dst) const
  201 + {
  202 + dst = src;
  203 + foreach (const Transform *f, transforms) {
  204 + try {
  205 + dst >> *f;
  206 + if (dst.file.fte)
  207 + break;
  208 + } catch (...) {
  209 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  210 + dst = Template(src.file);
  211 + dst.file.fte = true;
  212 + }
  213 + }
  214 + }
  215 +};
  216 +
  217 +BR_REGISTER(Transform, PipeTransform)
  218 +
  219 +} // namespace br
  220 +
  221 +#include "core/pipe.moc"
openbr/plugins/process.cpp renamed to openbr/plugins/core/processwrapper.cpp
1 - 1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 16
3 #include <QBuffer> 17 #include <QBuffer>
4 #include <QCoreApplication> 18 #include <QCoreApplication>
@@ -9,8 +23,8 @@ @@ -9,8 +23,8 @@
9 #include <QUuid> 23 #include <QUuid>
10 #include <QWaitCondition> 24 #include <QWaitCondition>
11 25
12 -#include "openbr_internal.h"  
13 -#include "openbr/core/opencvutils.h" 26 +#include <openbr/plugins/openbr_internal.h>
  27 +#include <openbr/core/opencvutils.h>
14 28
15 using namespace cv; 29 using namespace cv;
16 30
@@ -658,4 +672,4 @@ BR_REGISTER(Transform, ProcessWrapperTransform) @@ -658,4 +672,4 @@ BR_REGISTER(Transform, ProcessWrapperTransform)
658 672
659 } 673 }
660 674
661 -#include "process.moc" 675 +#include "core/processwrapper.moc"
openbr/plugins/core/progresscounter.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QElapsedTimer>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/qtutils.h>
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +class ProgressCounterTransform : public TimeVaryingTransform
  26 +{
  27 + Q_OBJECT
  28 +
  29 + Q_PROPERTY(qint64 totalProgress READ get_totalProgress WRITE set_totalProgress RESET reset_totalProgress STORED false)
  30 + BR_PROPERTY(qint64, totalProgress, 1)
  31 +
  32 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  33 + {
  34 + dst = src;
  35 +
  36 + qint64 elapsed = timer.elapsed();
  37 + int last_frame = -2;
  38 + if (!dst.empty()) {
  39 + for (int i=0;i < dst.size();i++) {
  40 + int frame = dst[i].file.get<int>("FrameNumber", -1);
  41 + if (frame == last_frame && frame != -1)
  42 + continue;
  43 +
  44 + // Use 1 as the starting index for progress output
  45 + Globals->currentProgress = dst[i].file.get<qint64>("progress",0)+1;
  46 + dst[i].file.remove("progress");
  47 + last_frame = frame;
  48 +
  49 + Globals->currentStep++;
  50 + }
  51 + }
  52 +
  53 + // updated every second
  54 + if (elapsed > 1000) {
  55 + Globals->printStatus();
  56 + timer.start();
  57 + }
  58 +
  59 + return;
  60 + }
  61 +
  62 + void train(const TemplateList& data)
  63 + {
  64 + (void) data;
  65 + }
  66 +
  67 + void finalize(TemplateList &data)
  68 + {
  69 + (void) data;
  70 + float p = br_progress();
  71 + qDebug("\r%05.2f%% ELAPSED=%s REMAINING=%s COUNT=%g", p*100, QtUtils::toTime(Globals->startTime.elapsed()/1000.0f).toStdString().c_str(), QtUtils::toTime(0).toStdString().c_str(), Globals->currentStep);
  72 + timer.start();
  73 + Globals->startTime.start();
  74 + Globals->currentStep = 0;
  75 + Globals->currentProgress = 0;
  76 + Globals->totalSteps = totalProgress;
  77 + }
  78 +
  79 + void init()
  80 + {
  81 + timer.start();
  82 + Globals->startTime.start();
  83 + Globals->currentProgress = 0;
  84 + Globals->currentStep = 0;
  85 + Globals->totalSteps = totalProgress;
  86 + }
  87 +
  88 +public:
  89 + ProgressCounterTransform() : TimeVaryingTransform(false,false) {}
  90 + QElapsedTimer timer;
  91 +};
  92 +
  93 +BR_REGISTER(Transform, ProgressCounterTransform)
  94 +
  95 +} // namespace br
  96 +
  97 +#include "core/progresscounter.moc"
openbr/plugins/core/registrar.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup initializers
  24 + * \brief Register custom objects with Qt meta object system.
  25 + * \author Charles Otto \cite caotto
  26 + */
  27 +class Registrar : public Initializer
  28 +{
  29 + Q_OBJECT
  30 +
  31 + void initialize() const
  32 + {
  33 + qRegisterMetaType<br::Neighbors>();
  34 + }
  35 +};
  36 +
  37 +BR_REGISTER(Initializer, Registrar)
  38 +
  39 +} // namespace br
  40 +
  41 +#include "core/registrar.moc"
openbr/plugins/core/remove.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Removes the matrix from the template at the specified index.
  25 + * \author Josh Klontz \cite jklontz
  26 + * \see IdentityTransform DiscardTransform FirstTransform RestTransform
  27 + */
  28 +//! [example_transform]
  29 +class RemoveTransform : public UntrainableMetaTransform
  30 +{
  31 + Q_OBJECT
  32 + Q_PROPERTY(int index READ get_index WRITE set_index RESET reset_index STORED false)
  33 + BR_PROPERTY(int, index, 0)
  34 +
  35 + void project(const Template &src, Template &dst) const
  36 + {
  37 + dst = src;
  38 + dst.removeAt(index);
  39 + }
  40 +};
  41 +
  42 +BR_REGISTER(Transform, RemoveTransform)
  43 +//! [example_transform]
  44 +
  45 +} // namespace br
  46 +
  47 +#include "core/remove.moc"
openbr/plugins/core/rest.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Removes the first matrix from the template.
  25 + * \see IdentityTransform DiscardTransform FirstTransform RemoveTransform
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class RestTransform : public UntrainableMetaTransform
  29 +{
  30 + Q_OBJECT
  31 +
  32 + void project(const Template &src, Template &dst) const
  33 + {
  34 + dst = src;
  35 + dst.removeFirst();
  36 + }
  37 +};
  38 +
  39 +BR_REGISTER(Transform, RestTransform)
  40 +
  41 +} // namespace br
  42 +
  43 +#include "core/rest.moc"
openbr/plugins/core/schrodinger.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief Generates two templates, one of which is passed through a transform and the other
  25 + * is not. No cats were harmed in the making of this transform.
  26 + * \author Scott Klum \cite sklum
  27 + */
  28 +class SchrodingerTransform : public MetaTransform
  29 +{
  30 + Q_OBJECT
  31 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  32 + BR_PROPERTY(br::Transform*, transform, NULL)
  33 +
  34 +public:
  35 + void train(const TemplateList &data)
  36 + {
  37 + transform->train(data);
  38 + }
  39 +
  40 + void project(const TemplateList &src, TemplateList &dst) const
  41 + {
  42 + foreach(const Template &t, src) {
  43 + dst.append(t);
  44 + Template u;
  45 + transform->project(t,u);
  46 + dst.append(u);
  47 + }
  48 + }
  49 +
  50 + void project(const Template &src, Template &dst) const {
  51 + TemplateList temp;
  52 + project(TemplateList() << src, temp);
  53 + if (!temp.isEmpty()) dst = temp.first();
  54 + }
  55 +
  56 +};
  57 +BR_REGISTER(Transform, SchrodingerTransform)
  58 +
  59 +} // namespace br
  60 +
  61 +#include "core/schrodinger.moc"
openbr/plugins/core/singleton.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup transforms
  24 + * \brief A globally shared transform.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class SingletonTransform : public MetaTransform
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false)
  31 + BR_PROPERTY(QString, description, "Identity")
  32 +
  33 + static QMutex mutex;
  34 + static QHash<QString,Transform*> transforms;
  35 + static QHash<QString,int> trainingReferenceCounts;
  36 + static QHash<QString,TemplateList> trainingData;
  37 +
  38 + Transform *transform;
  39 +
  40 + void init()
  41 + {
  42 + QMutexLocker locker(&mutex);
  43 + if (!transforms.contains(description)) {
  44 + transforms.insert(description, make(description));
  45 + trainingReferenceCounts.insert(description, 0);
  46 + }
  47 +
  48 + transform = transforms[description];
  49 + trainingReferenceCounts[description]++;
  50 + }
  51 +
  52 + void train(const TemplateList &data)
  53 + {
  54 + QMutexLocker locker(&mutex);
  55 + trainingData[description].append(data);
  56 + trainingReferenceCounts[description]--;
  57 + if (trainingReferenceCounts[description] > 0) return;
  58 + transform->train(trainingData[description]);
  59 + trainingData[description].clear();
  60 + }
  61 +
  62 + void project(const Template &src, Template &dst) const
  63 + {
  64 + transform->project(src, dst);
  65 + }
  66 +
  67 + void store(QDataStream &stream) const
  68 + {
  69 + if (transform->parent() == this)
  70 + transform->store(stream);
  71 + }
  72 +
  73 + void load(QDataStream &stream)
  74 + {
  75 + if (transform->parent() == this)
  76 + transform->load(stream);
  77 + }
  78 +};
  79 +
  80 +QMutex SingletonTransform::mutex;
  81 +QHash<QString,Transform*> SingletonTransform::transforms;
  82 +QHash<QString,int> SingletonTransform::trainingReferenceCounts;
  83 +QHash<QString,TemplateList> SingletonTransform::trainingData;
  84 +
  85 +BR_REGISTER(Transform, SingletonTransform)
  86 +
  87 +} // namespace br
  88 +
  89 +#include "core/singleton.moc"
openbr/plugins/stream.cpp renamed to openbr/plugins/core/stream.cpp
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
1 #include <fstream> 17 #include <fstream>
2 #include <QReadWriteLock> 18 #include <QReadWriteLock>
3 #include <QWaitCondition> 19 #include <QWaitCondition>
@@ -8,10 +24,11 @@ @@ -8,10 +24,11 @@
8 #include <QtConcurrent> 24 #include <QtConcurrent>
9 #include <opencv/highgui.h> 25 #include <opencv/highgui.h>
10 #include <opencv2/highgui/highgui.hpp> 26 #include <opencv2/highgui/highgui.hpp>
11 -#include "openbr_internal.h"  
12 -#include "openbr/core/common.h"  
13 -#include "openbr/core/opencvutils.h"  
14 -#include "openbr/core/qtutils.h" 27 +
  28 +#include <openbr/plugins/openbr_internal.h>
  29 +#include <openbr/core/common.h>
  30 +#include <openbr/core/opencvutils.h>
  31 +#include <openbr/core/qtutils.h>
15 32
16 using namespace cv; 33 using namespace cv;
17 using namespace std; 34 using namespace std;
@@ -1360,5 +1377,5 @@ BR_REGISTER(Transform, StreamTransform) @@ -1360,5 +1377,5 @@ BR_REGISTER(Transform, StreamTransform)
1360 1377
1361 } // namespace br 1378 } // namespace br
1362 1379
1363 -#include "stream.moc" 1380 +#include "core/stream.moc"
1364 1381
openbr/plugins/crop.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <opencv2/imgproc/imgproc.hpp>  
18 -#include "openbr_internal.h"  
19 -  
20 -#include "openbr/core/opencvutils.h"  
21 -  
22 -using namespace cv;  
23 -  
24 -namespace br  
25 -{  
26 -  
27 -/*!  
28 - * \ingroup transforms  
29 - * \brief Crops about the specified region of interest.  
30 - * \author Josh Klontz \cite jklontz  
31 - */  
32 -class CropTransform : public UntrainableTransform  
33 -{  
34 - Q_OBJECT  
35 - Q_PROPERTY(int x READ get_x WRITE set_x RESET reset_x STORED false)  
36 - Q_PROPERTY(int y READ get_y WRITE set_y RESET reset_y STORED false)  
37 - Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false)  
38 - Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false)  
39 - BR_PROPERTY(int, x, 0)  
40 - BR_PROPERTY(int, y, 0)  
41 - BR_PROPERTY(int, width, -1)  
42 - BR_PROPERTY(int, height, -1)  
43 -  
44 - void project(const Template &src, Template &dst) const  
45 - {  
46 - dst = Mat(src, Rect(x, y, width < 1 ? src.m().cols-x-abs(width) : width, height < 1 ? src.m().rows-y-abs(height) : height));  
47 - }  
48 -};  
49 -  
50 -BR_REGISTER(Transform, CropTransform)  
51 -  
52 -/*!  
53 - * \ingroup transforms  
54 - * \brief Crops the rectangular regions of interest.  
55 - * \author Josh Klontz \cite jklontz  
56 - */  
57 -class ROITransform : public UntrainableTransform  
58 -{  
59 - Q_OBJECT  
60 - Q_PROPERTY(QString propName READ get_propName WRITE set_propName RESET reset_propName STORED false)  
61 - BR_PROPERTY(QString, propName, "")  
62 -  
63 - void project(const Template &src, Template &dst) const  
64 - {  
65 - if (!propName.isEmpty()) {  
66 - QRectF rect = src.file.get<QRectF>(propName);  
67 - dst += src.m()(OpenCVUtils::toRect(rect));  
68 - } else if (!src.file.rects().empty()) {  
69 - foreach (const QRectF &rect, src.file.rects())  
70 - dst += src.m()(OpenCVUtils::toRect(rect));  
71 - } else if (src.file.contains(QStringList() << "X" << "Y" << "Width" << "Height")) {  
72 - dst += src.m()(Rect(src.file.get<int>("X"),  
73 - src.file.get<int>("Y"),  
74 - src.file.get<int>("Width"),  
75 - src.file.get<int>("Height")));  
76 - } else {  
77 - dst = src;  
78 - if (Globals->verbose)  
79 - qWarning("No rects present in file.");  
80 - }  
81 - }  
82 -};  
83 -  
84 -BR_REGISTER(Transform, ROITransform)  
85 -  
86 -/*!  
87 - * \ingroup transforms  
88 - * \brief Crops the rectangular regions of interest from given points and sizes.  
89 - * \author Austin Blanton \cite imaus10  
90 - */  
91 -class ROIFromPtsTransform : public UntrainableTransform  
92 -{  
93 - Q_OBJECT  
94 - Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false)  
95 - Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false)  
96 - BR_PROPERTY(int, width, 1)  
97 - BR_PROPERTY(int, height, 1)  
98 -  
99 - void project(const Template &src, Template &dst) const  
100 - {  
101 - foreach (const QPointF &pt, src.file.points()) {  
102 - int x = pt.x() - (width/2);  
103 - int y = pt.y() - (height/2);  
104 - dst += src.m()(Rect(x, y, width, height));  
105 - }  
106 - }  
107 -};  
108 -  
109 -BR_REGISTER(Transform, ROIFromPtsTransform)  
110 -  
111 -/*!  
112 - * \ingroup transforms  
113 - * \brief Resize the template  
114 - * \author Josh Klontz \cite jklontz  
115 - * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement.  
116 - * \param preserveAspect If true, the image will be sized per specification, but  
117 - * a border will be applied to preserve aspect ratio.  
118 - */  
119 -class ResizeTransform : public UntrainableTransform  
120 -{  
121 - Q_OBJECT  
122 - Q_ENUMS(Method)  
123 -  
124 -public:  
125 - /*!< */  
126 - enum Method { Near = INTER_NEAREST,  
127 - Area = INTER_AREA,  
128 - Bilin = INTER_LINEAR,  
129 - Cubic = INTER_CUBIC,  
130 - Lanczo = INTER_LANCZOS4};  
131 -  
132 -private:  
133 - Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false)  
134 - Q_PROPERTY(int columns READ get_columns WRITE set_columns RESET reset_columns STORED false)  
135 - Q_PROPERTY(Method method READ get_method WRITE set_method RESET reset_method STORED false)  
136 - Q_PROPERTY(bool preserveAspect READ get_preserveAspect WRITE set_preserveAspect RESET reset_preserveAspect STORED false)  
137 - BR_PROPERTY(int, rows, -1)  
138 - BR_PROPERTY(int, columns, -1)  
139 - BR_PROPERTY(Method, method, Bilin)  
140 - BR_PROPERTY(bool, preserveAspect, false)  
141 -  
142 - void project(const Template &src, Template &dst) const  
143 - {  
144 - if (!preserveAspect)  
145 - resize(src, dst, Size((columns == -1) ? src.m().cols*rows/src.m().rows : columns, rows), 0, 0, method);  
146 - else {  
147 - float inRatio = (float) src.m().rows / src.m().cols;  
148 - float outRatio = (float) rows / columns;  
149 - dst = Mat::zeros(rows, columns, src.m().type());  
150 - if (outRatio > inRatio) {  
151 - float heightAR = src.m().rows * inRatio / outRatio;  
152 - Mat buffer;  
153 - resize(src, buffer, Size(columns, heightAR), 0, 0, method);  
154 - buffer.copyTo(dst.m()(Rect(0, (rows - heightAR) / 2, columns, heightAR)));  
155 - } else {  
156 - float widthAR = src.m().cols / inRatio * outRatio;  
157 - Mat buffer;  
158 - resize(src, buffer, Size(widthAR, rows), 0, 0, method);  
159 - buffer.copyTo(dst.m()(Rect((columns - widthAR) / 2, 0, widthAR, rows)));  
160 - }  
161 - }  
162 - }  
163 -};  
164 -  
165 -BR_REGISTER(Transform, ResizeTransform)  
166 -  
167 -/*!  
168 - * \ingroup transforms  
169 - * \brief Limit the size of the template  
170 - * \author Josh Klontz \cite jklontz  
171 - */  
172 -class LimitSizeTransform : public UntrainableTransform  
173 -{  
174 - Q_OBJECT  
175 - Q_PROPERTY(int max READ get_max WRITE set_max RESET reset_max STORED false)  
176 - BR_PROPERTY(int, max, -1)  
177 -  
178 - void project(const Template &src, Template &dst) const  
179 - {  
180 - const Mat &m = src;  
181 - if (m.rows > m.cols)  
182 - if (m.rows > max) resize(m, dst, Size(std::max(1, m.cols * max / m.rows), max));  
183 - else dst = m;  
184 - else  
185 - if (m.cols > max) resize(m, dst, Size(max, std::max(1, m.rows * max / m.cols)));  
186 - else dst = m;  
187 - }  
188 -};  
189 -  
190 -BR_REGISTER(Transform, LimitSizeTransform)  
191 -  
192 -/*!  
193 - * \ingroup transforms  
194 - * \brief Enforce a multiple of \em n columns.  
195 - * \author Josh Klontz \cite jklontz  
196 - */  
197 -class DivTransform : public UntrainableTransform  
198 -{  
199 - Q_OBJECT  
200 - Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false)  
201 - BR_PROPERTY(int, n, 1)  
202 -  
203 - void project(const Template &src, Template &dst) const  
204 - {  
205 - dst = Mat(src, Rect(0,0,n*(src.m().cols/n),src.m().rows));  
206 - }  
207 -};  
208 -  
209 -BR_REGISTER(Transform, DivTransform)  
210 -  
211 -/*!  
212 - * \ingroup transforms  
213 - * \brief Crop out black borders  
214 - * \author Josh Klontz \cite jklontz  
215 - */  
216 -class CropBlackTransform : public UntrainableTransform  
217 -{  
218 - Q_OBJECT  
219 -  
220 - void project(const Template &src, Template &dst) const  
221 - {  
222 - Mat gray;  
223 - OpenCVUtils::cvtGray(src, gray);  
224 -  
225 - int xStart = 0;  
226 - while (xStart < gray.cols) {  
227 - if (mean(gray.col(xStart))[0] >= 1) break;  
228 - xStart++;  
229 - }  
230 -  
231 - int xEnd = gray.cols - 1;  
232 - while (xEnd >= 0) {  
233 - if (mean(gray.col(xEnd))[0] >= 1) break;  
234 - xEnd--;  
235 - }  
236 -  
237 - int yStart = 0;  
238 - while (yStart < gray.rows) {  
239 - if (mean(gray.col(yStart))[0] >= 1) break;  
240 - yStart++;  
241 - }  
242 -  
243 - int yEnd = gray.rows - 1;  
244 - while (yEnd >= 0) {  
245 - if (mean(gray.col(yEnd))[0] >= 1) break;  
246 - yEnd--;  
247 - }  
248 -  
249 - dst = src.m()(Rect(xStart, yStart, xEnd-xStart, yEnd-yStart));  
250 - }  
251 -};  
252 -  
253 -BR_REGISTER(Transform, CropBlackTransform)  
254 -  
255 -/*!  
256 - * \ingroup transforms  
257 - * \brief Divide the matrix into 4 smaller matricies of equal size.  
258 - * \author Josh Klontz \cite jklontz  
259 - */  
260 -class SubdivideTransform : public UntrainableTransform  
261 -{  
262 - Q_OBJECT  
263 -  
264 - void project(const Template &src, Template &dst) const  
265 - {  
266 - const Mat &m = src;  
267 - const int subrows = m.rows/2;  
268 - const int subcolumns = m.cols/2;  
269 - dst.append(Mat(m,Rect(0, 0, subcolumns, subrows)).clone());  
270 - dst.append(Mat(m,Rect(subcolumns, 0, subcolumns, subrows)).clone());  
271 - dst.append(Mat(m,Rect(0, subrows, subcolumns, subrows)).clone());  
272 - dst.append(Mat(m,Rect(subcolumns, subrows, subcolumns, subrows)).clone());  
273 - }  
274 -};  
275 -  
276 -BR_REGISTER(Transform, SubdivideTransform)  
277 -  
278 -/*!  
279 - * \ingroup transforms  
280 - * \brief Trim the image so the width and the height are the same size.  
281 - * \author Josh Klontz \cite jklontz  
282 - */  
283 -class CropSquareTransform : public UntrainableTransform  
284 -{  
285 - Q_OBJECT  
286 -  
287 - void project(const Template &src, Template &dst) const  
288 - {  
289 - const Mat &m = src;  
290 - const int newSize = min(m.rows, m.cols);  
291 - dst = Mat(m, Rect((m.cols-newSize)/2, (m.rows-newSize)/2, newSize, newSize));  
292 - }  
293 -};  
294 -  
295 -BR_REGISTER(Transform, CropSquareTransform)  
296 -  
297 -} // namespace br  
298 -  
299 -#include "crop.moc"  
openbr/plugins/cvt.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <opencv2/imgproc/imgproc_c.h>  
18 -#include <opencv2/imgproc/imgproc.hpp>  
19 -#include "openbr_internal.h"  
20 -#include "openbr/core/opencvutils.h"  
21 -  
22 -using namespace cv;  
23 -  
24 -namespace br  
25 -{  
26 -  
27 -/*!  
28 - * \ingroup transforms  
29 - * \brief Colorspace conversion.  
30 - * \author Josh Klontz \cite jklontz  
31 - */  
32 -class CvtTransform : public UntrainableTransform  
33 -{  
34 - Q_OBJECT  
35 - Q_ENUMS(ColorSpace)  
36 - Q_PROPERTY(ColorSpace colorSpace READ get_colorSpace WRITE set_colorSpace RESET reset_colorSpace STORED false)  
37 - Q_PROPERTY(int channel READ get_channel WRITE set_channel RESET reset_channel STORED false)  
38 -  
39 -public:  
40 - enum ColorSpace { Gray = CV_BGR2GRAY,  
41 - RGBGray = CV_RGB2GRAY,  
42 - HLS = CV_BGR2HLS,  
43 - HSV = CV_BGR2HSV,  
44 - Lab = CV_BGR2Lab,  
45 - Luv = CV_BGR2Luv,  
46 - RGB = CV_BGR2RGB,  
47 - XYZ = CV_BGR2XYZ,  
48 - YCrCb = CV_BGR2YCrCb,  
49 - Color = CV_GRAY2BGR };  
50 -  
51 -private:  
52 - BR_PROPERTY(ColorSpace, colorSpace, Gray)  
53 - BR_PROPERTY(int, channel, -1)  
54 -  
55 - void project(const Template &src, Template &dst) const  
56 - {  
57 - if (src.m().channels() > 1 || colorSpace == CV_GRAY2BGR) cvtColor(src, dst, colorSpace);  
58 - else dst = src;  
59 -  
60 - if (channel != -1) {  
61 - std::vector<Mat> mv;  
62 - split(dst, mv);  
63 - dst = mv[channel % (int)mv.size()];  
64 - }  
65 - }  
66 -};  
67 -  
68 -BR_REGISTER(Transform, CvtTransform)  
69 -  
70 -/*!  
71 - * \ingroup transforms  
72 - * \brief Convert to floating point format.  
73 - * \author Josh Klontz \cite jklontz  
74 - */  
75 -class CvtFloatTransform : public UntrainableTransform  
76 -{  
77 - Q_OBJECT  
78 -  
79 - void project(const Template &src, Template &dst) const  
80 - {  
81 - src.m().convertTo(dst, CV_32F);  
82 - }  
83 -};  
84 -  
85 -BR_REGISTER(Transform, CvtFloatTransform)  
86 -  
87 -/*!  
88 - * \ingroup transforms  
89 - * \brief Convert to uchar format  
90 - * \author Josh Klontz \cite jklontz  
91 - */  
92 -class CvtUCharTransform : public UntrainableTransform  
93 -{  
94 - Q_OBJECT  
95 -  
96 - void project(const Template &src, Template &dst) const  
97 - {  
98 - OpenCVUtils::cvtUChar(src, dst);  
99 - }  
100 -};  
101 -  
102 -BR_REGISTER(Transform, CvtUCharTransform)  
103 -  
104 -/*!  
105 - * \ingroup transforms  
106 - * \brief Scales using the given factor  
107 - * \author Scott Klum \cite sklum  
108 - */  
109 -class ScaleTransform : public UntrainableTransform  
110 -{  
111 - Q_OBJECT  
112 -  
113 - Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false)  
114 - BR_PROPERTY(float, scaleFactor, 1.)  
115 -  
116 - void project(const Template &src, Template &dst) const  
117 - {  
118 - resize(src, dst, Size(src.m().cols*scaleFactor,src.m().rows*scaleFactor));  
119 - }  
120 -};  
121 -  
122 -BR_REGISTER(Transform, ScaleTransform)  
123 -  
124 -/*!  
125 - * \ingroup transforms  
126 - * \brief Split a multi-channel matrix into several single-channel matrices.  
127 - * \author Josh Klontz \cite jklontz  
128 - */  
129 -class SplitChannelsTransform : public UntrainableTransform  
130 -{  
131 - Q_OBJECT  
132 -  
133 - void project(const Template &src, Template &dst) const  
134 - {  
135 - std::vector<Mat> mv;  
136 - split(src, mv);  
137 - foreach (const Mat &m, mv)  
138 - dst += m;  
139 - }  
140 -};  
141 -  
142 -BR_REGISTER(Transform, SplitChannelsTransform)  
143 -  
144 -/*!  
145 - * \ingroup transforms  
146 - * \brief Enforce the matrix has a certain number of channels by adding or removing channels.  
147 - * \author Josh Klontz \cite jklontz  
148 - */  
149 -class EnsureChannelsTransform : public UntrainableTransform  
150 -{  
151 - Q_OBJECT  
152 - Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false)  
153 - BR_PROPERTY(int, n, 1)  
154 -  
155 - void project(const Template &src, Template &dst) const  
156 - {  
157 - if (src.m().channels() == n) {  
158 - dst = src;  
159 - } else {  
160 - std::vector<Mat> mv;  
161 - split(src, mv);  
162 -  
163 - // Add extra channels  
164 - while ((int)mv.size() < n) {  
165 - for (int i=0; i<src.m().channels(); i++) {  
166 - mv.push_back(mv[i]);  
167 - if ((int)mv.size() == n)  
168 - break;  
169 - }  
170 - }  
171 -  
172 - // Remove extra channels  
173 - while ((int)mv.size() > n)  
174 - mv.pop_back();  
175 -  
176 - merge(mv, dst);  
177 - }  
178 - }  
179 -};  
180 -  
181 -BR_REGISTER(Transform, EnsureChannelsTransform)  
182 -  
183 -/*!  
184 - * \ingroup transforms  
185 - * \brief Drop the alpha channel (if exists).  
186 - * \author Austin Blanton \cite imaus10  
187 - */  
188 -class DiscardAlphaTransform : public UntrainableTransform  
189 -{  
190 - Q_OBJECT  
191 -  
192 - void project(const Template &src, Template &dst) const  
193 - {  
194 - if (src.m().channels() > 4 || src.m().channels() == 2) {  
195 - dst.file.fte = true;  
196 - return;  
197 - }  
198 -  
199 - dst = src;  
200 - if (src.m().channels() == 4) {  
201 - std::vector<Mat> mv;  
202 - split(src, mv);  
203 - mv.pop_back();  
204 - merge(mv, dst);  
205 - }  
206 - }  
207 -};  
208 -  
209 -BR_REGISTER(Transform, DiscardAlphaTransform)  
210 -  
211 -/*!  
212 - * \ingroup transforms  
213 - * \brief Normalized RG color space.  
214 - * \author Josh Klontz \cite jklontz  
215 - */  
216 -class RGTransform : public UntrainableTransform  
217 -{  
218 - Q_OBJECT  
219 -  
220 - void project(const Template &src, Template &dst) const  
221 - {  
222 - if (src.m().type() != CV_8UC3)  
223 - qFatal("Expected CV_8UC3 images.");  
224 -  
225 - const Mat &m = src.m();  
226 - Mat R(m.size(), CV_8UC1); // R / (R+G+B)  
227 - Mat G(m.size(), CV_8UC1); // G / (R+G+B)  
228 -  
229 - for (int i=0; i<m.rows; i++)  
230 - for (int j=0; j<m.cols; j++) {  
231 - Vec3b v = m.at<Vec3b>(i,j);  
232 - const int b = v[0];  
233 - const int g = v[1];  
234 - const int r = v[2];  
235 - const int sum = b + g + r;  
236 - if (sum > 0) {  
237 - R.at<uchar>(i, j) = saturate_cast<uchar>(255.0*r/(r+g+b));  
238 - G.at<uchar>(i, j) = saturate_cast<uchar>(255.0*g/(r+g+b));  
239 - } else {  
240 - R.at<uchar>(i, j) = 0;  
241 - G.at<uchar>(i, j) = 0;  
242 - }  
243 - }  
244 -  
245 - dst.append(R);  
246 - dst.append(G);  
247 - }  
248 -};  
249 -  
250 -BR_REGISTER(Transform, RGTransform)  
251 -  
252 -/*!  
253 - * \ingroup transforms  
254 - * \brief dst = a*src+b  
255 - * \author Josh Klontz \cite jklontz  
256 - */  
257 -class MAddTransform : public UntrainableTransform  
258 -{  
259 - Q_OBJECT  
260 - Q_PROPERTY(double a READ get_a WRITE set_a RESET reset_a STORED false)  
261 - Q_PROPERTY(double b READ get_b WRITE set_b RESET reset_b STORED false)  
262 - BR_PROPERTY(double, a, 1)  
263 - BR_PROPERTY(double, b, 0)  
264 -  
265 - void project(const Template &src, Template &dst) const  
266 - {  
267 - src.m().convertTo(dst.m(), src.m().depth(), a, b);  
268 - }  
269 -};  
270 -  
271 -BR_REGISTER(Transform, MAddTransform)  
272 -  
273 -/*!  
274 - * \ingroup transforms  
275 - * \brief Computes the absolute value of each element.  
276 - * \author Josh Klontz \cite jklontz  
277 - */  
278 -class AbsTransform : public UntrainableTransform  
279 -{  
280 - Q_OBJECT  
281 -  
282 - void project(const Template &src, Template &dst) const  
283 - {  
284 - dst = abs(src);  
285 - }  
286 -};  
287 -  
288 -BR_REGISTER(Transform, AbsTransform)  
289 -  
290 -} // namespace br  
291 -  
292 -#include "cvt.moc"  
openbr/plugins/distance.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <QFutureSynchronizer>  
18 -#include <QtConcurrentRun>  
19 -#include <numeric>  
20 -#include <opencv2/imgproc/imgproc.hpp>  
21 -#include <opencv2/imgproc/imgproc_c.h>  
22 -#include "openbr_internal.h"  
23 -  
24 -#include "openbr/core/distance_sse.h"  
25 -#include "openbr/core/qtutils.h"  
26 -#include "openbr/core/opencvutils.h"  
27 -  
28 -using namespace cv;  
29 -  
30 -namespace br  
31 -{  
32 -  
33 -/*!  
34 - * \ingroup distances  
35 - * \brief Standard distance metrics  
36 - * \author Josh Klontz \cite jklontz  
37 - */  
38 -class DistDistance : public UntrainableDistance  
39 -{  
40 - Q_OBJECT  
41 - Q_ENUMS(Metric)  
42 - Q_PROPERTY(Metric metric READ get_metric WRITE set_metric RESET reset_metric STORED false)  
43 - Q_PROPERTY(bool negLogPlusOne READ get_negLogPlusOne WRITE set_negLogPlusOne RESET reset_negLogPlusOne STORED false)  
44 -  
45 -public:  
46 - /*!< */  
47 - enum Metric { Correlation,  
48 - ChiSquared,  
49 - Intersection,  
50 - Bhattacharyya,  
51 - INF,  
52 - L1,  
53 - L2,  
54 - Cosine,  
55 - Dot};  
56 -  
57 -private:  
58 - BR_PROPERTY(Metric, metric, L2)  
59 - BR_PROPERTY(bool, negLogPlusOne, true)  
60 -  
61 - float compare(const Mat &a, const Mat &b) const  
62 - {  
63 - if ((a.size != b.size) ||  
64 - (a.type() != b.type()))  
65 - return -std::numeric_limits<float>::max();  
66 -  
67 -// TODO: this max value is never returned based on the switch / default  
68 - float result = std::numeric_limits<float>::max();  
69 - switch (metric) {  
70 - case Correlation:  
71 - return compareHist(a, b, CV_COMP_CORREL);  
72 - case ChiSquared:  
73 - result = compareHist(a, b, CV_COMP_CHISQR);  
74 - break;  
75 - case Intersection:  
76 - result = compareHist(a, b, CV_COMP_INTERSECT);  
77 - break;  
78 - case Bhattacharyya:  
79 - result = compareHist(a, b, CV_COMP_BHATTACHARYYA);  
80 - break;  
81 - case INF:  
82 - result = norm(a, b, NORM_INF);  
83 - break;  
84 - case L1:  
85 - result = norm(a, b, NORM_L1);  
86 - break;  
87 - case L2:  
88 - result = norm(a, b, NORM_L2);  
89 - break;  
90 - case Cosine:  
91 - return cosine(a, b);  
92 - case Dot:  
93 - return a.dot(b);  
94 - default:  
95 - qFatal("Invalid metric");  
96 - }  
97 -  
98 - if (result != result)  
99 - qFatal("NaN result.");  
100 -  
101 - return negLogPlusOne ? -log(result+1) : result;  
102 - }  
103 -  
104 - static float cosine(const Mat &a, const Mat &b)  
105 - {  
106 - float dot = 0;  
107 - float magA = 0;  
108 - float magB = 0;  
109 -  
110 - for (int row=0; row<a.rows; row++) {  
111 - for (int col=0; col<a.cols; col++) {  
112 - const float target = a.at<float>(row,col);  
113 - const float query = b.at<float>(row,col);  
114 - dot += target * query;  
115 - magA += target * target;  
116 - magB += query * query;  
117 - }  
118 - }  
119 -  
120 - return dot / (sqrt(magA)*sqrt(magB));  
121 - }  
122 -};  
123 -  
124 -BR_REGISTER(Distance, DistDistance)  
125 -  
126 -/*!  
127 - * \ingroup distances  
128 - * \brief DistDistance wrapper.  
129 - * \author Josh Klontz \cite jklontz  
130 - */  
131 -class DefaultDistance : public UntrainableDistance  
132 -{  
133 - Q_OBJECT  
134 - Distance *distance;  
135 -  
136 - void init()  
137 - {  
138 - distance = Distance::make("Dist("+file.suffix()+")");  
139 - }  
140 -  
141 - float compare(const cv::Mat &a, const cv::Mat &b) const  
142 - {  
143 - return distance->compare(a, b);  
144 - }  
145 -};  
146 -  
147 -BR_REGISTER(Distance, DefaultDistance)  
148 -  
149 -/*!  
150 - * \ingroup distances  
151 - * \brief Distances in series.  
152 - * \author Josh Klontz \cite jklontz  
153 - *  
154 - * The templates are compared using each br::Distance in order.  
155 - * If the result of the comparison with any given distance is -FLOAT_MAX then this result is returned early.  
156 - * Otherwise the returned result is the value of comparing the templates using the last br::Distance.  
157 - */  
158 -class PipeDistance : public Distance  
159 -{  
160 - Q_OBJECT  
161 - Q_PROPERTY(QList<br::Distance*> distances READ get_distances WRITE set_distances RESET reset_distances)  
162 - BR_PROPERTY(QList<br::Distance*>, distances, QList<br::Distance*>())  
163 -  
164 - void train(const TemplateList &data)  
165 - {  
166 - QFutureSynchronizer<void> futures;  
167 - foreach (br::Distance *distance, distances)  
168 - futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));  
169 - futures.waitForFinished();  
170 - }  
171 -  
172 - float compare(const Template &a, const Template &b) const  
173 - {  
174 - float result = -std::numeric_limits<float>::max();  
175 - foreach (br::Distance *distance, distances) {  
176 - result = distance->compare(a, b);  
177 - if (result == -std::numeric_limits<float>::max())  
178 - return result;  
179 - }  
180 - return result;  
181 - }  
182 -};  
183 -  
184 -BR_REGISTER(Distance, PipeDistance)  
185 -  
186 -/*!  
187 - * \ingroup distances  
188 - * \brief Fuses similarity scores across multiple matrices of compared templates  
189 - * \author Scott Klum \cite sklum  
190 - * \note Operation: Mean, sum, min, max are supported.  
191 - */  
192 -class FuseDistance : public Distance  
193 -{  
194 - Q_OBJECT  
195 - Q_ENUMS(Operation)  
196 - Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false)  
197 - Q_PROPERTY(Operation operation READ get_operation WRITE set_operation RESET reset_operation STORED false)  
198 - Q_PROPERTY(QList<float> weights READ get_weights WRITE set_weights RESET reset_weights STORED false)  
199 -  
200 - QList<br::Distance*> distances;  
201 -  
202 -public:  
203 - /*!< */  
204 - enum Operation {Mean, Sum, Max, Min};  
205 -  
206 -private:  
207 - BR_PROPERTY(QString, description, "L2")  
208 - BR_PROPERTY(Operation, operation, Mean)  
209 - BR_PROPERTY(QList<float>, weights, QList<float>())  
210 -  
211 - void train(const TemplateList &src)  
212 - {  
213 - // Partition the templates by matrix  
214 - QList<int> split;  
215 - for (int i=0; i<src.at(0).size(); i++) split.append(1);  
216 -  
217 - QList<TemplateList> partitionedSrc = src.partition(split);  
218 -  
219 - while (distances.size() < partitionedSrc.size())  
220 - distances.append(make(description));  
221 -  
222 - // Train on each of the partitions  
223 - for (int i=0; i<distances.size(); i++)  
224 - distances[i]->train(partitionedSrc[i]);  
225 - }  
226 -  
227 - float compare(const Template &a, const Template &b) const  
228 - {  
229 - if (a.size() != b.size()) qFatal("Comparison size mismatch");  
230 -  
231 - QList<float> scores;  
232 - for (int i=0; i<distances.size(); i++) {  
233 - float weight;  
234 - weights.isEmpty() ? weight = 1. : weight = weights[i];  
235 - scores.append(weight*distances[i]->compare(Template(a.file, a[i]),Template(b.file, b[i])));  
236 - }  
237 -  
238 - switch (operation) {  
239 - case Mean:  
240 - return std::accumulate(scores.begin(),scores.end(),0.0)/(float)scores.size();  
241 - break;  
242 - case Sum:  
243 - return std::accumulate(scores.begin(),scores.end(),0.0);  
244 - break;  
245 - case Min:  
246 - return *std::min_element(scores.begin(),scores.end());  
247 - break;  
248 - case Max:  
249 - return *std::max_element(scores.begin(),scores.end());  
250 - break;  
251 - default:  
252 - qFatal("Invalid operation.");  
253 - }  
254 - return 0;  
255 - }  
256 -  
257 - void store(QDataStream &stream) const  
258 - {  
259 - stream << distances.size();  
260 - foreach (Distance *distance, distances)  
261 - distance->store(stream);  
262 - }  
263 -  
264 - void load(QDataStream &stream)  
265 - {  
266 - int numDistances;  
267 - stream >> numDistances;  
268 - while (distances.size() < numDistances)  
269 - distances.append(make(description));  
270 - foreach (Distance *distance, distances)  
271 - distance->load(stream);  
272 - }  
273 -};  
274 -  
275 -BR_REGISTER(Distance, FuseDistance)  
276 -  
277 -/*!  
278 - * \ingroup distances  
279 - * \brief Fast 8-bit L1 distance  
280 - * \author Josh Klontz \cite jklontz  
281 - */  
282 -class ByteL1Distance : public UntrainableDistance  
283 -{  
284 - Q_OBJECT  
285 -  
286 - float compare(const unsigned char *a, const unsigned char *b, size_t size) const  
287 - {  
288 - return l1(a, b, size);  
289 - }  
290 -};  
291 -  
292 -BR_REGISTER(Distance, ByteL1Distance)  
293 -  
294 -/*!  
295 - * \ingroup distances  
296 - * \brief Fast 4-bit L1 distance  
297 - * \author Josh Klontz \cite jklontz  
298 - */  
299 -class HalfByteL1Distance : public UntrainableDistance  
300 -{  
301 - Q_OBJECT  
302 -  
303 - float compare(const Mat &a, const Mat &b) const  
304 - {  
305 - return packed_l1(a.data, b.data, a.total());  
306 - }  
307 -};  
308 -  
309 -BR_REGISTER(Distance, HalfByteL1Distance)  
310 -  
311 -/*!  
312 - * \ingroup distances  
313 - * \brief Returns -log(distance(a,b)+1)  
314 - * \author Josh Klontz \cite jklontz  
315 - */  
316 -class NegativeLogPlusOneDistance : public UntrainableDistance  
317 -{  
318 - Q_OBJECT  
319 - Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)  
320 - BR_PROPERTY(br::Distance*, distance, NULL)  
321 -  
322 - void train(const TemplateList &src)  
323 - {  
324 - distance->train(src);  
325 - }  
326 -  
327 - float compare(const Template &a, const Template &b) const  
328 - {  
329 - return -log(distance->compare(a,b)+1);  
330 - }  
331 -  
332 - void store(QDataStream &stream) const  
333 - {  
334 - distance->store(stream);  
335 - }  
336 -  
337 - void load(QDataStream &stream)  
338 - {  
339 - distance->load(stream);  
340 - }  
341 -};  
342 -  
343 -BR_REGISTER(Distance, NegativeLogPlusOneDistance)  
344 -  
345 -/*!  
346 - * \ingroup distances  
347 - * \brief Returns \c true if the templates are identical, \c false otherwise.  
348 - * \author Josh Klontz \cite jklontz  
349 - */  
350 -class IdenticalDistance : public UntrainableDistance  
351 -{  
352 - Q_OBJECT  
353 -  
354 - float compare(const Mat &a, const Mat &b) const  
355 - {  
356 - const size_t size = a.total() * a.elemSize();  
357 - if (size != b.total() * b.elemSize()) return 0;  
358 - for (size_t i=0; i<size; i++)  
359 - if (a.data[i] != b.data[i]) return 0;  
360 - return 1;  
361 - }  
362 -};  
363 -  
364 -BR_REGISTER(Distance, IdenticalDistance)  
365 -  
366 -/*!  
367 - * \ingroup distances  
368 - * \brief Online distance metric to attenuate match scores across multiple frames  
369 - * \author Brendan klare \cite bklare  
370 - */  
371 -class OnlineDistance : public UntrainableDistance  
372 -{  
373 - Q_OBJECT  
374 - Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)  
375 - Q_PROPERTY(float alpha READ get_alpha WRITE set_alpha RESET reset_alpha STORED false)  
376 - BR_PROPERTY(br::Distance*, distance, NULL)  
377 - BR_PROPERTY(float, alpha, 0.1f)  
378 -  
379 - mutable QHash<QString,float> scoreHash;  
380 - mutable QMutex mutex;  
381 -  
382 - float compare(const Template &target, const Template &query) const  
383 - {  
384 - float currentScore = distance->compare(target, query);  
385 -  
386 - QMutexLocker mutexLocker(&mutex);  
387 - return scoreHash[target.file.name] = (1.0- alpha) * scoreHash[target.file.name] + alpha * currentScore;  
388 - }  
389 -};  
390 -  
391 -BR_REGISTER(Distance, OnlineDistance)  
392 -  
393 -/*!  
394 - * \ingroup distances  
395 - * \brief Attenuation function based distance from attributes  
396 - * \author Scott Klum \cite sklum  
397 - */  
398 -class AttributeDistance : public UntrainableDistance  
399 -{  
400 - Q_OBJECT  
401 - Q_PROPERTY(QString attribute READ get_attribute WRITE set_attribute RESET reset_attribute STORED false)  
402 - BR_PROPERTY(QString, attribute, QString())  
403 -  
404 - float compare(const Template &target, const Template &query) const  
405 - {  
406 - float queryValue = query.file.get<float>(attribute);  
407 - float targetValue = target.file.get<float>(attribute);  
408 -  
409 - // TODO: Set this magic number to something meaningful  
410 - float stddev = 1;  
411 -  
412 - if (queryValue == targetValue) return 1;  
413 - else return 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((targetValue-queryValue)/stddev, 2));  
414 - }  
415 -};  
416 -  
417 -BR_REGISTER(Distance, AttributeDistance)  
418 -  
419 -/*!  
420 - * \ingroup distances  
421 - * \brief Sum match scores across multiple distances  
422 - * \author Scott Klum \cite sklum  
423 - */  
424 -class SumDistance : public UntrainableDistance  
425 -{  
426 - Q_OBJECT  
427 - Q_PROPERTY(QList<br::Distance*> distances READ get_distances WRITE set_distances RESET reset_distances)  
428 - BR_PROPERTY(QList<br::Distance*>, distances, QList<br::Distance*>())  
429 -  
430 - void train(const TemplateList &data)  
431 - {  
432 - QFutureSynchronizer<void> futures;  
433 - foreach (br::Distance *distance, distances)  
434 - futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));  
435 - futures.waitForFinished();  
436 - }  
437 -  
438 - float compare(const Template &target, const Template &query) const  
439 - {  
440 - float result = 0;  
441 -  
442 - foreach (br::Distance *distance, distances) {  
443 - result += distance->compare(target, query);  
444 -  
445 - if (result == -std::numeric_limits<float>::max())  
446 - return result;  
447 - }  
448 -  
449 - return result;  
450 - }  
451 -};  
452 -  
453 -BR_REGISTER(Distance, SumDistance)  
454 -  
455 -/*!  
456 - * \ingroup transforms  
457 - * \brief Compare each template to a fixed gallery (with name = galleryName), using the specified distance.  
458 - * dst will contain a 1 by n vector of scores.  
459 - * \author Charles Otto \cite caotto  
460 - */  
461 -class GalleryCompareTransform : public Transform  
462 -{  
463 - Q_OBJECT  
464 - Q_PROPERTY(br::Distance *distance READ get_distance WRITE set_distance RESET reset_distance STORED true)  
465 - Q_PROPERTY(QString galleryName READ get_galleryName WRITE set_galleryName RESET reset_galleryName STORED false)  
466 - BR_PROPERTY(br::Distance*, distance, NULL)  
467 - BR_PROPERTY(QString, galleryName, "")  
468 -  
469 - TemplateList gallery;  
470 -  
471 - void project(const Template &src, Template &dst) const  
472 - {  
473 - dst = src;  
474 - if (gallery.isEmpty())  
475 - return;  
476 -  
477 - QList<float> line = distance->compare(gallery, src);  
478 - dst.m() = OpenCVUtils::toMat(line, 1);  
479 - }  
480 -  
481 - void init()  
482 - {  
483 - if (!galleryName.isEmpty())  
484 - gallery = TemplateList::fromGallery(galleryName);  
485 - }  
486 -  
487 - void train(const TemplateList &data)  
488 - {  
489 - gallery = data;  
490 - }  
491 -  
492 - void store(QDataStream &stream) const  
493 - {  
494 - br::Object::store(stream);  
495 - stream << gallery;  
496 - }  
497 -  
498 - void load(QDataStream &stream)  
499 - {  
500 - br::Object::load(stream);  
501 - stream >> gallery;  
502 - }  
503 -  
504 -public:  
505 - GalleryCompareTransform() : Transform(false, true) {}  
506 -};  
507 -  
508 -BR_REGISTER(Transform, GalleryCompareTransform)  
509 -  
510 -  
511 -} // namespace br  
512 -#include "distance.moc"  
openbr/plugins/distance/L2.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <Eigen/Dense>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief L2 distance computed using eigen.
  27 + * \author Josh Klontz \cite jklontz
  28 + */
  29 +class L2Distance : public UntrainableDistance
  30 +{
  31 + Q_OBJECT
  32 +
  33 + float compare(const cv::Mat &a, const cv::Mat &b) const
  34 + {
  35 + const int size = a.rows * a.cols;
  36 + Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size);
  37 + Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size);
  38 + return (aMap-bMap).squaredNorm();
  39 + }
  40 +};
  41 +
  42 +BR_REGISTER(Distance, L2Distance)
  43 +
  44 +} // namespace br
  45 +
  46 +#include "distance/L2.moc"
openbr/plugins/distance/attribute.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Attenuation function based distance from attributes
  25 + * \author Scott Klum \cite sklum
  26 + */
  27 +class AttributeDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(QString attribute READ get_attribute WRITE set_attribute RESET reset_attribute STORED false)
  31 + BR_PROPERTY(QString, attribute, QString())
  32 +
  33 + float compare(const Template &target, const Template &query) const
  34 + {
  35 + float queryValue = query.file.get<float>(attribute);
  36 + float targetValue = target.file.get<float>(attribute);
  37 +
  38 + // TODO: Set this magic number to something meaningful
  39 + float stddev = 1;
  40 +
  41 + if (queryValue == targetValue) return 1;
  42 + else return 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((targetValue-queryValue)/stddev, 2));
  43 + }
  44 +};
  45 +
  46 +BR_REGISTER(Distance, AttributeDistance)
  47 +
  48 +} // namespace br
  49 +
  50 +#include "distance/attribute.moc"
openbr/plugins/distance/bayesianquantization.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/opencvutils.h>
  21 +
  22 +using namespace cv;
  23 +
  24 +namespace br
  25 +{
  26 +
  27 +/*!
  28 + * \ingroup distances
  29 + * \brief Bayesian quantization distance
  30 + * \author Josh Klontz \cite jklontz
  31 + */
  32 +class BayesianQuantizationDistance : public Distance
  33 +{
  34 + Q_OBJECT
  35 +
  36 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  37 + BR_PROPERTY(QString, inputVariable, "Label")
  38 +
  39 + QVector<float> loglikelihoods;
  40 +
  41 + static void computeLogLikelihood(const Mat &data, const QList<int> &labels, float *loglikelihood)
  42 + {
  43 + const QList<uchar> vals = OpenCVUtils::matrixToVector<uchar>(data);
  44 + if (vals.size() != labels.size())
  45 + qFatal("Logic error.");
  46 +
  47 + QVector<quint64> genuines(256, 0), impostors(256,0);
  48 + for (int i=0; i<vals.size(); i++)
  49 + for (int j=i+1; j<vals.size(); j++)
  50 + if (labels[i] == labels[j]) genuines[abs(vals[i]-vals[j])]++;
  51 + else impostors[abs(vals[i]-vals[j])]++;
  52 +
  53 + quint64 totalGenuines(0), totalImpostors(0);
  54 + for (int i=0; i<256; i++) {
  55 + totalGenuines += genuines[i];
  56 + totalImpostors += impostors[i];
  57 + }
  58 +
  59 + for (int i=0; i<256; i++)
  60 + loglikelihood[i] = log((float(genuines[i]+1)/totalGenuines)/(float(impostors[i]+1)/totalImpostors));
  61 + }
  62 +
  63 + void train(const TemplateList &src)
  64 + {
  65 + if ((src.first().size() > 1) || (src.first().m().type() != CV_8UC1))
  66 + qFatal("Expected sigle matrix templates of type CV_8UC1!");
  67 +
  68 + const Mat data = OpenCVUtils::toMat(src.data());
  69 + const QList<int> templateLabels = src.indexProperty(inputVariable);
  70 + loglikelihoods = QVector<float>(data.cols*256, 0);
  71 +
  72 + QFutureSynchronizer<void> futures;
  73 + for (int i=0; i<data.cols; i++)
  74 + futures.addFuture(QtConcurrent::run(&BayesianQuantizationDistance::computeLogLikelihood, data.col(i), templateLabels, &loglikelihoods.data()[i*256]));
  75 + futures.waitForFinished();
  76 + }
  77 +
  78 + float compare(const cv::Mat &a, const cv::Mat &b) const
  79 + {
  80 + const uchar *aData = a.data;
  81 + const uchar *bData = b.data;
  82 + const int size = a.rows * a.cols;
  83 + float likelihood = 0;
  84 + for (int i=0; i<size; i++)
  85 + likelihood += loglikelihoods[i*256+abs(aData[i]-bData[i])];
  86 + return likelihood;
  87 + }
  88 +
  89 + void store(QDataStream &stream) const
  90 + {
  91 + stream << loglikelihoods;
  92 + }
  93 +
  94 + void load(QDataStream &stream)
  95 + {
  96 + stream >> loglikelihoods;
  97 + }
  98 +};
  99 +
  100 +BR_REGISTER(Distance, BayesianQuantizationDistance)
  101 +
  102 +} // namespace br
  103 +
  104 +#include "distance/bayesianquantization.moc"
openbr/plugins/distance/byteL1.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/distance_sse.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup distances
  25 + * \brief Fast 8-bit L1 distance
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class ByteL1Distance : public UntrainableDistance
  29 +{
  30 + Q_OBJECT
  31 +
  32 + float compare(const unsigned char *a, const unsigned char *b, size_t size) const
  33 + {
  34 + return l1(a, b, size);
  35 + }
  36 +};
  37 +
  38 +BR_REGISTER(Distance, ByteL1Distance)
  39 +
  40 +} // namespace br
  41 +
  42 +#include "distance/byteL1.moc"
openbr/plugins/distance/crossvalidate.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Cross validate a distance metric.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class CrossValidateDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 +
  31 + float compare(const Template &a, const Template &b) const
  32 + {
  33 + static const QString key("Partition"); // More efficient to preallocate this
  34 + const int partitionA = a.file.get<int>(key, 0);
  35 + const int partitionB = b.file.get<int>(key, 0);
  36 + return (partitionA != partitionB) ? -std::numeric_limits<float>::max() : 0;
  37 + }
  38 +};
  39 +
  40 +BR_REGISTER(Distance, CrossValidateDistance)
  41 +
  42 +} // namespace br
  43 +
  44 +#include "distance/crossvalidate.moc"
openbr/plugins/distance/default.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief DistDistance wrapper.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class DefaultDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 + Distance *distance;
  31 +
  32 + void init()
  33 + {
  34 + distance = Distance::make("Dist("+file.suffix()+")");
  35 + }
  36 +
  37 + float compare(const cv::Mat &a, const cv::Mat &b) const
  38 + {
  39 + return distance->compare(a, b);
  40 + }
  41 +};
  42 +
  43 +BR_REGISTER(Distance, DefaultDistance)
  44 +
  45 +} // namespace br
  46 +
  47 +#include "distance/default.moc"
openbr/plugins/distance/dist.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <opencv2/imgproc/imgproc.hpp>
  18 +#include <openbr/plugins/openbr_internal.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup distances
  27 + * \brief Standard distance metrics
  28 + * \author Josh Klontz \cite jklontz
  29 + */
  30 +class DistDistance : public UntrainableDistance
  31 +{
  32 + Q_OBJECT
  33 + Q_ENUMS(Metric)
  34 + Q_PROPERTY(Metric metric READ get_metric WRITE set_metric RESET reset_metric STORED false)
  35 + Q_PROPERTY(bool negLogPlusOne READ get_negLogPlusOne WRITE set_negLogPlusOne RESET reset_negLogPlusOne STORED false)
  36 +
  37 +public:
  38 + /*!< */
  39 + enum Metric { Correlation,
  40 + ChiSquared,
  41 + Intersection,
  42 + Bhattacharyya,
  43 + INF,
  44 + L1,
  45 + L2,
  46 + Cosine,
  47 + Dot};
  48 +
  49 +private:
  50 + BR_PROPERTY(Metric, metric, L2)
  51 + BR_PROPERTY(bool, negLogPlusOne, true)
  52 +
  53 + float compare(const Mat &a, const Mat &b) const
  54 + {
  55 + if ((a.size != b.size) ||
  56 + (a.type() != b.type()))
  57 + return -std::numeric_limits<float>::max();
  58 +
  59 +// TODO: this max value is never returned based on the switch / default
  60 + float result = std::numeric_limits<float>::max();
  61 + switch (metric) {
  62 + case Correlation:
  63 + return compareHist(a, b, CV_COMP_CORREL);
  64 + case ChiSquared:
  65 + result = compareHist(a, b, CV_COMP_CHISQR);
  66 + break;
  67 + case Intersection:
  68 + result = compareHist(a, b, CV_COMP_INTERSECT);
  69 + break;
  70 + case Bhattacharyya:
  71 + result = compareHist(a, b, CV_COMP_BHATTACHARYYA);
  72 + break;
  73 + case INF:
  74 + result = norm(a, b, NORM_INF);
  75 + break;
  76 + case L1:
  77 + result = norm(a, b, NORM_L1);
  78 + break;
  79 + case L2:
  80 + result = norm(a, b, NORM_L2);
  81 + break;
  82 + case Cosine:
  83 + return cosine(a, b);
  84 + case Dot:
  85 + return a.dot(b);
  86 + default:
  87 + qFatal("Invalid metric");
  88 + }
  89 +
  90 + if (result != result)
  91 + qFatal("NaN result.");
  92 +
  93 + return negLogPlusOne ? -log(result+1) : result;
  94 + }
  95 +
  96 + static float cosine(const Mat &a, const Mat &b)
  97 + {
  98 + float dot = 0;
  99 + float magA = 0;
  100 + float magB = 0;
  101 +
  102 + for (int row=0; row<a.rows; row++) {
  103 + for (int col=0; col<a.cols; col++) {
  104 + const float target = a.at<float>(row,col);
  105 + const float query = b.at<float>(row,col);
  106 + dot += target * query;
  107 + magA += target * target;
  108 + magB += query * query;
  109 + }
  110 + }
  111 +
  112 + return dot / (sqrt(magA)*sqrt(magB));
  113 + }
  114 +};
  115 +
  116 +BR_REGISTER(Distance, DistDistance)
  117 +
  118 +} // namespace br
  119 +
  120 +#include "distance/dist.moc"
openbr/plugins/distance/filter.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Checks target metadata against filters.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class FilterDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 +
  31 + float compare(const Template &a, const Template &b) const
  32 + {
  33 + (void) b; // Query template isn't checked
  34 + foreach (const QString &key, Globals->filters.keys()) {
  35 + bool keep = false;
  36 + const QString metadata = a.file.get<QString>(key, "");
  37 + if (Globals->filters[key].isEmpty()) continue;
  38 + if (metadata.isEmpty()) return -std::numeric_limits<float>::max();
  39 + foreach (const QString &value, Globals->filters[key]) {
  40 + if (metadata == value) {
  41 + keep = true;
  42 + break;
  43 + }
  44 + }
  45 + if (!keep) return -std::numeric_limits<float>::max();
  46 + }
  47 + return 0;
  48 + }
  49 +};
  50 +
  51 +BR_REGISTER(Distance, FilterDistance)
  52 +
  53 +} // namespace br
  54 +
  55 +#include "distance/filter.moc"
openbr/plugins/distance/fuse.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <numeric>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief Fuses similarity scores across multiple matrices of compared templates
  27 + * \author Scott Klum \cite sklum
  28 + * \note Operation: Mean, sum, min, max are supported.
  29 + */
  30 +class FuseDistance : public Distance
  31 +{
  32 + Q_OBJECT
  33 + Q_ENUMS(Operation)
  34 + Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false)
  35 + Q_PROPERTY(Operation operation READ get_operation WRITE set_operation RESET reset_operation STORED false)
  36 + Q_PROPERTY(QList<float> weights READ get_weights WRITE set_weights RESET reset_weights STORED false)
  37 +
  38 + QList<br::Distance*> distances;
  39 +
  40 +public:
  41 + /*!< */
  42 + enum Operation {Mean, Sum, Max, Min};
  43 +
  44 +private:
  45 + BR_PROPERTY(QString, description, "L2")
  46 + BR_PROPERTY(Operation, operation, Mean)
  47 + BR_PROPERTY(QList<float>, weights, QList<float>())
  48 +
  49 + void train(const TemplateList &src)
  50 + {
  51 + // Partition the templates by matrix
  52 + QList<int> split;
  53 + for (int i=0; i<src.at(0).size(); i++) split.append(1);
  54 +
  55 + QList<TemplateList> partitionedSrc = src.partition(split);
  56 +
  57 + while (distances.size() < partitionedSrc.size())
  58 + distances.append(make(description));
  59 +
  60 + // Train on each of the partitions
  61 + for (int i=0; i<distances.size(); i++)
  62 + distances[i]->train(partitionedSrc[i]);
  63 + }
  64 +
  65 + float compare(const Template &a, const Template &b) const
  66 + {
  67 + if (a.size() != b.size()) qFatal("Comparison size mismatch");
  68 +
  69 + QList<float> scores;
  70 + for (int i=0; i<distances.size(); i++) {
  71 + float weight;
  72 + weights.isEmpty() ? weight = 1. : weight = weights[i];
  73 + scores.append(weight*distances[i]->compare(Template(a.file, a[i]),Template(b.file, b[i])));
  74 + }
  75 +
  76 + switch (operation) {
  77 + case Mean:
  78 + return std::accumulate(scores.begin(),scores.end(),0.0)/(float)scores.size();
  79 + break;
  80 + case Sum:
  81 + return std::accumulate(scores.begin(),scores.end(),0.0);
  82 + break;
  83 + case Min:
  84 + return *std::min_element(scores.begin(),scores.end());
  85 + break;
  86 + case Max:
  87 + return *std::max_element(scores.begin(),scores.end());
  88 + break;
  89 + default:
  90 + qFatal("Invalid operation.");
  91 + }
  92 + return 0;
  93 + }
  94 +
  95 + void store(QDataStream &stream) const
  96 + {
  97 + stream << distances.size();
  98 + foreach (Distance *distance, distances)
  99 + distance->store(stream);
  100 + }
  101 +
  102 + void load(QDataStream &stream)
  103 + {
  104 + int numDistances;
  105 + stream >> numDistances;
  106 + while (distances.size() < numDistances)
  107 + distances.append(make(description));
  108 + foreach (Distance *distance, distances)
  109 + distance->load(stream);
  110 + }
  111 +};
  112 +
  113 +BR_REGISTER(Distance, FuseDistance)
  114 +
  115 +} // namespace br
  116 +
  117 +#include "distance/fuse.moc"
openbr/plugins/distance/halfbyteL1.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/distance_sse.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup distances
  27 + * \brief Fast 4-bit L1 distance
  28 + * \author Josh Klontz \cite jklontz
  29 + */
  30 +class HalfByteL1Distance : public UntrainableDistance
  31 +{
  32 + Q_OBJECT
  33 +
  34 + float compare(const Mat &a, const Mat &b) const
  35 + {
  36 + return packed_l1(a.data, b.data, a.total());
  37 + }
  38 +};
  39 +
  40 +BR_REGISTER(Distance, HalfByteL1Distance)
  41 +
  42 +
  43 +} // namespace br
  44 +
  45 +#include "distance/halfbyteL1.moc"
openbr/plugins/distance/heatmap.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief 1v1 heat map comparison
  25 + * \author Scott Klum \cite sklum
  26 + */
  27 +class HeatMapDistance : public Distance
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false)
  31 + Q_PROPERTY(int step READ get_step WRITE set_step RESET reset_step STORED false)
  32 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  33 + BR_PROPERTY(QString, description, "IdenticalDistance")
  34 + BR_PROPERTY(int, step, 1)
  35 + BR_PROPERTY(QString, inputVariable, "Label")
  36 +
  37 + QList<br::Distance*> distances;
  38 +
  39 + void train(const TemplateList &src)
  40 + {
  41 + QList<TemplateList> patches;
  42 +
  43 + // Split src into list of TemplateLists of corresponding patches across all Templates
  44 + for (int i=0; i<step; i++) {
  45 + TemplateList patchBuffer;
  46 + for (int j=0; j<src.size(); j++)
  47 + patchBuffer.append(Template(src[j].file, src[j][i]));
  48 + patches.append(patchBuffer);
  49 + patchBuffer.clear();
  50 + }
  51 +
  52 + while (distances.size() < patches.size())
  53 + distances.append(make(description));
  54 +
  55 + // Train on a distance for each patch
  56 + for (int i=0; i<distances.size(); i++)
  57 + distances[i]->train(patches[i]);
  58 + }
  59 +
  60 + float compare(const cv::Mat &target, const cv::Mat &query) const
  61 + {
  62 + (void) target;
  63 + (void) query;
  64 + qFatal("Heatmap Distance not compatible with Template to Template comparison.");
  65 +
  66 + return 0;
  67 + }
  68 +
  69 + void compare(const TemplateList &target, const TemplateList &query, Output *output) const
  70 + {
  71 + for (int i=0; i<target.size(); i++) {
  72 + if (target[i].size() != step || query[i].size() != step) qFatal("Heatmap step not equal to the number of patches.");
  73 + for (int j=0; j<step; j++)
  74 + output->setRelative(distances[j]->compare(target[i][j],query[i][j]), j, 0);
  75 + }
  76 + }
  77 +
  78 + void store(QDataStream &stream) const
  79 + {
  80 + stream << distances.size();
  81 + foreach (Distance *distance, distances)
  82 + distance->store(stream);
  83 + }
  84 +
  85 + void load(QDataStream &stream)
  86 + {
  87 + int numDistances;
  88 + stream >> numDistances;
  89 + while (distances.size() < numDistances)
  90 + distances.append(make(description));
  91 + foreach (Distance *distance, distances)
  92 + distance->load(stream);
  93 + }
  94 +};
  95 +
  96 +BR_REGISTER(Distance, HeatMapDistance)
  97 +
  98 +} // namespace br
  99 +
  100 +#include "distance/heatmap.moc"
openbr/plugins/distance/identical.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +using namespace cv;
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief Returns \c true if the templates are identical, \c false otherwise.
  27 + * \author Josh Klontz \cite jklontz
  28 + */
  29 +class IdenticalDistance : public UntrainableDistance
  30 +{
  31 + Q_OBJECT
  32 +
  33 + float compare(const Mat &a, const Mat &b) const
  34 + {
  35 + const size_t size = a.total() * a.elemSize();
  36 + if (size != b.total() * b.elemSize()) return 0;
  37 + for (size_t i=0; i<size; i++)
  38 + if (a.data[i] != b.data[i]) return 0;
  39 + return 1;
  40 + }
  41 +};
  42 +
  43 +BR_REGISTER(Distance, IdenticalDistance)
  44 +
  45 +} // namespace br
  46 +
  47 +#include "distance/identical.moc"
openbr/plugins/distance/keypointmatcher.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <opencv2/features2d/features2d.hpp>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +using namespace cv;
  22 +
  23 +namespace br
  24 +{
  25 +
  26 +/*!
  27 + * \ingroup transforms
  28 + * \brief Wraps OpenCV Key Point Matcher
  29 + * \author Josh Klontz \cite jklontz
  30 + */
  31 +class KeyPointMatcherDistance : public UntrainableDistance
  32 +{
  33 + Q_OBJECT
  34 + Q_PROPERTY(QString matcher READ get_matcher WRITE set_matcher RESET reset_matcher STORED false)
  35 + Q_PROPERTY(float maxRatio READ get_maxRatio WRITE set_maxRatio RESET reset_maxRatio STORED false)
  36 + BR_PROPERTY(QString, matcher, "BruteForce")
  37 + BR_PROPERTY(float, maxRatio, 0.8)
  38 +
  39 + Ptr<DescriptorMatcher> descriptorMatcher;
  40 +
  41 + void init()
  42 + {
  43 + descriptorMatcher = DescriptorMatcher::create(matcher.toStdString());
  44 + if (descriptorMatcher.empty())
  45 + qFatal("Failed to create DescriptorMatcher: %s", qPrintable(matcher));
  46 + }
  47 +
  48 + float compare(const Mat &a, const Mat &b) const
  49 + {
  50 + if ((a.rows < 2) || (b.rows < 2)) return 0;
  51 +
  52 + std::vector< std::vector<DMatch> > matches;
  53 + if (a.rows < b.rows) descriptorMatcher->knnMatch(a, b, matches, 2);
  54 + else descriptorMatcher->knnMatch(b, a, matches, 2);
  55 +
  56 + QList<float> distances;
  57 + foreach (const std::vector<DMatch> &match, matches) {
  58 + if (match[0].distance / match[1].distance > maxRatio) continue;
  59 + distances.append(match[0].distance);
  60 + }
  61 + qSort(distances);
  62 +
  63 + float similarity = 0;
  64 + for (int i=0; i<distances.size(); i++)
  65 + similarity += 1.f/(1+distances[i])/(i+1);
  66 + return similarity;
  67 + }
  68 +};
  69 +
  70 +BR_REGISTER(Distance, KeyPointMatcherDistance)
  71 +
  72 +} // namespace br
  73 +
  74 +#include "distance/keypointmatcher.moc"
openbr/plugins/distance/l1.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <Eigen/Dense>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief L1 distance computed using eigen.
  27 + * \author Josh Klontz \cite jklontz
  28 + */
  29 +class L1Distance : public UntrainableDistance
  30 +{
  31 + Q_OBJECT
  32 +
  33 + float compare(const cv::Mat &a, const cv::Mat &b) const
  34 + {
  35 + const int size = a.rows * a.cols;
  36 + Eigen::Map<Eigen::VectorXf> aMap((float*)a.data, size);
  37 + Eigen::Map<Eigen::VectorXf> bMap((float*)b.data, size);
  38 + return (aMap-bMap).cwiseAbs().sum();
  39 + }
  40 +};
  41 +
  42 +BR_REGISTER(Distance, L1Distance)
  43 +
  44 +} // namespace br
  45 +
  46 +#include "distance/L1.moc"
openbr/plugins/distance/matchprobability.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/common.h>
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +float KDEPointer(const QList<float> *scores, double x, double h)
  26 +{
  27 + return Common::KernelDensityEstimation(*scores, x, h);
  28 +}
  29 +
  30 +/* Kernel Density Estimator */
  31 +struct KDE
  32 +{
  33 + float min, max;
  34 + double mean, stddev;
  35 + QList<float> bins;
  36 +
  37 + KDE() : min(0), max(1), mean(0), stddev(1) {}
  38 +
  39 + KDE(const QList<float> &scores, bool trainKDE)
  40 + {
  41 + Common::MinMax(scores, &min, &max);
  42 + Common::MeanStdDev(scores, &mean, &stddev);
  43 +
  44 + if (!trainKDE)
  45 + return;
  46 +
  47 + double h = Common::KernelDensityBandwidth(scores);
  48 + const int size = 255;
  49 + bins.reserve(size);
  50 +
  51 + QFutureSynchronizer<float> futures;
  52 +
  53 + for (int i=0; i < size; i++)
  54 + futures.addFuture(QtConcurrent::run(KDEPointer, &scores, min + (max-min)*i/(size-1), h));
  55 + futures.waitForFinished();
  56 +
  57 + foreach(const QFuture<float> & future, futures.futures())
  58 + bins.append(future.result());
  59 + }
  60 +
  61 + float operator()(float score, bool gaussian = true) const
  62 + {
  63 + if (gaussian) return 1/(stddev*sqrt(2*CV_PI))*exp(-0.5*pow((score-mean)/stddev, 2));
  64 + if (bins.empty())
  65 + return -std::numeric_limits<float>::max();
  66 +
  67 + if (score <= min) return bins.first();
  68 + if (score >= max) return bins.last();
  69 + const float x = (score-min)/(max-min)*bins.size();
  70 + const float y1 = bins[floor(x)];
  71 + const float y2 = bins[ceil(x)];
  72 + return y1 + (y2-y1)*(x-floor(x));
  73 + }
  74 +};
  75 +
  76 +QDataStream &operator<<(QDataStream &stream, const KDE &kde)
  77 +{
  78 + return stream << kde.min << kde.max << kde.mean << kde.stddev << kde.bins;
  79 +}
  80 +
  81 +QDataStream &operator>>(QDataStream &stream, KDE &kde)
  82 +{
  83 + return stream >> kde.min >> kde.max >> kde.mean >> kde.stddev >> kde.bins;
  84 +}
  85 +
  86 +/* Match Probability */
  87 +struct MP
  88 +{
  89 + KDE genuine, impostor;
  90 + MP() {}
  91 + MP(const QList<float> &genuineScores, const QList<float> &impostorScores, bool trainKDE)
  92 + : genuine(genuineScores, trainKDE), impostor(impostorScores, trainKDE) {}
  93 + float operator()(float score, bool gaussian = true) const
  94 + {
  95 + const float g = genuine(score, gaussian);
  96 + const float s = g / (impostor(score, gaussian) + g);
  97 + return s;
  98 + }
  99 +};
  100 +
  101 +QDataStream &operator<<(QDataStream &stream, const MP &nmp)
  102 +{
  103 + return stream << nmp.genuine << nmp.impostor;
  104 +}
  105 +
  106 +QDataStream &operator>>(QDataStream &stream, MP &nmp)
  107 +{
  108 + return stream >> nmp.genuine >> nmp.impostor;
  109 +}
  110 +
  111 +/*!
  112 + * \ingroup distances
  113 + * \brief Match Probability \cite klare12
  114 + * \author Josh Klontz \cite jklontz
  115 + */
  116 +class MatchProbabilityDistance : public Distance
  117 +{
  118 + Q_OBJECT
  119 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  120 + Q_PROPERTY(bool gaussian READ get_gaussian WRITE set_gaussian RESET reset_gaussian STORED false)
  121 + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false)
  122 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  123 +
  124 + MP mp;
  125 +
  126 + void train(const TemplateList &src)
  127 + {
  128 + distance->train(src);
  129 +
  130 + const QList<int> labels = src.indexProperty(inputVariable);
  131 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
  132 + distance->compare(src, src, matrixOutput.data());
  133 +
  134 + QList<float> genuineScores, impostorScores;
  135 + genuineScores.reserve(labels.size());
  136 + impostorScores.reserve(labels.size()*labels.size());
  137 + for (int i=0; i<src.size(); i++) {
  138 + for (int j=0; j<i; j++) {
  139 + const float score = matrixOutput.data()->data.at<float>(i, j);
  140 + if (score == -std::numeric_limits<float>::max()) continue;
  141 + if (crossModality && src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue;
  142 + if (labels[i] == labels[j]) genuineScores.append(score);
  143 + else impostorScores.append(score);
  144 + }
  145 + }
  146 +
  147 + mp = MP(genuineScores, impostorScores, !gaussian);
  148 + }
  149 +
  150 + float compare(const Template &target, const Template &query) const
  151 + {
  152 + return normalize(distance->compare(target, query));
  153 + }
  154 +
  155 + float compare(const cv::Mat &target, const cv::Mat &query) const
  156 + {
  157 + return normalize(distance->compare(target, query));
  158 + }
  159 +
  160 + float compare(const uchar *a, const uchar *b, size_t size) const
  161 + {
  162 + return normalize(distance->compare(a, b, size));
  163 + }
  164 +
  165 + float normalize(float score) const
  166 + {
  167 + if (score == -std::numeric_limits<float>::max()) return score;
  168 + if (!Globals->scoreNormalization) return -log(score+1);
  169 + return mp(score, gaussian);
  170 + }
  171 +
  172 + void store(QDataStream &stream) const
  173 + {
  174 + distance->store(stream);
  175 + stream << mp;
  176 + }
  177 +
  178 + void load(QDataStream &stream)
  179 + {
  180 + distance->load(stream);
  181 + stream >> mp;
  182 + }
  183 +
  184 +protected:
  185 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  186 + BR_PROPERTY(bool, gaussian, true)
  187 + BR_PROPERTY(bool, crossModality, false)
  188 + BR_PROPERTY(QString, inputVariable, "Label")
  189 +};
  190 +
  191 +BR_REGISTER(Distance, MatchProbabilityDistance)
  192 +
  193 +} // namespace br
  194 +
  195 +#include "distance/matchprobability.moc"
openbr/plugins/distance/metadata.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup distances
  25 + * \brief Checks target metadata against query metadata.
  26 + * \author Scott Klum \cite sklum
  27 + */
  28 +class MetadataDistance : public UntrainableDistance
  29 +{
  30 + Q_OBJECT
  31 +
  32 + Q_PROPERTY(QStringList filters READ get_filters WRITE set_filters RESET reset_filters STORED false)
  33 + BR_PROPERTY(QStringList, filters, QStringList())
  34 +
  35 + float compare(const Template &a, const Template &b) const
  36 + {
  37 + foreach (const QString &key, filters) {
  38 + QString aValue = a.file.get<QString>(key, QString());
  39 + QString bValue = b.file.get<QString>(key, QString());
  40 +
  41 + // The query value may be a range. Let's check.
  42 + if (bValue.isEmpty()) bValue = QtUtils::toString(b.file.get<QPointF>(key, QPointF()));
  43 +
  44 + if (aValue.isEmpty() || bValue.isEmpty()) continue;
  45 +
  46 + bool keep = false;
  47 + bool ok;
  48 +
  49 + QPointF range = QtUtils::toPoint(bValue,&ok);
  50 +
  51 + if (ok) /* Range */ {
  52 + int value = range.x();
  53 + int upperBound = range.y();
  54 +
  55 + while (value <= upperBound) {
  56 + if (aValue == QString::number(value)) {
  57 + keep = true;
  58 + break;
  59 + }
  60 + value++;
  61 + }
  62 + }
  63 + else if (aValue == bValue) keep = true;
  64 +
  65 + if (!keep) return -std::numeric_limits<float>::max();
  66 + }
  67 + return 0;
  68 + }
  69 +};
  70 +
  71 +
  72 +BR_REGISTER(Distance, MetadataDistance)
  73 +
  74 +} // namespace br
  75 +
  76 +#include "distance/metadata.moc"
openbr/plugins/distance/neglogplusone.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Returns -log(distance(a,b)+1)
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class NegativeLogPlusOneDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  31 + BR_PROPERTY(br::Distance*, distance, NULL)
  32 +
  33 + void train(const TemplateList &src)
  34 + {
  35 + distance->train(src);
  36 + }
  37 +
  38 + float compare(const Template &a, const Template &b) const
  39 + {
  40 + return -log(distance->compare(a,b)+1);
  41 + }
  42 +
  43 + void store(QDataStream &stream) const
  44 + {
  45 + distance->store(stream);
  46 + }
  47 +
  48 + void load(QDataStream &stream)
  49 + {
  50 + distance->load(stream);
  51 + }
  52 +};
  53 +
  54 +BR_REGISTER(Distance, NegativeLogPlusOneDistance)
  55 +
  56 +} // namespace br
  57 +
  58 +#include "distance/neglogplusone.moc"
openbr/plugins/distance/online.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Online distance metric to attenuate match scores across multiple frames
  25 + * \author Brendan klare \cite bklare
  26 + */
  27 +class OnlineDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  31 + Q_PROPERTY(float alpha READ get_alpha WRITE set_alpha RESET reset_alpha STORED false)
  32 + BR_PROPERTY(br::Distance*, distance, NULL)
  33 + BR_PROPERTY(float, alpha, 0.1f)
  34 +
  35 + mutable QHash<QString,float> scoreHash;
  36 + mutable QMutex mutex;
  37 +
  38 + float compare(const Template &target, const Template &query) const
  39 + {
  40 + float currentScore = distance->compare(target, query);
  41 +
  42 + QMutexLocker mutexLocker(&mutex);
  43 + return scoreHash[target.file.name] = (1.0- alpha) * scoreHash[target.file.name] + alpha * currentScore;
  44 + }
  45 +};
  46 +
  47 +BR_REGISTER(Distance, OnlineDistance)
  48 +
  49 +} // namespace br
  50 +
  51 +#include "distance/online.moc"
openbr/plugins/distance/pipe.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief Distances in series.
  27 + * \author Josh Klontz \cite jklontz
  28 + *
  29 + * The templates are compared using each br::Distance in order.
  30 + * If the result of the comparison with any given distance is -FLOAT_MAX then this result is returned early.
  31 + * Otherwise the returned result is the value of comparing the templates using the last br::Distance.
  32 + */
  33 +class PipeDistance : public Distance
  34 +{
  35 + Q_OBJECT
  36 + Q_PROPERTY(QList<br::Distance*> distances READ get_distances WRITE set_distances RESET reset_distances)
  37 + BR_PROPERTY(QList<br::Distance*>, distances, QList<br::Distance*>())
  38 +
  39 + void train(const TemplateList &data)
  40 + {
  41 + QFutureSynchronizer<void> futures;
  42 + foreach (br::Distance *distance, distances)
  43 + futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));
  44 + futures.waitForFinished();
  45 + }
  46 +
  47 + float compare(const Template &a, const Template &b) const
  48 + {
  49 + float result = -std::numeric_limits<float>::max();
  50 + foreach (br::Distance *distance, distances) {
  51 + result = distance->compare(a, b);
  52 + if (result == -std::numeric_limits<float>::max())
  53 + return result;
  54 + }
  55 + return result;
  56 + }
  57 +};
  58 +
  59 +BR_REGISTER(Distance, PipeDistance)
  60 +
  61 +} // namespace br
  62 +
  63 +#include "distance/pipe.moc"
openbr/plugins/distance/reject.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Sets distance to -FLOAT_MAX if a target template has/doesn't have a key.
  25 + * \author Scott Klum \cite sklum
  26 + */
  27 +class RejectDistance : public UntrainableDistance
  28 +{
  29 + Q_OBJECT
  30 +
  31 + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false)
  32 + BR_PROPERTY(QStringList, keys, QStringList())
  33 + Q_PROPERTY(bool rejectIfContains READ get_rejectIfContains WRITE set_rejectIfContains RESET reset_rejectIfContains STORED false)
  34 + BR_PROPERTY(bool, rejectIfContains, false)
  35 +
  36 + float compare(const Template &a, const Template &b) const
  37 + {
  38 + // We don't look at the query
  39 + (void) b;
  40 +
  41 + foreach (const QString &key, keys)
  42 + if ((rejectIfContains && a.file.contains(key)) || (!rejectIfContains && !a.file.contains(key)))
  43 + return -std::numeric_limits<float>::max();
  44 +
  45 + return 0;
  46 + }
  47 +};
  48 +
  49 +
  50 +BR_REGISTER(Distance, RejectDistance)
  51 +
  52 +} // namespace br
  53 +
  54 +#include "distance/reject.moc"
openbr/plugins/distance/sum.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtConcurrent>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +
  21 +namespace br
  22 +{
  23 +
  24 +/*!
  25 + * \ingroup distances
  26 + * \brief Sum match scores across multiple distances
  27 + * \author Scott Klum \cite sklum
  28 + */
  29 +class SumDistance : public UntrainableDistance
  30 +{
  31 + Q_OBJECT
  32 + Q_PROPERTY(QList<br::Distance*> distances READ get_distances WRITE set_distances RESET reset_distances)
  33 + BR_PROPERTY(QList<br::Distance*>, distances, QList<br::Distance*>())
  34 +
  35 + void train(const TemplateList &data)
  36 + {
  37 + QFutureSynchronizer<void> futures;
  38 + foreach (br::Distance *distance, distances)
  39 + futures.addFuture(QtConcurrent::run(distance, &Distance::train, data));
  40 + futures.waitForFinished();
  41 + }
  42 +
  43 + float compare(const Template &target, const Template &query) const
  44 + {
  45 + float result = 0;
  46 +
  47 + foreach (br::Distance *distance, distances) {
  48 + result += distance->compare(target, query);
  49 +
  50 + if (result == -std::numeric_limits<float>::max())
  51 + return result;
  52 + }
  53 +
  54 + return result;
  55 + }
  56 +};
  57 +
  58 +BR_REGISTER(Distance, SumDistance)
  59 +
  60 +} // namespace br
  61 +
  62 +#include "distance/sum.moc"
openbr/plugins/distance/turk.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/opencvutils.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup distances
  25 + * \brief Unmaps Turk HITs to be compared against query mats
  26 + * \author Scott Klum \cite sklum
  27 + */
  28 +class TurkDistance : public UntrainableDistance
  29 +{
  30 + Q_OBJECT
  31 + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key)
  32 + Q_PROPERTY(QStringList values READ get_values WRITE set_values RESET reset_values STORED false)
  33 + BR_PROPERTY(QString, key, QString())
  34 + BR_PROPERTY(QStringList, values, QStringList())
  35 +
  36 + bool targetHuman;
  37 + bool queryMachine;
  38 +
  39 + void init()
  40 + {
  41 + targetHuman = Globals->property("TurkTargetHuman").toBool();
  42 + queryMachine = Globals->property("TurkQueryMachine").toBool();
  43 + }
  44 +
  45 + cv::Mat getValues(const Template &t) const
  46 + {
  47 + QList<float> result;
  48 + foreach (const QString &value, values)
  49 + result.append(t.file.get<float>(key + "_" + value));
  50 + return OpenCVUtils::toMat(result, 1);
  51 + }
  52 +
  53 + float compare(const Template &target, const Template &query) const
  54 + {
  55 + const cv::Mat a = targetHuman ? getValues(target) : target.m();
  56 + const cv::Mat b = queryMachine ? query.m() : getValues(query);
  57 + return -norm(a, b, cv::NORM_L1);
  58 + }
  59 +};
  60 +
  61 +BR_REGISTER(Distance, TurkDistance)
  62 +
  63 +} // namespace br
  64 +
  65 +#include "distance/turk.moc"
openbr/plugins/distance/unit.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup distances
  24 + * \brief Linear normalizes of a distance so the mean impostor score is 0 and the mean genuine score is 1.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class UnitDistance : public Distance
  28 +{
  29 + Q_OBJECT
  30 + Q_PROPERTY(br::Distance *distance READ get_distance WRITE set_distance RESET reset_distance)
  31 + Q_PROPERTY(float a READ get_a WRITE set_a RESET reset_a)
  32 + Q_PROPERTY(float b READ get_b WRITE set_b RESET reset_b)
  33 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  34 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  35 + BR_PROPERTY(float, a, 1)
  36 + BR_PROPERTY(float, b, 0)
  37 + BR_PROPERTY(QString, inputVariable, "Label")
  38 +
  39 + void train(const TemplateList &templates)
  40 + {
  41 + const TemplateList samples = templates.mid(0, 2000);
  42 + const QList<int> sampleLabels = samples.indexProperty(inputVariable);
  43 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(samples.size()), FileList(samples.size())));
  44 + Distance::compare(samples, samples, matrixOutput.data());
  45 +
  46 + double genuineAccumulator, impostorAccumulator;
  47 + int genuineCount, impostorCount;
  48 + genuineAccumulator = impostorAccumulator = genuineCount = impostorCount = 0;
  49 +
  50 + for (int i=0; i<samples.size(); i++) {
  51 + for (int j=0; j<i; j++) {
  52 + const float val = matrixOutput.data()->data.at<float>(i, j);
  53 + if (sampleLabels[i] == sampleLabels[j]) {
  54 + genuineAccumulator += val;
  55 + genuineCount++;
  56 + } else {
  57 + impostorAccumulator += val;
  58 + impostorCount++;
  59 + }
  60 + }
  61 + }
  62 +
  63 + if (genuineCount == 0) { qWarning("No genuine matches."); return; }
  64 + if (impostorCount == 0) { qWarning("No impostor matches."); return; }
  65 +
  66 + double genuineMean = genuineAccumulator / genuineCount;
  67 + double impostorMean = impostorAccumulator / impostorCount;
  68 +
  69 + if (genuineMean == impostorMean) { qWarning("Genuines and impostors are indistinguishable."); return; }
  70 +
  71 + a = 1.0/(genuineMean-impostorMean);
  72 + b = impostorMean;
  73 +
  74 + qDebug("a = %f, b = %f", a, b);
  75 + }
  76 +
  77 + float compare(const Template &target, const Template &query) const
  78 + {
  79 + return a * (distance->compare(target, query) - b);
  80 + }
  81 +};
  82 +
  83 +BR_REGISTER(Distance, UnitDistance)
  84 +
  85 +} // namespace br
  86 +
  87 +#include "distance/unit.moc"
openbr/plugins/distance/zscore.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/common.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +class ZScoreDistance : public Distance
  24 +{
  25 + Q_OBJECT
  26 + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
  27 + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false)
  28 + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)"))
  29 + BR_PROPERTY(bool, crossModality, false)
  30 +
  31 + float min, max;
  32 + double mean, stddev;
  33 +
  34 + void train(const TemplateList &src)
  35 + {
  36 + distance->train(src);
  37 +
  38 + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
  39 + distance->compare(src, src, matrixOutput.data());
  40 +
  41 + QList<float> scores;
  42 + scores.reserve(src.size()*src.size());
  43 + for (int i=0; i<src.size(); i++) {
  44 + for (int j=0; j<i; j++) {
  45 + const float score = matrixOutput.data()->data.at<float>(i, j);
  46 + if (score == -std::numeric_limits<float>::max()) continue;
  47 + if (crossModality && src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue;
  48 + scores.append(score);
  49 + }
  50 + }
  51 +
  52 + Common::MinMax(scores, &min, &max);
  53 + Common::MeanStdDev(scores, &mean, &stddev);
  54 +
  55 + if (stddev == 0) qFatal("Stddev is 0.");
  56 + }
  57 +
  58 + float compare(const Template &target, const Template &query) const
  59 + {
  60 + float score = distance->compare(target,query);
  61 + if (score == -std::numeric_limits<float>::max()) score = (min - mean) / stddev;
  62 + else if (score == std::numeric_limits<float>::max()) score = (max - mean) / stddev;
  63 + else score = (score - mean) / stddev;
  64 + return score;
  65 + }
  66 +
  67 + void store(QDataStream &stream) const
  68 + {
  69 + distance->store(stream);
  70 + stream << min << max << mean << stddev;
  71 + }
  72 +
  73 + void load(QDataStream &stream)
  74 + {
  75 + distance->load(stream);
  76 + stream >> min >> max >> mean >> stddev;
  77 + }
  78 +};
  79 +
  80 +BR_REGISTER(Distance, ZScoreDistance)
  81 +
  82 +} // namespace br
  83 +
  84 +#include "distance/zscore.moc"
openbr/plugins/draw.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <opencv2/highgui/highgui.hpp>  
18 -#include <opencv2/highgui/highgui_c.h>  
19 -#include <opencv2/imgproc/imgproc.hpp>  
20 -#include <vector>  
21 -#include "openbr_internal.h"  
22 -#include "openbr/core/opencvutils.h"  
23 -  
24 -using namespace cv;  
25 -  
26 -namespace br  
27 -{  
28 -  
29 -/*!  
30 - * \ingroup transforms  
31 - * \brief Renders metadata onto the image.  
32 - *  
33 - * The inPlace argument controls whether or not the image is cloned before the metadata is drawn.  
34 - *  
35 - * \author Josh Klontz \cite jklontz  
36 - */  
37 -class DrawTransform : public UntrainableTransform  
38 -{  
39 - Q_OBJECT  
40 - Q_PROPERTY(bool verbose READ get_verbose WRITE set_verbose RESET reset_verbose STORED false)  
41 - Q_PROPERTY(bool points READ get_points WRITE set_points RESET reset_points STORED false)  
42 - Q_PROPERTY(bool rects READ get_rects WRITE set_rects RESET reset_rects STORED false)  
43 - Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false)  
44 - Q_PROPERTY(int lineThickness READ get_lineThickness WRITE set_lineThickness RESET reset_lineThickness STORED false)  
45 - Q_PROPERTY(bool named READ get_named WRITE set_named RESET reset_named STORED false)  
46 - Q_PROPERTY(bool location READ get_location WRITE set_location RESET reset_location STORED false)  
47 - BR_PROPERTY(bool, verbose, false)  
48 - BR_PROPERTY(bool, points, true)  
49 - BR_PROPERTY(bool, rects, true)  
50 - BR_PROPERTY(bool, inPlace, false)  
51 - BR_PROPERTY(int, lineThickness, 1)  
52 - BR_PROPERTY(bool, named, true)  
53 - BR_PROPERTY(bool, location, true)  
54 -  
55 - void project(const Template &src, Template &dst) const  
56 - {  
57 - const Scalar color(0,255,0);  
58 - const Scalar verboseColor(255, 255, 0);  
59 - dst.m() = inPlace ? src.m() : src.m().clone();  
60 -  
61 - if (points) {  
62 - const QList<Point2f> pointsList = (named) ? OpenCVUtils::toPoints(src.file.points()+src.file.namedPoints()) : OpenCVUtils::toPoints(src.file.points());  
63 - for (int i=0; i<pointsList.size(); i++) {  
64 - const Point2f &point = pointsList[i];  
65 - circle(dst, point, 3, color, -1);  
66 - QString label = (location) ? QString("%1,(%2,%3)").arg(QString::number(i),QString::number(point.x),QString::number(point.y)) : QString("%1").arg(QString::number(i));  
67 - if (verbose) putText(dst, label.toStdString(), point, FONT_HERSHEY_SIMPLEX, 0.5, verboseColor, 1);  
68 - }  
69 - }  
70 - if (rects) {  
71 - foreach (const Rect &rect, OpenCVUtils::toRects(src.file.namedRects() + src.file.rects()))  
72 - rectangle(dst, rect, color, lineThickness);  
73 - }  
74 - }  
75 -};  
76 -  
77 -BR_REGISTER(Transform, DrawTransform)  
78 -  
79 -  
80 -/*!  
81 - * \ingroup transforms  
82 - * \brief Draw the value of the specified property at the specified point on the image  
83 - *  
84 - * The inPlace argument controls whether or not the image is cloned before it is drawn on.  
85 - *  
86 - * \author Charles Otto \cite caotto  
87 - */  
88 -class DrawPropertyPointTransform : public UntrainableTransform  
89 -{  
90 - Q_OBJECT  
91 - Q_PROPERTY(QString propName READ get_propName WRITE set_propName RESET reset_propName STORED false)  
92 - Q_PROPERTY(QString pointName READ get_pointName WRITE set_pointName RESET reset_pointName STORED false)  
93 - Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false)  
94 - BR_PROPERTY(QString, propName, "")  
95 - BR_PROPERTY(QString, pointName, "")  
96 - BR_PROPERTY(bool, inPlace, false)  
97 -  
98 -  
99 - void project(const Template &src, Template &dst) const  
100 - {  
101 - dst = src;  
102 - if (propName.isEmpty() || pointName.isEmpty())  
103 - return;  
104 -  
105 - dst.m() = inPlace ? src.m() : src.m().clone();  
106 -  
107 - const Scalar textColor(255, 255, 0);  
108 -  
109 - QVariant prop = dst.file.value(propName);  
110 -  
111 -  
112 - if (!prop.canConvert(QVariant::String))  
113 - return;  
114 - QString propString = prop.toString();  
115 -  
116 - QVariant point = dst.file.value(pointName);  
117 -  
118 - if (!point.canConvert(QVariant::PointF))  
119 - return;  
120 -  
121 - QPointF targetPoint = point.toPointF();  
122 -  
123 - Point2f cvPoint =OpenCVUtils::toPoint(targetPoint);  
124 -  
125 - std::string text = propName.toStdString() + ": " + propString.toStdString();  
126 - putText(dst, text, cvPoint, FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1);  
127 - }  
128 -  
129 -};  
130 -BR_REGISTER(Transform, DrawPropertyPointTransform)  
131 -  
132 -/*!  
133 - * \ingroup transforms  
134 - * \brief Draw the values of a list of properties at the specified point on the image  
135 - *  
136 - * The inPlace argument controls whether or not the image is cloned before it is drawn on.  
137 - *  
138 - * \author Charles Otto \cite caotto  
139 - */  
140 -class DrawPropertiesPointTransform : public UntrainableTransform  
141 -{  
142 - Q_OBJECT  
143 - Q_PROPERTY(QStringList propNames READ get_propNames WRITE set_propNames RESET reset_propNames STORED false)  
144 - Q_PROPERTY(QString pointName READ get_pointName WRITE set_pointName RESET reset_pointName STORED false)  
145 - Q_PROPERTY(bool inPlace READ get_inPlace WRITE set_inPlace RESET reset_inPlace STORED false)  
146 - BR_PROPERTY(QStringList, propNames, QStringList())  
147 - BR_PROPERTY(QString, pointName, "")  
148 - BR_PROPERTY(bool, inPlace, false)  
149 -  
150 - void project(const Template &src, Template &dst) const  
151 - {  
152 - dst = src;  
153 - if (propNames.isEmpty() || pointName.isEmpty())  
154 - return;  
155 -  
156 - dst.m() = inPlace ? src.m() : src.m().clone();  
157 -  
158 - QVariant point = dst.file.value(pointName);  
159 -  
160 - if (!point.canConvert(QVariant::PointF))  
161 - return;  
162 -  
163 - QPointF targetPoint = point.toPointF();  
164 -  
165 - Point2f cvPoint =OpenCVUtils::toPoint(targetPoint);  
166 -  
167 -  
168 - const Scalar textColor(255, 255, 0);  
169 -  
170 - std::string outString = "";  
171 - foreach (const QString &propName, propNames)  
172 - {  
173 - QVariant prop = dst.file.value(propName);  
174 -  
175 - if (!prop.canConvert(QVariant::String))  
176 - continue;  
177 - QString propString = prop.toString();  
178 - outString += propName.toStdString() + ": " + propString.toStdString() + " ";  
179 -  
180 - }  
181 - if (outString.empty())  
182 - return;  
183 -  
184 - putText(dst, outString, cvPoint, FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1);  
185 - }  
186 -  
187 -};  
188 -BR_REGISTER(Transform, DrawPropertiesPointTransform)  
189 -  
190 -  
191 -/*!  
192 - * \ingroup transforms  
193 - * \brief Draws a grid on the image  
194 - * \author Josh Klontz \cite jklontz  
195 - */  
196 -class DrawGridTransform : public UntrainableTransform  
197 -{  
198 - Q_OBJECT  
199 - Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false)  
200 - Q_PROPERTY(int columns READ get_columns WRITE set_columns RESET reset_columns STORED false)  
201 - Q_PROPERTY(int r READ get_r WRITE set_r RESET reset_r STORED false)  
202 - Q_PROPERTY(int g READ get_g WRITE set_g RESET reset_g STORED false)  
203 - Q_PROPERTY(int b READ get_b WRITE set_b RESET reset_b STORED false)  
204 - BR_PROPERTY(int, rows, 0)  
205 - BR_PROPERTY(int, columns, 0)  
206 - BR_PROPERTY(int, r, 196)  
207 - BR_PROPERTY(int, g, 196)  
208 - BR_PROPERTY(int, b, 196)  
209 -  
210 - void project(const Template &src, Template &dst) const  
211 - {  
212 - Mat m = src.m().clone();  
213 - float rowStep = 1.f * m.rows / (rows+1);  
214 - float columnStep = 1.f * m.cols / (columns+1);  
215 - int thickness = qMin(m.rows, m.cols) / 256;  
216 - for (float row = rowStep/2; row < m.rows; row += rowStep)  
217 - line(m, Point(0, row), Point(m.cols, row), Scalar(r, g, b), thickness, CV_AA);  
218 - for (float column = columnStep/2; column < m.cols; column += columnStep)  
219 - line(m, Point(column, 0), Point(column, m.rows), Scalar(r, g, b), thickness, CV_AA);  
220 - dst = m;  
221 - }  
222 -};  
223 -  
224 -BR_REGISTER(Transform, DrawGridTransform)  
225 -  
226 -/*!  
227 - * \ingroup transforms  
228 - * \brief Computes the mean of a set of templates.  
229 - * \note Suitable for visualization only as it sets every projected template to the mean template.  
230 - * \author Scott Klum \cite sklum  
231 - */  
232 -class MeanTransform : public Transform  
233 -{  
234 - Q_OBJECT  
235 -  
236 - Mat mean;  
237 -  
238 - void train(const TemplateList &data)  
239 - {  
240 - mean = Mat::zeros(data[0].m().rows,data[0].m().cols,CV_32F);  
241 -  
242 - for (int i = 0; i < data.size(); i++) {  
243 - Mat converted;  
244 - data[i].m().convertTo(converted, CV_32F);  
245 - mean += converted;  
246 - }  
247 -  
248 - mean /= data.size();  
249 - }  
250 -  
251 - void project(const Template &src, Template &dst) const  
252 - {  
253 - dst = src;  
254 - dst.m() = mean;  
255 - }  
256 -  
257 -};  
258 -  
259 -BR_REGISTER(Transform, MeanTransform)  
260 -  
261 -/*!  
262 - * \ingroup transforms  
263 - * \brief Load the image named in the specified property, draw it on the current matrix adjacent to the rect specified in the other property.  
264 - * \author Charles Otto \cite caotto  
265 - */  
266 -class AdjacentOverlayTransform : public Transform  
267 -{  
268 - Q_OBJECT  
269 -  
270 - Q_PROPERTY(QString imgName READ get_imgName WRITE set_imgName RESET reset_imgName STORED false)  
271 - Q_PROPERTY(QString targetName READ get_targetName WRITE set_targetName RESET reset_targetName STORED false)  
272 - BR_PROPERTY(QString, imgName, "")  
273 - BR_PROPERTY(QString, targetName, "")  
274 -  
275 - QSharedPointer<Transform> opener;  
276 - void project(const Template &src, Template &dst) const  
277 - {  
278 - dst = src;  
279 -  
280 - if (imgName.isEmpty() || targetName.isEmpty() || !dst.file.contains(imgName) || !dst.file.contains(targetName))  
281 - return;  
282 -  
283 - QVariant temp = src.file.value(imgName);  
284 - cv::Mat im;  
285 - // is this a filename?  
286 - if (temp.canConvert<QString>()) {  
287 - QString im_name = temp.toString();  
288 - Template temp_im;  
289 - opener->project(File(im_name), temp_im);  
290 - im = temp_im.m();  
291 - }  
292 - // a cv::Mat ?  
293 - else if (temp.canConvert<cv::Mat>())  
294 - im = src.file.get<cv::Mat>(imgName);  
295 - else  
296 - qDebug() << "Unrecognized property type " << imgName << "for" << src.file.name;  
297 -  
298 - // Location of detected face in source image  
299 - QRectF target_location = src.file.get<QRectF>(targetName);  
300 -  
301 - // match width with target region  
302 - qreal target_width = target_location.width();  
303 - qreal current_width = im.cols;  
304 - qreal current_height = im.rows;  
305 -  
306 - qreal aspect_ratio = current_height / current_width;  
307 - qreal target_height = target_width * aspect_ratio;  
308 -  
309 - cv::resize(im, im, cv::Size(target_width, target_height));  
310 -  
311 - // ROI used to maybe crop the matched image  
312 - cv::Rect clip_roi;  
313 - clip_roi.x = 0;  
314 - clip_roi.y = 0;  
315 - clip_roi.width = im.cols;  
316 - clip_roi.height= im.rows <= dst.m().rows ? im.rows : dst.m().rows;  
317 -  
318 - int half_width = src.m().cols / 2;  
319 - int out_x = 0;  
320 -  
321 - // place in the source image we will copy the matched image to.  
322 - cv::Rect target_roi;  
323 - bool left_side = false;  
324 - int width_adjust = 0;  
325 - // Place left  
326 - if (target_location.center().rx() > half_width) {  
327 - out_x = target_location.left() - im.cols;  
328 - if (out_x < 0) {  
329 - width_adjust = abs(out_x);  
330 - out_x = 0;  
331 - }  
332 - left_side = true;  
333 - }  
334 - // place right  
335 - else {  
336 - out_x = target_location.right();  
337 - int high = out_x + im.cols;  
338 - if (high >= src.m().cols) {  
339 - width_adjust = abs(high - src.m().cols + 1);  
340 - }  
341 - }  
342 -  
343 - cv::Mat outIm;  
344 - if (width_adjust)  
345 - {  
346 - outIm.create(dst.m().rows, dst.m().cols + width_adjust, CV_8UC3);  
347 - memset(outIm.data, 127, outIm.rows * outIm.cols * outIm.channels());  
348 -  
349 - Rect temp;  
350 -  
351 - if (left_side)  
352 - temp = Rect(abs(width_adjust), 0, dst.m().cols, dst.m().rows);  
353 -  
354 - else  
355 - temp = Rect(0, 0, dst.m().cols, dst.m().rows);  
356 -  
357 - dst.m().copyTo(outIm(temp));  
358 -  
359 - }  
360 - else  
361 - outIm = dst.m();  
362 -  
363 - if (clip_roi.height + target_location.top() >= outIm.rows)  
364 - {  
365 - clip_roi.height -= abs(outIm.rows - (clip_roi.height + target_location.top() ));  
366 - }  
367 - if (clip_roi.x + clip_roi.width >= im.cols) {  
368 - clip_roi.width -= abs(im.cols - (clip_roi.x + clip_roi.width + 1));  
369 - if (clip_roi.width < 0)  
370 - clip_roi.width = 1;  
371 - }  
372 -  
373 - if (clip_roi.y + clip_roi.height >= im.rows) {  
374 - clip_roi.height -= abs(im.rows - (clip_roi.y + clip_roi.height + 1));  
375 - }  
376 - if (clip_roi.x < 0)  
377 - clip_roi.x = 0;  
378 - if (clip_roi.y < 0)  
379 - clip_roi.y = 0;  
380 -  
381 - if (clip_roi.height < 0)  
382 - clip_roi.height = 0;  
383 -  
384 - if (clip_roi.width < 0)  
385 - clip_roi.width = 0;  
386 -  
387 -  
388 - if (clip_roi.y + clip_roi.height >= im.rows)  
389 - {  
390 - qDebug() << "Bad clip y" << clip_roi.y + clip_roi.height << im.rows;  
391 - }  
392 - if (clip_roi.x + clip_roi.width >= im.cols)  
393 - {  
394 - qDebug() << "Bad clip x" << clip_roi.x + clip_roi.width << im.cols;  
395 - }  
396 -  
397 - if (clip_roi.y < 0 || clip_roi.height < 0)  
398 - {  
399 - qDebug() << "bad clip y, low" << clip_roi.y << clip_roi.height;  
400 - qFatal("die");  
401 - }  
402 - if (clip_roi.x < 0 || clip_roi.width < 0)  
403 - {  
404 - qDebug() << "bad clip x, low" << clip_roi.x << clip_roi.width;  
405 - qFatal("die");  
406 - }  
407 -  
408 - target_roi.x = out_x;  
409 - target_roi.width = clip_roi.width;  
410 - target_roi.y = target_location.top();  
411 - target_roi.height = clip_roi.height;  
412 -  
413 -  
414 - im = im(clip_roi);  
415 -  
416 - if (target_roi.x < 0 || target_roi.x >= outIm.cols)  
417 - {  
418 - qDebug() << "Bad xdim in targetROI!" << target_roi.x << " out im x: " << outIm.cols;  
419 - qFatal("die");  
420 - }  
421 -  
422 - if (target_roi.x + target_roi.width < 0 || (target_roi.x + target_roi.width) >= outIm.cols)  
423 - {  
424 - qDebug() << "Bad xdim in targetROI!" << target_roi.x + target_roi.width;  
425 - qFatal("die");  
426 - }  
427 -  
428 - if (target_roi.y < 0 || target_roi.y >= outIm.rows)  
429 - {  
430 - qDebug() << "Bad ydim in targetROI!" << target_roi.y;  
431 - qFatal("die");  
432 - }  
433 -  
434 - if ((target_roi.y + target_roi.height) < 0 || (target_roi.y + target_roi.height) > outIm.rows)  
435 - {  
436 - qDebug() << "Bad ydim in targetROI!" << target_roi.y + target_roi.height;  
437 - qDebug() << "target_roi.y: " << target_roi.y << " height: " << target_roi.height;  
438 - qFatal("die");  
439 - }  
440 -  
441 -  
442 - std::vector<cv::Mat> channels;  
443 - cv::split(outIm, channels);  
444 -  
445 - std::vector<cv::Mat> patch_channels;  
446 - cv::split(im, patch_channels);  
447 -  
448 - for (size_t i=0; i < channels.size(); i++)  
449 - {  
450 - cv::addWeighted(channels[i](target_roi), 0, patch_channels[i % patch_channels.size()], 1, 0,channels[i](target_roi));  
451 - }  
452 - cv::merge(channels, outIm);  
453 - dst.m() = outIm;  
454 -  
455 - }  
456 -  
457 - void init()  
458 - {  
459 - opener = QSharedPointer<br::Transform>(br::Transform::make("Cache(Open)", NULL));  
460 - }  
461 -  
462 -};  
463 -  
464 -BR_REGISTER(Transform, AdjacentOverlayTransform)  
465 -  
466 -/*!  
467 - * \ingroup transforms  
468 - * \brief Draw a line representing the direction and magnitude of optical flow at the specified points.  
469 - * \author Austin Blanton \cite imaus10  
470 - */  
471 -class DrawOpticalFlow : public UntrainableTransform  
472 -{  
473 - Q_OBJECT  
474 - Q_PROPERTY(QString original READ get_original WRITE set_original RESET reset_original STORED false)  
475 - BR_PROPERTY(QString, original, "original")  
476 -  
477 - void project(const Template &src, Template &dst) const  
478 - {  
479 - const Scalar color(0,255,0);  
480 - Mat flow = src.m();  
481 - dst = src;  
482 - if (!dst.file.contains(original)) qFatal("The original img must be saved in the metadata with SaveMat.");  
483 - dst.m() = dst.file.get<Mat>(original);  
484 - dst.file.remove(original);  
485 - foreach (const Point2f &pt, OpenCVUtils::toPoints(dst.file.points())) {  
486 - Point2f dxy = flow.at<Point2f>(pt.y, pt.x);  
487 - Point2f newPt(pt.x+dxy.x, pt.y+dxy.y);  
488 - line(dst, pt, newPt, color);  
489 - }  
490 - }  
491 -};  
492 -BR_REGISTER(Transform, DrawOpticalFlow)  
493 -  
494 -/*!  
495 - * \ingroup transforms  
496 - * \brief Fill in the segmentations or draw a line between intersecting segments.  
497 - * \author Austin Blanton \cite imaus10  
498 - */  
499 -class DrawSegmentation : public UntrainableTransform  
500 -{  
501 - Q_OBJECT  
502 - Q_PROPERTY(bool fillSegment READ get_fillSegment WRITE set_fillSegment RESET reset_fillSegment STORED false)  
503 - BR_PROPERTY(bool, fillSegment, true)  
504 -  
505 - void project(const Template &src, Template &dst) const  
506 - {  
507 - if (!src.file.contains("SegmentsMask") || !src.file.contains("NumSegments")) qFatal("Must supply a Contours object in the metadata to drawContours.");  
508 - Mat segments = src.file.get<Mat>("SegmentsMask");  
509 - int numSegments = src.file.get<int>("NumSegments");  
510 -  
511 - dst.file = src.file;  
512 - Mat drawn = fillSegment ? Mat(segments.size(), CV_8UC3, Scalar::all(0)) : src.m();  
513 -  
514 - for (int i=1; i<numSegments+1; i++) {  
515 - Mat mask = segments == i;  
516 - if (fillSegment) { // color the whole segment  
517 - // set to a random color - get ready for a craaaazy acid trip  
518 - int b = theRNG().uniform(0, 255);  
519 - int g = theRNG().uniform(0, 255);  
520 - int r = theRNG().uniform(0, 255);  
521 - drawn.setTo(Scalar(r,g,b), mask);  
522 - } else { // draw lines where there's a color change  
523 - vector<vector<Point> > contours;  
524 - Scalar color(0,255,0);  
525 - findContours(mask, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);  
526 - drawContours(drawn, contours, -1, color);  
527 - }  
528 - }  
529 -  
530 - dst.m() = drawn;  
531 - }  
532 -};  
533 -BR_REGISTER(Transform, DrawSegmentation)  
534 -  
535 -/*!  
536 - * \ingroup transforms  
537 - * \brief Write all mats to disk as images.  
538 - * \author Brendan Klare \cite bklare  
539 - */  
540 -class WriteImageTransform : public TimeVaryingTransform  
541 -{  
542 - Q_OBJECT  
543 - Q_PROPERTY(QString outputDirectory READ get_outputDirectory WRITE set_outputDirectory RESET reset_outputDirectory STORED false)  
544 - Q_PROPERTY(QString imageName READ get_imageName WRITE set_imageName RESET reset_imageName STORED false)  
545 - Q_PROPERTY(QString imgExtension READ get_imgExtension WRITE set_imgExtension RESET reset_imgExtension STORED false)  
546 - BR_PROPERTY(QString, outputDirectory, "Temp")  
547 - BR_PROPERTY(QString, imageName, "image")  
548 - BR_PROPERTY(QString, imgExtension, "jpg")  
549 -  
550 - int cnt;  
551 -  
552 - void init() {  
553 - cnt = 0;  
554 - if (! QDir(outputDirectory).exists())  
555 - QDir().mkdir(outputDirectory);  
556 - }  
557 -  
558 - void projectUpdate(const Template &src, Template &dst)  
559 - {  
560 - dst = src;  
561 - OpenCVUtils::saveImage(dst.m(), QString("%1/%2_%3.%4").arg(outputDirectory).arg(imageName).arg(cnt++, 5, 10, QChar('0')).arg(imgExtension));  
562 - }  
563 -  
564 -};  
565 -BR_REGISTER(Transform, WriteImageTransform)  
566 -  
567 -  
568 -/**  
569 - * @brief The MeanImageTransform class computes the average template/image  
570 - * and save the result as an encoded image.  
571 - */  
572 -class MeanImageTransform : public TimeVaryingTransform  
573 -{  
574 - Q_OBJECT  
575 -  
576 - Q_PROPERTY(QString imgname READ get_imgname WRITE set_imgname RESET reset_imgname STORED false)  
577 - Q_PROPERTY(QString ext READ get_ext WRITE set_ext RESET reset_ext STORED false)  
578 -  
579 - BR_PROPERTY(QString, imgname, "average")  
580 - BR_PROPERTY(QString, ext, "jpg")  
581 -  
582 - Mat average;  
583 - int cnt;  
584 -  
585 - void init()  
586 - {  
587 - cnt = 0;  
588 - }  
589 -  
590 - void projectUpdate(const Template &src, Template &dst)  
591 - {  
592 - dst = src;  
593 - if (cnt == 0) {  
594 - if (src.m().channels() == 1)  
595 - average = Mat::zeros(dst.m().size(),CV_64FC1);  
596 - else if (src.m().channels() == 3)  
597 - average = Mat::zeros(dst.m().size(),CV_64FC3);  
598 - else  
599 - qFatal("Unsupported number of channels");  
600 - }  
601 -  
602 - Mat temp;  
603 - if (src.m().channels() == 1) {  
604 - src.m().convertTo(temp, CV_64FC1);  
605 - average += temp;  
606 - } else if (src.m().channels() == 3) {  
607 - src.m().convertTo(temp, CV_64FC3);  
608 - average += temp;  
609 - } else  
610 - qFatal("Unsupported number of channels");  
611 -  
612 - cnt++;  
613 - }  
614 -  
615 - virtual void finalize(TemplateList &output)  
616 - {  
617 - average /= float(cnt);  
618 - imwrite(QString("%1.%2").arg(imgname).arg(ext).toStdString(), average);  
619 - output = TemplateList();  
620 - }  
621 -  
622 -  
623 -public:  
624 - MeanImageTransform() : TimeVaryingTransform(false, false) {}  
625 -};  
626 -  
627 -BR_REGISTER(Transform, MeanImageTransform)  
628 -  
629 -  
630 -// TODO: re-implement EditTransform using Qt  
631 -#if 0  
632 -/*!  
633 - * \ingroup transforms  
634 - * \brief Remove landmarks.  
635 - * \author Josh Klontz \cite jklontz  
636 - */  
637 -class EditTransform : public UntrainableTransform  
638 -{  
639 - Q_OBJECT  
640 -  
641 - Transform *draw;  
642 - static Template currentTemplate;  
643 - static QMutex currentTemplateLock;  
644 -  
645 - void init()  
646 - {  
647 - draw = make("Draw");  
648 - Globals->setProperty("parallelism", "0"); // Can only work in single threaded mode  
649 - }  
650 -  
651 - void project(const Template &src, Template &dst) const  
652 - {  
653 - dst = src;  
654 -  
655 - if (Globals->parallelism) {  
656 - qWarning("Edit::project() only works in single threaded mode.");  
657 - return;  
658 - }  
659 -  
660 - currentTemplateLock.lock();  
661 - currentTemplate = src;  
662 - OpenCVUtils::showImage(src, "Edit", false);  
663 - setMouseCallback("Edit", mouseCallback, (void*)this);  
664 - mouseEvent(0, 0, 0, 0);  
665 - waitKey(-1);  
666 - dst = currentTemplate;  
667 - currentTemplateLock.unlock();  
668 - }  
669 -  
670 - static void mouseCallback(int event, int x, int y, int flags, void *userdata)  
671 - {  
672 - ((const EditTransform*)userdata)->mouseEvent(event, x, y, flags);  
673 - }  
674 -  
675 - void mouseEvent(int event, int x, int y, int flags) const  
676 - {  
677 - (void) event;  
678 - if (flags) {  
679 - QList<QRectF> rects = currentTemplate.file.rects();  
680 - for (int i=rects.size()-1; i>=0; i--)  
681 - if (rects[i].contains(x,y))  
682 - rects.removeAt(i);  
683 - currentTemplate.file.setRects(rects);  
684 - }  
685 -  
686 - Template temp;  
687 - draw->project(currentTemplate, temp);  
688 - OpenCVUtils::showImage(temp, "Edit", false);  
689 - }  
690 -};  
691 -  
692 -Template EditTransform::currentTemplate;  
693 -QMutex EditTransform::currentTemplateLock;  
694 -  
695 -BR_REGISTER(Transform, EditTransform)  
696 -#endif  
697 -  
698 -} // namespace br  
699 -  
700 -#include "draw.moc"  
openbr/plugins/eigen3.cmake deleted
1 -set(BR_WITH_EIGEN3 ON CACHE BOOL "Build Eigen3 plugins")  
2 -  
3 -if(${BR_WITH_EIGEN3})  
4 - find_package(Eigen3 REQUIRED)  
5 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/eigen3.cpp)  
6 - install(FILES ${EIGEN3_LICENSE} RENAME Eigen3 DESTINATION share/openbr/licenses)  
7 -endif()  
openbr/plugins/filter.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <opencv2/imgproc/imgproc.hpp>  
18 -#include "openbr_internal.h"  
19 -#include "openbr/core/tanh_sse.h"  
20 -  
21 -using namespace cv;  
22 -  
23 -namespace br  
24 -{  
25 -  
26 -/*!  
27 - * \ingroup transforms  
28 - * \brief Gamma correction  
29 - * \author Josh Klontz \cite jklontz  
30 - */  
31 -class GammaTransform : public UntrainableTransform  
32 -{  
33 - Q_OBJECT  
34 - Q_PROPERTY(float gamma READ get_gamma WRITE set_gamma RESET reset_gamma STORED false)  
35 - BR_PROPERTY(float, gamma, 0.2)  
36 -  
37 - Mat lut;  
38 -  
39 - void init()  
40 - {  
41 - lut.create(256, 1, CV_32FC1);  
42 - if (gamma == 0) for (int i=0; i<256; i++) lut.at<float>(i,0) = log((float)i);  
43 - else for (int i=0; i<256; i++) lut.at<float>(i,0) = pow(i, gamma);  
44 - }  
45 -  
46 - void project(const Template &src, Template &dst) const  
47 - {  
48 - if (src.m().depth() == CV_8U) LUT(src, lut, dst);  
49 - else pow(src, gamma, dst);  
50 - }  
51 -};  
52 -  
53 -BR_REGISTER(Transform, GammaTransform)  
54 -  
55 -/*!  
56 - * \ingroup transforms  
57 - * \brief Gaussian blur  
58 - * \author Josh Klontz \cite jklontz  
59 - */  
60 -class BlurTransform : public UntrainableTransform  
61 -{  
62 - Q_OBJECT  
63 - Q_PROPERTY(float sigma READ get_sigma WRITE set_sigma RESET reset_sigma STORED false)  
64 - Q_PROPERTY(bool ROI READ get_ROI WRITE set_ROI RESET reset_ROI STORED false)  
65 - BR_PROPERTY(float, sigma, 1)  
66 - BR_PROPERTY(bool, ROI, false)  
67 -  
68 - void project(const Template &src, Template &dst) const  
69 - {  
70 - if (!ROI) GaussianBlur(src, dst, Size(0,0), sigma);  
71 - else {  
72 - dst.m() = src.m();  
73 - foreach (const QRectF &rect, src.file.rects()) {  
74 - Rect region(rect.x(), rect.y(), rect.width(), rect.height());  
75 - Mat input = dst.m();  
76 - Mat output = input.clone();  
77 - GaussianBlur(input(region), output(region), Size(0,0), sigma);  
78 - dst.m() = output;  
79 - }  
80 - }  
81 - }  
82 -};  
83 -  
84 -BR_REGISTER(Transform, BlurTransform)  
85 -  
86 -/*!  
87 - * \ingroup transforms  
88 - * \brief Difference of gaussians  
89 - * \author Josh Klontz \cite jklontz  
90 - */  
91 -class DoGTransform : public UntrainableTransform  
92 -{  
93 - Q_OBJECT  
94 - Q_PROPERTY(float sigma0 READ get_sigma0 WRITE set_sigma0 RESET reset_sigma0 STORED false)  
95 - Q_PROPERTY(float sigma1 READ get_sigma1 WRITE set_sigma1 RESET reset_sigma1 STORED false)  
96 - BR_PROPERTY(float, sigma0, 1)  
97 - BR_PROPERTY(float, sigma1, 2)  
98 -  
99 - Size ksize0, ksize1;  
100 -  
101 - static Size getKernelSize(double sigma)  
102 - {  
103 - // Inverts OpenCV's conversion from kernel size to sigma:  
104 - // sigma = ((ksize-1)*0.5 - 1)*0.3 + 0.8  
105 - // See documentation for cv::getGaussianKernel()  
106 - int ksize = ((sigma - 0.8) / 0.3 + 1) * 2 + 1;  
107 - if (ksize % 2 == 0) ksize++;  
108 - return Size(ksize, ksize);  
109 - }  
110 -  
111 - void init()  
112 - {  
113 - ksize0 = getKernelSize(sigma0);  
114 - ksize1 = getKernelSize(sigma1);  
115 - }  
116 -  
117 - void project(const Template &src, Template &dst) const  
118 - {  
119 - Mat g0, g1;  
120 - GaussianBlur(src, g0, ksize0, 0);  
121 - GaussianBlur(src, g1, ksize1, 0);  
122 - subtract(g0, g1, dst);  
123 - }  
124 -};  
125 -  
126 -BR_REGISTER(Transform, DoGTransform)  
127 -  
128 -/*!  
129 - * \ingroup transforms  
130 - * \brief Meyers, E.; Wolf, L.  
131 - * “Using biologically inspired features for face processing,”  
132 - * Int. Journal of Computer Vision, vol. 76, no. 1, pp 93–104, 2008.  
133 - * \author Scott Klum \cite sklum  
134 - */  
135 -  
136 -class CSDNTransform : public UntrainableTransform  
137 -{  
138 - Q_OBJECT  
139 -  
140 - Q_PROPERTY(float s READ get_s WRITE set_s RESET reset_s STORED false)  
141 - BR_PROPERTY(int, s, 16)  
142 -  
143 - void project(const Template &src, Template &dst) const  
144 - {  
145 - if (src.m().channels() != 1) qFatal("Expected single channel source matrix.");  
146 -  
147 - const int nRows = src.m().rows;  
148 - const int nCols = src.m().cols;  
149 -  
150 - Mat m;  
151 - src.m().convertTo(m, CV_32FC1);  
152 -  
153 - const int surround = s/2;  
154 -  
155 - for ( int i = 0; i < nRows; i++ ) {  
156 - for ( int j = 0; j < nCols; j++ ) {  
157 - int width = min( j+surround, nCols ) - max( 0, j-surround );  
158 - int height = min( i+surround, nRows ) - max( 0, i-surround );  
159 -  
160 - Rect_<int> ROI(max(0, j-surround), max(0, i-surround), width, height);  
161 -  
162 - Scalar_<float> avg = mean(m(ROI));  
163 -  
164 - m.at<float>(i,j) = m.at<float>(i,j) - avg[0];  
165 - }  
166 - }  
167 -  
168 - dst = m;  
169 -  
170 - }  
171 -};  
172 -  
173 -BR_REGISTER(Transform, CSDNTransform)  
174 -  
175 -/*!  
176 - * \ingroup transforms  
177 - * \brief Xiaoyang Tan; Triggs, B.;  
178 - * "Enhanced Local Texture Feature Sets for Face Recognition Under Difficult Lighting Conditions,"  
179 - * Image Processing, IEEE Transactions on , vol.19, no.6, pp.1635-1650, June 2010  
180 - * \author Josh Klontz \cite jklontz  
181 - */  
182 -class ContrastEqTransform : public UntrainableTransform  
183 -{  
184 - Q_OBJECT  
185 - Q_PROPERTY(float a READ get_a WRITE set_a RESET reset_a STORED false)  
186 - Q_PROPERTY(float t READ get_t WRITE set_t RESET reset_t STORED false)  
187 - BR_PROPERTY(float, a, 1)  
188 - BR_PROPERTY(float, t, 0.1)  
189 -  
190 - void project(const Template &src, Template &dst) const  
191 - {  
192 - if (src.m().channels() != 1) qFatal("Expected single channel source matrix.");  
193 -  
194 - // Stage 1  
195 - Mat stage1;  
196 - {  
197 - Mat abs_dst;  
198 - absdiff(src, Scalar(0), abs_dst);  
199 - Mat pow_dst;  
200 - pow(abs_dst, a, pow_dst);  
201 - float denominator = pow((float)mean(pow_dst)[0], 1.f/a);  
202 - src.m().convertTo(stage1, CV_32F, 1/denominator);  
203 - }  
204 -  
205 - // Stage 2  
206 - Mat stage2;  
207 - {  
208 - Mat abs_dst;  
209 - absdiff(stage1, Scalar(0), abs_dst);  
210 - Mat min_dst;  
211 - min(abs_dst, t, min_dst);  
212 - Mat pow_dst;  
213 - pow(min_dst, a, pow_dst);  
214 - float denominator = pow((float)mean(pow_dst)[0], 1.f/a);  
215 - stage1.convertTo(stage2, CV_32F, 1/denominator);  
216 - }  
217 -  
218 - // Hyperbolic tangent  
219 - const int nRows = src.m().rows;  
220 - const int nCols = src.m().cols;  
221 - const float* p = (const float*)stage2.ptr();  
222 - Mat m(nRows, nCols, CV_32FC1);  
223 - for (int i=0; i<nRows; i++)  
224 - for (int j=0; j<nCols; j++)  
225 - m.at<float>(i, j) = fast_tanh(p[i*nCols+j]);  
226 - // TODO: m.at<float>(i, j) = t * fast_tanh(p[i*nCols+j] / t);  
227 -  
228 - dst = m;  
229 - }  
230 -};  
231 -  
232 -BR_REGISTER(Transform, ContrastEqTransform)  
233 -  
234 -/*!  
235 - * \ingroup transforms  
236 - * \brief Raise each element to the specified power.  
237 - * \author Josh Klontz \cite jklontz  
238 - */  
239 -class PowTransform : public UntrainableTransform  
240 -{  
241 - Q_OBJECT  
242 - Q_PROPERTY(float power READ get_power WRITE set_power RESET reset_power STORED false)  
243 - Q_PROPERTY(bool preserveSign READ get_preserveSign WRITE set_preserveSign RESET reset_preserveSign STORED false)  
244 - BR_PROPERTY(float, power, 2)  
245 - BR_PROPERTY(bool, preserveSign, false)  
246 -  
247 - void project(const Template &src, Template &dst) const  
248 - {  
249 - pow(preserveSign ? abs(src) : src.m(), power, dst);  
250 - if (preserveSign) subtract(Scalar::all(0), dst, dst, src.m() < 0);  
251 - }  
252 -};  
253 -  
254 -BR_REGISTER(Transform, PowTransform)  
255 -  
256 -} // namespace br  
257 -  
258 -#include "filter.moc"  
openbr/plugins/format.cpp deleted
1 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  
2 - * Copyright 2012 The MITRE Corporation *  
3 - * *  
4 - * Licensed under the Apache License, Version 2.0 (the "License"); *  
5 - * you may not use this file except in compliance with the License. *  
6 - * You may obtain a copy of the License at *  
7 - * *  
8 - * http://www.apache.org/licenses/LICENSE-2.0 *  
9 - * *  
10 - * Unless required by applicable law or agreed to in writing, software *  
11 - * distributed under the License is distributed on an "AS IS" BASIS, *  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  
13 - * See the License for the specific language governing permissions and *  
14 - * limitations under the License. *  
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
16 -  
17 -#include <QDate>  
18 -#include <QSize>  
19 -#include <QChar>  
20 -#ifndef BR_EMBEDDED  
21 -#include <QtXml>  
22 -#endif // BR_EMBEDDED  
23 -#include <QFile>  
24 -#include <QFileInfo>  
25 -  
26 -#include <opencv2/highgui/highgui.hpp>  
27 -#include <opencv2/highgui/highgui_c.h>  
28 -#include "openbr_internal.h"  
29 -  
30 -#include "openbr/core/bee.h"  
31 -#include "openbr/core/opencvutils.h"  
32 -#include "openbr/core/qtutils.h"  
33 -  
34 -using namespace cv;  
35 -  
36 -namespace br  
37 -{  
38 -  
39 - /*!  
40 - * \ingroup formats  
41 - * \brief Read all frames of a video using OpenCV  
42 - * \author Charles Otto \cite caotto  
43 - */  
44 -class videoFormat : public Format  
45 -{  
46 - Q_OBJECT  
47 -  
48 -public:  
49 - Template read() const  
50 - {  
51 - if (!file.exists() )  
52 - return Template();  
53 -  
54 - VideoCapture videoSource(file.name.toStdString());  
55 - videoSource.open(file.name.toStdString() );  
56 -  
57 -  
58 - Template frames;  
59 - if (!videoSource.isOpened()) {  
60 - qWarning("video file open failed");  
61 - return frames;  
62 - }  
63 -  
64 - bool open = true;  
65 - while (open) {  
66 - cv::Mat frame;  
67 - open = videoSource.read(frame);  
68 - if (!open) break;  
69 -  
70 - frames.append(cv::Mat());  
71 - frames.back() = frame.clone();  
72 - }  
73 -  
74 - return frames;  
75 - }  
76 -  
77 - void write(const Template &t) const  
78 - {  
79 - int fourcc = OpenCVUtils::getFourcc();  
80 - VideoWriter videoSink(file.name.toStdString(), fourcc, 30, t.begin()->size());  
81 -  
82 - // Did we successfully open the output file?  
83 - if (!videoSink.isOpened() ) qFatal("Failed to open output file");  
84 -  
85 - for (Template::const_iterator it = t.begin(); it!= t.end(); ++it) {  
86 - videoSink << *it;  
87 - }  
88 - }  
89 -};  
90 -  
91 -BR_REGISTER(Format, videoFormat)  
92 -  
93 -/*!  
94 - * \ingroup formats  
95 - * \brief A simple binary matrix format.  
96 - * \author Josh Klontz \cite jklontz  
97 - * First 4 bytes indicate the number of rows.  
98 - * Second 4 bytes indicate the number of columns.  
99 - * The rest of the bytes are 32-bit floating data elements in row-major order.  
100 - */  
101 -class binFormat : public Format  
102 -{  
103 - Q_OBJECT  
104 - Q_PROPERTY(bool raw READ get_raw WRITE set_raw RESET reset_raw STORED false)  
105 - BR_PROPERTY(bool, raw, false)  
106 -  
107 - Template read() const  
108 - {  
109 - QByteArray data;  
110 - QtUtils::readFile(file, data);  
111 - if (raw) {  
112 - return Template(file, Mat(1, data.size(), CV_8UC1, data.data()).clone());  
113 - } else {  
114 - return Template(file, Mat(((quint32*)data.data())[0],  
115 - ((quint32*)data.data())[1],  
116 - CV_32FC1,  
117 - data.data()+8).clone());  
118 - }  
119 - }  
120 -  
121 - void write(const Template &t) const  
122 - {  
123 - QFile f(file);  
124 - QtUtils::touchDir(f);  
125 - if (!f.open(QFile::WriteOnly))  
126 - qFatal("Failed to open %s for writing.", qPrintable(file));  
127 -  
128 - Mat m;  
129 - if (!raw) {  
130 - if (t.m().type() != CV_32FC1)  
131 - t.m().convertTo(m, CV_32F);  
132 - else m = t.m();  
133 -  
134 - if (m.channels() != 1) qFatal("Only supports single channel matrices.");  
135 -  
136 - f.write((const char *) &m.rows, 4);  
137 - f.write((const char *) &m.cols, 4);  
138 - }  
139 - else m = t.m();  
140 -  
141 - qint64 rowSize = m.cols * sizeof(float);  
142 - for (int i=0; i < m.rows; i++)  
143 - {  
144 - f.write((const char *) m.row(i).data, rowSize);  
145 - }  
146 - f.close();  
147 - }  
148 -};  
149 -  
150 -BR_REGISTER(Format, binFormat)  
151 -  
152 -/*!  
153 - * \ingroup formats  
154 - * \brief Reads a comma separated value file.  
155 - * \author Josh Klontz \cite jklontz  
156 - */  
157 -class csvFormat : public Format  
158 -{  
159 - Q_OBJECT  
160 -  
161 - Template read() const  
162 - {  
163 - QFile f(file.name);  
164 - f.open(QFile::ReadOnly);  
165 - QStringList lines(QString(f.readAll()).split(QRegularExpression("[\n|\r\n|\r]"), QString::SkipEmptyParts));  
166 - f.close();  
167 -  
168 - bool isUChar = true;  
169 - QList< QList<float> > valsList;  
170 - foreach (const QString &line, lines) {  
171 - QList<float> vals;  
172 - foreach (const QString &word, line.split(QRegExp(" *, *"), QString::SkipEmptyParts)) {  
173 - bool ok;  
174 - const float val = word.toFloat(&ok);  
175 - vals.append(val);  
176 - isUChar = isUChar && (val == float(uchar(val)));  
177 - }  
178 - if (!vals.isEmpty())  
179 - valsList.append(vals);  
180 - }  
181 -  
182 - Mat m(valsList.size(), valsList[0].size(), CV_32FC1);  
183 - for (int i=0; i<valsList.size(); i++)  
184 - for (int j=0; j<valsList[i].size(); j++)  
185 - m.at<float>(i,j) = valsList[i][j];  
186 -  
187 - if (isUChar) m.convertTo(m, CV_8U);  
188 - return Template(m);  
189 - }  
190 -  
191 - void write(const Template &t) const  
192 - {  
193 - const Mat &m = t.m();  
194 - if (t.size() != 1) qFatal("Only supports single matrix templates.");  
195 - if (m.channels() != 1) qFatal("Only supports single channel matrices.");  
196 -  
197 - QStringList lines; lines.reserve(m.rows);  
198 - for (int r=0; r<m.rows; r++) {  
199 - QStringList elements; elements.reserve(m.cols);  
200 - for (int c=0; c<m.cols; c++)  
201 - elements.append(OpenCVUtils::elemToString(m, r, c));  
202 - lines.append(elements.join(","));  
203 - }  
204 -  
205 - QtUtils::writeFile(file, lines);  
206 - }  
207 -};  
208 -  
209 -BR_REGISTER(Format, csvFormat)  
210 -  
211 -/*!  
212 - * \ingroup formats  
213 - * \brief Reads image files.  
214 - * \author Josh Klontz \cite jklontz  
215 - */  
216 -class DefaultFormat : public Format  
217 -{  
218 - Q_OBJECT  
219 -  
220 - Template read() const  
221 - {  
222 - Template t;  
223 -  
224 - if (file.name.startsWith("http://") || file.name.startsWith("https://") || file.name.startsWith("www.")) {  
225 - if (Factory<Format>::names().contains("url")) {  
226 - File urlFile = file;  
227 - urlFile.name.append(".url");  
228 - QScopedPointer<Format> url(Factory<Format>::make(urlFile));  
229 - t = url->read();  
230 - }  
231 - } else {  
232 - Mat m = imread(file.resolved().toStdString());  
233 - if (m.data) {  
234 - t.append(m);  
235 - } else {  
236 - videoFormat videoReader;  
237 - videoReader.file = file;  
238 - t = videoReader.read();  
239 - }  
240 - }  
241 -  
242 - return t;  
243 - }  
244 -  
245 - void write(const Template &t) const  
246 - {  
247 - if (t.size() > 1) {  
248 - videoFormat videoWriter;  
249 - videoWriter.file = file;  
250 - videoWriter.write(t);  
251 - } else if (t.size() == 1) {  
252 - QtUtils::touchDir(QDir(file.path()));  
253 - imwrite(file.name.toStdString(), t);  
254 - }  
255 - }  
256 -};  
257 -  
258 -BR_REGISTER(Format, DefaultFormat)  
259 -  
260 -/*!  
261 - * \ingroup formats  
262 - * \brief Reads a NIST LFFS file.  
263 - * \author Josh Klontz \cite jklontz  
264 - */  
265 -class lffsFormat : public Format  
266 -{  
267 - Q_OBJECT  
268 -  
269 - Template read() const  
270 - {  
271 - QByteArray byteArray;  
272 - QtUtils::readFile(file.name, byteArray);  
273 - return Mat(1, byteArray.size(), CV_8UC1, byteArray.data()).clone();  
274 - }  
275 -  
276 - void write(const Template &t) const  
277 - {  
278 - QByteArray byteArray((const char*)t.m().data, t.m().total()*t.m().elemSize());  
279 - QtUtils::writeFile(file.name, byteArray);  
280 - }  
281 -};  
282 -  
283 -BR_REGISTER(Format, lffsFormat)  
284 -  
285 -/*!  
286 - * \ingroup formats  
287 - * \brief Reads a NIST BEE similarity matrix.  
288 - * \author Josh Klontz \cite jklontz  
289 - */  
290 -class mtxFormat : public Format  
291 -{  
292 - Q_OBJECT  
293 -  
294 - Template read() const  
295 - {  
296 - QString target, query;  
297 - Template result = BEE::readMatrix(file, &target, &query);  
298 - result.file.set("Target", target);  
299 - result.file.set("Query", query);  
300 - return result;  
301 - }  
302 -  
303 - void write(const Template &t) const  
304 - {  
305 - BEE::writeMatrix(t, file);  
306 - }  
307 -};  
308 -  
309 -BR_REGISTER(Format, mtxFormat)  
310 -  
311 -/*!  
312 - * \ingroup formats  
313 - * \brief Reads a NIST BEE mask matrix.  
314 - * \author Josh Klontz \cite jklontz  
315 - */  
316 -class maskFormat : public mtxFormat  
317 -{  
318 - Q_OBJECT  
319 -};  
320 -  
321 -BR_REGISTER(Format, maskFormat)  
322 -  
323 -/*!  
324 - * \ingroup formats  
325 - * \brief MATLAB <tt>.mat</tt> format.  
326 - * \author Josh Klontz \cite jklontz  
327 - * http://www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf  
328 - * \note matFormat is known not to work with compressed matrices  
329 - */  
330 -class matFormat : public Format  
331 -{  
332 - Q_OBJECT  
333 -  
334 - struct Element  
335 - {  
336 - // It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing.  
337 - // This ensures that you always know exactly what size integers you are reading and writing, no matter what the  
338 - // underlying platform and architecture the application happens to be running on.  
339 - // http://qt-project.org/doc/qt-4.8/datastreamformat.html  
340 - quint32 type, bytes;  
341 - QByteArray data;  
342 - Element() : type(0), bytes(0) {}  
343 - Element(QDataStream &stream)  
344 - : type(0), bytes(0)  
345 - {  
346 - // Read first 4 bytes into type (32 bit integer),  
347 - // specifying the type of data used  
348 - if (stream.readRawData((char*)&type, 4) != 4)  
349 - qFatal("Unexpected end of file.");  
350 -  
351 - if (type >= 1 << 16) {  
352 - // Small data format  
353 - bytes = type;  
354 - type = type & 0x0000FFFF;  
355 - bytes = bytes >> 16;  
356 - } else {  
357 - // Regular format  
358 - // Read 4 bytes into bytes (32 bit integer),  
359 - // specifying the size of the element  
360 - if (stream.readRawData((char*)&bytes, 4) != 4)  
361 - qFatal("Unexpected end of file.");  
362 - }  
363 -  
364 - // Set the size of data to bytes  
365 - data.resize(bytes);  
366 -  
367 - // Read bytes amount of data from the file into data  
368 - if (int(bytes) != stream.readRawData(data.data(), bytes))  
369 - qFatal("Unexpected end of file.");  
370 -  
371 - // Alignment  
372 - int skipBytes = (bytes < 4) ? (4 - bytes) : (8 - bytes%8)%8;  
373 - if (skipBytes != 0) stream.skipRawData(skipBytes);  
374 - }  
375 - };  
376 -  
377 - Template read() const  
378 - {  
379 - QByteArray byteArray;  
380 - QtUtils::readFile(file, byteArray);  
381 - QDataStream f(byteArray);  
382 -  
383 - { // Check header  
384 - QByteArray header(128, 0);  
385 - f.readRawData(header.data(), 128);  
386 - if (!header.startsWith("MATLAB 5.0 MAT-file"))  
387 - qFatal("Invalid MAT header.");  
388 - }  
389 -  
390 - Template t(file);  
391 -  
392 - while (!f.atEnd()) {  
393 - Element element(f);  
394 -  
395 - // miCOMPRESSED  
396 - if (element.type == 15) {  
397 - // Prepend the number of bytes to element.data  
398 - element.data.prepend((char*)&element.bytes, 4); // Qt zlib wrapper requires this to preallocate the buffer  
399 - QDataStream uncompressed(qUncompress(element.data));  
400 - element = Element(uncompressed);  
401 - }  
402 -  
403 - // miMATRIX  
404 - if (element.type == 14) {  
405 - QDataStream matrix(element.data);  
406 - qint32 rows = 0, columns = 0;  
407 - int matrixType = 0;  
408 - QByteArray matrixData;  
409 - while (!matrix.atEnd()) {  
410 - Element subelement(matrix);  
411 - if (subelement.type == 5) { // Dimensions array  
412 - if (subelement.bytes == 8) {  
413 - rows = ((qint32*)subelement.data.data())[0];  
414 - columns = ((qint32*)subelement.data.data())[1];  
415 - } else {  
416 - qWarning("matFormat::read can only handle 2D arrays.");  
417 - }  
418 - } else if (subelement.type == 7) { //miSINGLE  
419 - matrixType = CV_32FC1;  
420 - matrixData = subelement.data;  
421 - } else if (subelement.type == 9) { //miDOUBLE  
422 - matrixType = CV_64FC1;  
423 - matrixData = subelement.data;  
424 - }  
425 - }  
426 -  
427 - if ((rows > 0) && (columns > 0) && (matrixType != 0) && !matrixData.isEmpty()) {  
428 - Mat transposed;  
429 - transpose(Mat(columns, rows, matrixType, matrixData.data()), transposed);  
430 - t.append(transposed);  
431 - }  
432 - }  
433 - }  
434 -  
435 - return t;  
436 - }  
437 -  
438 - void write(const Template &t) const  
439 - {  
440 - QByteArray data;  
441 - QDataStream stream(&data, QFile::WriteOnly);  
442 -  
443 - { // Header  
444 - QByteArray header = "MATLAB 5.0 MAT-file; Made with OpenBR | www.openbiometrics.org\n";  
445 - QByteArray buffer(116-header.size(), 0);  
446 - stream.writeRawData(header.data(), header.size());  
447 - stream.writeRawData(buffer.data(), buffer.size());  
448 - quint64 subsystem = 0;  
449 - quint16 version = 0x0100;  
450 - const char *endianness = "IM";  
451 - stream.writeRawData((const char*)&subsystem, 8);  
452 - stream.writeRawData((const char*)&version, 2);  
453 - stream.writeRawData(endianness, 2);  
454 - }  
455 -  
456 - for (int i=0; i<t.size(); i++) {  
457 - const Mat &m = t[i];  
458 - if (m.channels() != 1) qFatal("Only supports single channel matrices.");  
459 -  
460 - QByteArray subdata;  
461 - QDataStream substream(&subdata, QFile::WriteOnly);  
462 -  
463 - { // Array Flags  
464 - quint32 type = 6;  
465 - quint32 bytes = 8;  
466 - quint64 arrayClass = 0;  
467 - switch (m.type()) {  
468 - case CV_64FC1: arrayClass = 6; break;  
469 - case CV_32FC1: arrayClass = 7; break;  
470 - case CV_8UC1: arrayClass = 8; break;  
471 - case CV_8SC1: arrayClass = 9; break;  
472 - case CV_16UC1: arrayClass = 10; break;  
473 - case CV_16SC1: arrayClass = 11; break;  
474 - case CV_32SC1: arrayClass = 12; break;  
475 - default: qFatal("Unsupported matrix class.");  
476 - }  
477 - substream.writeRawData((const char*)&type, 4);  
478 - substream.writeRawData((const char*)&bytes, 4);  
479 - substream.writeRawData((const char*)&arrayClass, 8);  
480 - }  
481 -  
482 - { // Dimensions Array  
483 - quint32 type = 5;  
484 - quint32 bytes = 8;  
485 - substream.writeRawData((const char*)&type, 4);  
486 - substream.writeRawData((const char*)&bytes, 4);  
487 - substream.writeRawData((const char*)&m.rows, 4);  
488 - substream.writeRawData((const char*)&m.cols, 4);  
489 - }  
490 -  
491 - { // Array Name  
492 - QByteArray name(qPrintable(QString("OpenBR_%1").arg(QString::number(i))));  
493 - quint32 type = 1;  
494 - quint32 bytes = name.size();  
495 - QByteArray buffer((8 - bytes%8)%8, 0);  
496 - substream.writeRawData((const char*)&type, 4);  
497 - substream.writeRawData((const char*)&bytes, 4);  
498 - substream.writeRawData(name.data(), name.size());  
499 - substream.writeRawData(buffer.data(), buffer.size());  
500 - }  
501 -  
502 - { // Real part  
503 - quint32 type = 0;  
504 - switch (m.type()) {  
505 - case CV_8SC1: type = 1; break;  
506 - case CV_8UC1: type = 2; break;  
507 - case CV_16SC1: type = 3; break;  
508 - case CV_16UC1: type = 4; break;  
509 - case CV_32SC1: type = 5; break;  
510 - case CV_32FC1: type = 7; break;  
511 - case CV_64FC1: type = 9; break;  
512 - default: qFatal("Unsupported matrix type.");  
513 - }  
514 - quint32 bytes = m.elemSize() * m.rows * m.cols;  
515 - QByteArray buffer((8 - bytes%8)%8, 0);  
516 - Mat transposed;  
517 - transpose(m, transposed);  
518 - substream.writeRawData((const char*)&type, 4);  
519 - substream.writeRawData((const char*)&bytes, 4);  
520 - substream.writeRawData((const char*)transposed.data, bytes);  
521 - substream.writeRawData(buffer.data(), buffer.size());  
522 - }  
523 -  
524 - { // Matrix  
525 - quint32 type = 14;  
526 - quint32 bytes = subdata.size();  
527 - stream.writeRawData((const char*)&type, 4);  
528 - stream.writeRawData((const char*)&bytes, 4);  
529 - stream.writeRawData(subdata.data(), subdata.size());  
530 - }  
531 - }  
532 -  
533 - QtUtils::writeFile(file, data);  
534 - }  
535 -};  
536 -  
537 -BR_REGISTER(Format, matFormat)  
538 -  
539 -/*!  
540 - * \ingroup formats  
541 - * \brief Returns an empty matrix.  
542 - * \author Josh Klontz \cite jklontz  
543 - */  
544 -class nullFormat : public Format  
545 -{  
546 - Q_OBJECT  
547 -  
548 - Template read() const  
549 - {  
550 - return Template(file, Mat());  
551 - }  
552 -  
553 - void write(const Template &t) const  
554 - {  
555 - (void)t;  
556 - }  
557 -};  
558 -  
559 -BR_REGISTER(Format, nullFormat)  
560 -  
561 -/*!  
562 - * \ingroup formats  
563 - * \brief RAW format  
564 - *  
565 - * http://www.nist.gov/srd/nistsd27.cfm  
566 - * \author Josh Klontz \cite jklontz  
567 - */  
568 -class rawFormat : public Format  
569 -{  
570 - Q_OBJECT  
571 - static QHash<QString, QHash<QString,QSize> > imageSizes; // QHash<Path, QHash<File,Size> >  
572 -  
573 - Template read() const  
574 - {  
575 - QString path = file.path();  
576 - if (!imageSizes.contains(path)) {  
577 - static QMutex mutex;  
578 - QMutexLocker locker(&mutex);  
579 -  
580 - if (!imageSizes.contains(path)) {  
581 - const QString imageSize = path+"/ImageSize.txt";  
582 - QStringList lines;  
583 - if (QFileInfo(imageSize).exists()) {  
584 - lines = QtUtils::readLines(imageSize);  
585 - lines.removeFirst(); // Remove header  
586 - }  
587 -  
588 - QHash<QString,QSize> sizes;  
589 - QRegExp whiteSpace("\\s+");  
590 - foreach (const QString &line, lines) {  
591 - QStringList words = line.split(whiteSpace);  
592 - if (words.size() != 3) continue;  
593 - sizes.insert(words[0], QSize(words[2].toInt(), words[1].toInt()));  
594 - }  
595 -  
596 - imageSizes.insert(path, sizes);  
597 - }  
598 - }  
599 -  
600 - QByteArray data;  
601 - QtUtils::readFile(file, data);  
602 -  
603 - QSize size = imageSizes[path][file.baseName()];  
604 - if (!size.isValid()) size = QSize(800,768);  
605 - if (data.size() != size.width() * size.height())  
606 - qFatal("Expected %d*%d bytes, got %d.", size.height(), size.width(), data.size());  
607 - return Template(file, Mat(size.height(), size.width(), CV_8UC1, data.data()).clone());  
608 - }  
609 -  
610 - void write(const Template &t) const  
611 - {  
612 - QtUtils::writeFile(file, QByteArray().setRawData((const char*)t.m().data, t.m().total() * t.m().elemSize()));  
613 - }  
614 -};  
615 -  
616 -QHash<QString, QHash<QString,QSize> > rawFormat::imageSizes;  
617 -  
618 -BR_REGISTER(Format, rawFormat)  
619 -  
620 -/*!  
621 - * \ingroup formats  
622 - * \brief Retrieves an image from a webcam.  
623 - * \author Josh Klontz \cite jklontz  
624 - */  
625 -class webcamFormat : public Format  
626 -{  
627 - Q_OBJECT  
628 -  
629 - Template read() const  
630 - {  
631 - static QScopedPointer<VideoCapture> videoCapture;  
632 -  
633 - if (videoCapture.isNull())  
634 - videoCapture.reset(new VideoCapture(0));  
635 -  
636 - Mat m;  
637 - videoCapture->read(m);  
638 - return Template(m);  
639 - }  
640 -  
641 - void write(const Template &t) const  
642 - {  
643 - (void) t;  
644 - qFatal("Not supported.");  
645 - }  
646 -};  
647 -  
648 -BR_REGISTER(Format, webcamFormat)  
649 -  
650 -/*!  
651 - * \ingroup formats  
652 - * \brief Decodes images from Base64 xml  
653 - * \author Scott Klum \cite sklum  
654 - * \author Josh Klontz \cite jklontz  
655 - */  
656 -class xmlFormat : public Format  
657 -{  
658 - Q_OBJECT  
659 -  
660 - Template read() const  
661 - {  
662 - Template t;  
663 -  
664 -#ifndef BR_EMBEDDED  
665 - QString fileName = file.get<QString>("path") + file.name;  
666 -  
667 - QDomDocument doc(fileName);  
668 - QFile f(fileName);  
669 -  
670 - if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file.flat()));  
671 - if (!doc.setContent(&f)) qWarning("Unable to parse %s.", qPrintable(file.flat()));  
672 - f.close();  
673 -  
674 - QDomElement docElem = doc.documentElement();  
675 - QDomNode subject = docElem.firstChild();  
676 - while (!subject.isNull()) {  
677 - QDomNode fileNode = subject.firstChild();  
678 -  
679 - while (!fileNode.isNull()) {  
680 - QDomElement e = fileNode.toElement();  
681 -  
682 - if (e.tagName() == "FORMAL_IMG") {  
683 - QByteArray byteArray = QByteArray::fromBase64(qPrintable(e.text()));  
684 - Mat m = imdecode(Mat(3, byteArray.size(), CV_8UC3, byteArray.data()), CV_LOAD_IMAGE_COLOR);  
685 - if (!m.data) qWarning("xmlFormat::read failed to decode image data.");  
686 - t.append(m);  
687 - } else if ((e.tagName() == "RELEASE_IMG") ||  
688 - (e.tagName() == "PREBOOK_IMG") ||  
689 - (e.tagName() == "LPROFILE") ||  
690 - (e.tagName() == "RPROFILE")) {  
691 - // Ignore these other image fields for now  
692 - } else {  
693 - t.file.set(e.tagName(), e.text());  
694 - }  
695 -  
696 - fileNode = fileNode.nextSibling();  
697 - }  
698 - subject = subject.nextSibling();  
699 - }  
700 -  
701 - // Calculate age  
702 - if (t.file.contains("DOB")) {  
703 - const QDate dob = QDate::fromString(t.file.get<QString>("DOB").left(10), "yyyy-MM-dd");  
704 - const QDate current = QDate::currentDate();  
705 - int age = current.year() - dob.year();  
706 - if (current.month() < dob.month()) age--;  
707 - t.file.set("Age", age);  
708 - }  
709 -#endif // BR_EMBEDDED  
710 -  
711 - return t;  
712 - }  
713 -  
714 - void write(const Template &t) const  
715 - {  
716 - QStringList lines;  
717 - lines.append("<?xml version=\"1.0\" standalone=\"yes\"?>");  
718 - lines.append("<openbr-xml-format>");  
719 - lines.append("\t<xml-data>");  
720 - foreach (const QString &key, t.file.localKeys()) {  
721 - if ((key == "Index") || (key == "Label")) continue;  
722 - lines.append("\t\t<"+key+">"+QtUtils::toString(t.file.value(key))+"</"+key+">");  
723 - }  
724 - std::vector<uchar> data;  
725 - imencode(".jpg",t.m(),data);  
726 - QByteArray byteArray = QByteArray::fromRawData((const char*)data.data(), data.size());  
727 - lines.append("\t\t<FORMAL_IMG>"+byteArray.toBase64()+"</FORMAL_IMG>");  
728 - lines.append("\t</xml-data>");  
729 - lines.append("</openbr-xml-format>");  
730 - QtUtils::writeFile(file, lines);  
731 - }  
732 -};  
733 -  
734 -BR_REGISTER(Format, xmlFormat)  
735 -  
736 -/*!  
737 - * \ingroup formats  
738 - * \brief Reads in scores or ground truth from a text table.  
739 - * \author Josh Klontz \cite jklontz  
740 - *  
741 - * Example of the format:  
742 - * \code  
743 - * 2.2531514 FALSE 99990377 99990164  
744 - * 2.2549822 TRUE 99990101 99990101  
745 - * \endcode  
746 - */  
747 -class scoresFormat : public Format  
748 -{  
749 - Q_OBJECT  
750 - Q_PROPERTY(int column READ get_column WRITE set_column RESET reset_column STORED false)  
751 - Q_PROPERTY(bool groundTruth READ get_groundTruth WRITE set_groundTruth RESET reset_groundTruth STORED false)  
752 - Q_PROPERTY(QString delimiter READ get_delimiter WRITE set_delimiter RESET reset_delimiter STORED false)  
753 - BR_PROPERTY(int, column, 0)  
754 - BR_PROPERTY(bool, groundTruth, false)  
755 - BR_PROPERTY(QString, delimiter, "\t")  
756 -  
757 - Template read() const  
758 - {  
759 - QFile f(file.name);  
760 - if (!f.open(QFile::ReadOnly | QFile::Text))  
761 - qFatal("Failed to open %s for reading.", qPrintable(f.fileName()));  
762 - QList<float> values;  
763 - while (!f.atEnd()) {  
764 - const QStringList words = QString(f.readLine()).split(delimiter);  
765 - if (words.size() <= column) qFatal("Expected file to have at least %d columns.", column+1);  
766 - const QString &word = words[column];  
767 - bool ok;  
768 - float value = word.toFloat(&ok);  
769 - if (!ok) value = (QtUtils::toBool(word) ? BEE::Match : BEE::NonMatch);  
770 - values.append(value);  
771 - }  
772 - if (values.size() == 1)  
773 - qWarning("Only one value read, double check file line endings.");  
774 - Mat result = OpenCVUtils::toMat(values);  
775 - if (groundTruth) result.convertTo(result, CV_8U);  
776 - return result;  
777 - }  
778 -  
779 - void write(const Template &t) const  
780 - {  
781 - (void) t;  
782 - qFatal("Not implemented.");  
783 - }  
784 -};  
785 -  
786 -BR_REGISTER(Format, scoresFormat)  
787 -  
788 -/*!  
789 - * \ingroup formats  
790 - * \brief Reads FBI EBTS transactions.  
791 - * \author Scott Klum \cite sklum  
792 - * https://www.fbibiospecs.org/ebts.html  
793 - */  
794 -class ebtsFormat : public Format  
795 -{  
796 - Q_OBJECT  
797 -  
798 - struct Field {  
799 - int type;  
800 - QList<QByteArray> data;  
801 - };  
802 -  
803 - struct Record {  
804 - int type;  
805 - quint32 bytes;  
806 - int position; // Starting position of record  
807 -  
808 - QHash<int,QList<QByteArray> > fields;  
809 - };  
810 -  
811 - quint32 recordBytes(const QByteArray &byteArray, const float recordType, int from) const  
812 - {  
813 - bool ok;  
814 - quint32 size;  
815 -  
816 - if (recordType == 4 || recordType == 7) {  
817 - // read first four bytes  
818 - ok = true;  
819 - size = qFromBigEndian<quint32>((const uchar*)byteArray.mid(from,4).constData());  
820 - } else {  
821 - int index = byteArray.indexOf(QChar(0x1D), from);  
822 - size = byteArray.mid(from, index-from).split(':').last().toInt(&ok);  
823 - }  
824 -  
825 - return ok ? size : -1;  
826 - }  
827 -  
828 - void parseRecord(const QByteArray &byteArray, Record &record) const  
829 - {  
830 - if (record.type == 4 || record.type == 7) {  
831 - // Just a binary blob  
832 - // Read everything after the first four bytes  
833 - // Not current supported  
834 - } else {  
835 - // Continue reading fields until we get all the data  
836 - unsigned int position = record.position;  
837 - while (position < record.position + record.bytes) {  
838 - int index = byteArray.indexOf(QChar(0x1D), position);  
839 - Field field = parseField(byteArray.mid(position, index-position),QChar(0x1F));  
840 - if (field.type == 999 ) {  
841 - // Data begin after the field identifier and the colon  
842 - int dataBegin = byteArray.indexOf(':', position)+1;  
843 - field.data.clear();  
844 - field.data.append(byteArray.mid(dataBegin, record.bytes-(dataBegin-record.position)));  
845 -  
846 - // Data fields are always last in the record  
847 - record.fields.insert(field.type,field.data);  
848 - break;  
849 - }  
850 - // Advance the position accounting for the separator  
851 - position += index-position+1;  
852 - record.fields.insert(field.type,field.data);  
853 - }  
854 - }  
855 - }  
856 -  
857 - Field parseField(const QByteArray &byteArray, const QChar &sep) const  
858 - {  
859 - bool ok;  
860 - Field f;  
861 -  
862 - QList<QByteArray> data = byteArray.split(':');  
863 -  
864 - f.type = data.first().split('.').last().toInt(&ok);  
865 - f.data = data.last().split(sep.toLatin1());  
866 -  
867 - return f;  
868 - }  
869 -  
870 - Template read() const  
871 - {  
872 - QByteArray byteArray;  
873 - QtUtils::readFile(file, byteArray);  
874 -  
875 - Template t;  
876 -  
877 - Mat m;  
878 -  
879 - QList<Record> records;  
880 -  
881 - // Read the type one record (every EBTS file will have one of these)  
882 - Record r1;  
883 - r1.type = 1;  
884 - r1.position = 0;  
885 - r1.bytes = recordBytes(byteArray,r1.type,r1.position);  
886 -  
887 - // The fields in a type 1 record are strictly defined  
888 - QList<QByteArray> data = byteArray.mid(r1.position,r1.bytes).split(QChar(0x1D).toLatin1());  
889 - foreach (const QByteArray &datum, data) {  
890 - Field f = parseField(datum,QChar(0x1F));  
891 - r1.fields.insert(f.type,f.data);  
892 - }  
893 -  
894 - records.append(r1);  
895 -  
896 - // Read the type two record (every EBTS file will have one of these)  
897 - Record r2;  
898 - r2.type = 2;  
899 - r2.position = r1.bytes;  
900 - r2.bytes = recordBytes(byteArray,r2.type,r2.position);  
901 -  
902 - // The fields in a type 2 record are strictly defined  
903 - data = byteArray.mid(r2.position,r2.bytes).split(QChar(0x1D).toLatin1());  
904 - foreach (const QByteArray &datum, data) {  
905 - Field f = parseField(datum,QChar(0x1F));  
906 - r2.fields.insert(f.type,f.data);  
907 - }  
908 -  
909 - // Demographics  
910 - if (r2.fields.contains(18)) {  
911 - QString name = r2.fields.value(18).first();  
912 - QStringList names = name.split(',');  
913 - t.file.set("FIRSTNAME", names.at(1));  
914 - t.file.set("LASTNAME", names.at(0));  
915 - }  
916 -  
917 - if (r2.fields.contains(22)) t.file.set("DOB", r2.fields.value(22).first().toInt());  
918 - if (r2.fields.contains(24)) t.file.set("GENDER", QString(r2.fields.value(24).first()));  
919 - if (r2.fields.contains(25)) t.file.set("RACE", QString(r2.fields.value(25).first()));  
920 -  
921 - if (t.file.contains("DOB")) {  
922 - const QDate dob = QDate::fromString(t.file.get<QString>("DOB"), "yyyyMMdd");  
923 - const QDate current = QDate::currentDate();  
924 - int age = current.year() - dob.year();  
925 - if (current.month() < dob.month()) age--;  
926 - t.file.set("Age", age);  
927 - }  
928 -  
929 - records.append(r2);  
930 -  
931 - // The third field of the first record contains informations about all the remaining records in the transaction  
932 - // We don't care about the first two and the final items  
933 - QList<QByteArray> recordTypes = r1.fields.value(3);  
934 - for (int i=2; i<recordTypes.size()-1; i++) {  
935 - // The first two bytes indicate the record index (and we don't want the separator), but we only care about the type  
936 - QByteArray recordType = recordTypes[i].mid(3);  
937 - Record r;  
938 - r.type = recordType.toInt();  
939 - records.append(r);  
940 - }  
941 -  
942 - QList<int> frontalIdxs;  
943 - int position = r1.bytes + r2.bytes;  
944 - for (int i=2; i<records.size(); i++) {  
945 - records[i].position = position;  
946 - records[i].bytes = recordBytes(byteArray,records[i].type,position);  
947 -  
948 - parseRecord(byteArray, records[i]);  
949 - if (records[i].type == 10) frontalIdxs.append(i);  
950 - position += records[i].bytes;  
951 - }  
952 -  
953 - if (!frontalIdxs.isEmpty()) {  
954 - // We use the first type 10 record to get the frontal  
955 - QByteArray frontal = records[frontalIdxs.first()].fields.value(999).first();  
956 - m = imdecode(Mat(3, frontal.size(), CV_8UC3, frontal.data()), CV_LOAD_IMAGE_COLOR);  
957 - if (!m.data) qWarning("ebtsFormat::read failed to decode image data.");  
958 - t.m() = m;  
959 - } else qWarning("ebtsFormat::cannot find image data within file.");  
960 -  
961 - return t;  
962 - }  
963 -  
964 - void write(const Template &t) const  
965 - {  
966 - (void) t;  
967 - qFatal("Writing EBTS files is not supported.");  
968 - }  
969 -};  
970 -  
971 -BR_REGISTER(Format, ebtsFormat)  
972 -  
973 -} // namespace br  
974 -  
975 -#include "format.moc"  
openbr/plugins/format/binary.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup formats
  27 + * \brief A simple binary matrix format.
  28 + * \author Josh Klontz \cite jklontz
  29 + * First 4 bytes indicate the number of rows.
  30 + * Second 4 bytes indicate the number of columns.
  31 + * The rest of the bytes are 32-bit floating data elements in row-major order.
  32 + */
  33 +class binaryFormat : public Format
  34 +{
  35 + Q_OBJECT
  36 + Q_PROPERTY(bool raw READ get_raw WRITE set_raw RESET reset_raw STORED false)
  37 + BR_PROPERTY(bool, raw, false)
  38 +
  39 + Template read() const
  40 + {
  41 + QByteArray data;
  42 + QtUtils::readFile(file, data);
  43 + if (raw) {
  44 + return Template(file, Mat(1, data.size(), CV_8UC1, data.data()).clone());
  45 + } else {
  46 + return Template(file, Mat(((quint32*)data.data())[0],
  47 + ((quint32*)data.data())[1],
  48 + CV_32FC1,
  49 + data.data()+8).clone());
  50 + }
  51 + }
  52 +
  53 + void write(const Template &t) const
  54 + {
  55 + QFile f(file);
  56 + QtUtils::touchDir(f);
  57 + if (!f.open(QFile::WriteOnly))
  58 + qFatal("Failed to open %s for writing.", qPrintable(file));
  59 +
  60 + Mat m;
  61 + if (!raw) {
  62 + if (t.m().type() != CV_32FC1)
  63 + t.m().convertTo(m, CV_32F);
  64 + else m = t.m();
  65 +
  66 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
  67 +
  68 + f.write((const char *) &m.rows, 4);
  69 + f.write((const char *) &m.cols, 4);
  70 + }
  71 + else m = t.m();
  72 +
  73 + qint64 rowSize = m.cols * sizeof(float);
  74 + for (int i=0; i < m.rows; i++)
  75 + {
  76 + f.write((const char *) m.row(i).data, rowSize);
  77 + }
  78 + f.close();
  79 + }
  80 +};
  81 +
  82 +BR_REGISTER(Format, binaryFormat)
  83 +
  84 +} // namespace br
  85 +
  86 +#include "format/binary.moc"
openbr/plugins/format/csv.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QRegularExpression>
  18 +
  19 +#include <openbr/plugins/openbr_internal.h>
  20 +#include <openbr/core/opencvutils.h>
  21 +#include <openbr/core/qtutils.h>
  22 +
  23 +using namespace cv;
  24 +
  25 +namespace br
  26 +{
  27 +
  28 +/*!
  29 + * \ingroup formats
  30 + * \brief Reads a comma separated value file.
  31 + * \author Josh Klontz \cite jklontz
  32 + */
  33 +class csvFormat : public Format
  34 +{
  35 + Q_OBJECT
  36 +
  37 + Template read() const
  38 + {
  39 + QFile f(file.name);
  40 + f.open(QFile::ReadOnly);
  41 + QStringList lines(QString(f.readAll()).split(QRegularExpression("[\n|\r\n|\r]"), QString::SkipEmptyParts));
  42 + f.close();
  43 +
  44 + bool isUChar = true;
  45 + QList< QList<float> > valsList;
  46 + foreach (const QString &line, lines) {
  47 + QList<float> vals;
  48 + foreach (const QString &word, line.split(QRegExp(" *, *"), QString::SkipEmptyParts)) {
  49 + bool ok;
  50 + const float val = word.toFloat(&ok);
  51 + vals.append(val);
  52 + isUChar = isUChar && (val == float(uchar(val)));
  53 + }
  54 + if (!vals.isEmpty())
  55 + valsList.append(vals);
  56 + }
  57 +
  58 + Mat m(valsList.size(), valsList[0].size(), CV_32FC1);
  59 + for (int i=0; i<valsList.size(); i++)
  60 + for (int j=0; j<valsList[i].size(); j++)
  61 + m.at<float>(i,j) = valsList[i][j];
  62 +
  63 + if (isUChar) m.convertTo(m, CV_8U);
  64 + return Template(m);
  65 + }
  66 +
  67 + void write(const Template &t) const
  68 + {
  69 + const Mat &m = t.m();
  70 + if (t.size() != 1) qFatal("Only supports single matrix templates.");
  71 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
  72 +
  73 + QStringList lines; lines.reserve(m.rows);
  74 + for (int r=0; r<m.rows; r++) {
  75 + QStringList elements; elements.reserve(m.cols);
  76 + for (int c=0; c<m.cols; c++)
  77 + elements.append(OpenCVUtils::elemToString(m, r, c));
  78 + lines.append(elements.join(","));
  79 + }
  80 +
  81 + QtUtils::writeFile(file, lines);
  82 + }
  83 +};
  84 +
  85 +BR_REGISTER(Format, csvFormat)
  86 +
  87 +} // namespace br
  88 +
  89 +#include "format/csv.moc"
openbr/plugins/format/ebts.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QtEndian>
  18 +#include <opencv2/highgui/highgui.hpp>
  19 +
  20 +#include <openbr/plugins/openbr_internal.h>
  21 +#include <openbr/core/qtutils.h>
  22 +
  23 +using namespace cv;
  24 +
  25 +namespace br
  26 +{
  27 +
  28 +/*!
  29 + * \ingroup formats
  30 + * \brief Reads FBI EBTS transactions.
  31 + * \author Scott Klum \cite sklum
  32 + * https://www.fbibiospecs.org/ebts.html
  33 + */
  34 +class ebtsFormat : public Format
  35 +{
  36 + Q_OBJECT
  37 +
  38 + struct Field {
  39 + int type;
  40 + QList<QByteArray> data;
  41 + };
  42 +
  43 + struct Record {
  44 + int type;
  45 + quint32 bytes;
  46 + int position; // Starting position of record
  47 +
  48 + QHash<int,QList<QByteArray> > fields;
  49 + };
  50 +
  51 + quint32 recordBytes(const QByteArray &byteArray, const float recordType, int from) const
  52 + {
  53 + bool ok;
  54 + quint32 size;
  55 +
  56 + if (recordType == 4 || recordType == 7) {
  57 + // read first four bytes
  58 + ok = true;
  59 + size = qFromBigEndian<quint32>((const uchar*)byteArray.mid(from,4).constData());
  60 + } else {
  61 + int index = byteArray.indexOf(QChar(0x1D), from);
  62 + size = byteArray.mid(from, index-from).split(':').last().toInt(&ok);
  63 + }
  64 +
  65 + return ok ? size : -1;
  66 + }
  67 +
  68 + void parseRecord(const QByteArray &byteArray, Record &record) const
  69 + {
  70 + if (record.type == 4 || record.type == 7) {
  71 + // Just a binary blob
  72 + // Read everything after the first four bytes
  73 + // Not current supported
  74 + } else {
  75 + // Continue reading fields until we get all the data
  76 + unsigned int position = record.position;
  77 + while (position < record.position + record.bytes) {
  78 + int index = byteArray.indexOf(QChar(0x1D), position);
  79 + Field field = parseField(byteArray.mid(position, index-position),QChar(0x1F));
  80 + if (field.type == 999 ) {
  81 + // Data begin after the field identifier and the colon
  82 + int dataBegin = byteArray.indexOf(':', position)+1;
  83 + field.data.clear();
  84 + field.data.append(byteArray.mid(dataBegin, record.bytes-(dataBegin-record.position)));
  85 +
  86 + // Data fields are always last in the record
  87 + record.fields.insert(field.type,field.data);
  88 + break;
  89 + }
  90 + // Advance the position accounting for the separator
  91 + position += index-position+1;
  92 + record.fields.insert(field.type,field.data);
  93 + }
  94 + }
  95 + }
  96 +
  97 + Field parseField(const QByteArray &byteArray, const QChar &sep) const
  98 + {
  99 + bool ok;
  100 + Field f;
  101 +
  102 + QList<QByteArray> data = byteArray.split(':');
  103 +
  104 + f.type = data.first().split('.').last().toInt(&ok);
  105 + f.data = data.last().split(sep.toLatin1());
  106 +
  107 + return f;
  108 + }
  109 +
  110 + Template read() const
  111 + {
  112 + QByteArray byteArray;
  113 + QtUtils::readFile(file, byteArray);
  114 +
  115 + Template t;
  116 +
  117 + Mat m;
  118 +
  119 + QList<Record> records;
  120 +
  121 + // Read the type one record (every EBTS file will have one of these)
  122 + Record r1;
  123 + r1.type = 1;
  124 + r1.position = 0;
  125 + r1.bytes = recordBytes(byteArray,r1.type,r1.position);
  126 +
  127 + // The fields in a type 1 record are strictly defined
  128 + QList<QByteArray> data = byteArray.mid(r1.position,r1.bytes).split(QChar(0x1D).toLatin1());
  129 + foreach (const QByteArray &datum, data) {
  130 + Field f = parseField(datum,QChar(0x1F));
  131 + r1.fields.insert(f.type,f.data);
  132 + }
  133 +
  134 + records.append(r1);
  135 +
  136 + // Read the type two record (every EBTS file will have one of these)
  137 + Record r2;
  138 + r2.type = 2;
  139 + r2.position = r1.bytes;
  140 + r2.bytes = recordBytes(byteArray,r2.type,r2.position);
  141 +
  142 + // The fields in a type 2 record are strictly defined
  143 + data = byteArray.mid(r2.position,r2.bytes).split(QChar(0x1D).toLatin1());
  144 + foreach (const QByteArray &datum, data) {
  145 + Field f = parseField(datum,QChar(0x1F));
  146 + r2.fields.insert(f.type,f.data);
  147 + }
  148 +
  149 + // Demographics
  150 + if (r2.fields.contains(18)) {
  151 + QString name = r2.fields.value(18).first();
  152 + QStringList names = name.split(',');
  153 + t.file.set("FIRSTNAME", names.at(1));
  154 + t.file.set("LASTNAME", names.at(0));
  155 + }
  156 +
  157 + if (r2.fields.contains(22)) t.file.set("DOB", r2.fields.value(22).first().toInt());
  158 + if (r2.fields.contains(24)) t.file.set("GENDER", QString(r2.fields.value(24).first()));
  159 + if (r2.fields.contains(25)) t.file.set("RACE", QString(r2.fields.value(25).first()));
  160 +
  161 + if (t.file.contains("DOB")) {
  162 + const QDate dob = QDate::fromString(t.file.get<QString>("DOB"), "yyyyMMdd");
  163 + const QDate current = QDate::currentDate();
  164 + int age = current.year() - dob.year();
  165 + if (current.month() < dob.month()) age--;
  166 + t.file.set("Age", age);
  167 + }
  168 +
  169 + records.append(r2);
  170 +
  171 + // The third field of the first record contains informations about all the remaining records in the transaction
  172 + // We don't care about the first two and the final items
  173 + QList<QByteArray> recordTypes = r1.fields.value(3);
  174 + for (int i=2; i<recordTypes.size()-1; i++) {
  175 + // The first two bytes indicate the record index (and we don't want the separator), but we only care about the type
  176 + QByteArray recordType = recordTypes[i].mid(3);
  177 + Record r;
  178 + r.type = recordType.toInt();
  179 + records.append(r);
  180 + }
  181 +
  182 + QList<int> frontalIdxs;
  183 + int position = r1.bytes + r2.bytes;
  184 + for (int i=2; i<records.size(); i++) {
  185 + records[i].position = position;
  186 + records[i].bytes = recordBytes(byteArray,records[i].type,position);
  187 +
  188 + parseRecord(byteArray, records[i]);
  189 + if (records[i].type == 10) frontalIdxs.append(i);
  190 + position += records[i].bytes;
  191 + }
  192 +
  193 + if (!frontalIdxs.isEmpty()) {
  194 + // We use the first type 10 record to get the frontal
  195 + QByteArray frontal = records[frontalIdxs.first()].fields.value(999).first();
  196 + m = imdecode(Mat(3, frontal.size(), CV_8UC3, frontal.data()), CV_LOAD_IMAGE_COLOR);
  197 + if (!m.data) qWarning("ebtsFormat::read failed to decode image data.");
  198 + t.m() = m;
  199 + } else qWarning("ebtsFormat::cannot find image data within file.");
  200 +
  201 + return t;
  202 + }
  203 +
  204 + void write(const Template &t) const
  205 + {
  206 + (void) t;
  207 + qFatal("Writing EBTS files is not supported.");
  208 + }
  209 +};
  210 +
  211 +BR_REGISTER(Format, ebtsFormat)
  212 +
  213 +} // namespace br
  214 +
  215 +#include "format/ebts.moc"
openbr/plugins/format/lffs.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup formats
  27 + * \brief Reads a NIST LFFS file.
  28 + * \author Josh Klontz \cite jklontz
  29 + */
  30 +class lffsFormat : public Format
  31 +{
  32 + Q_OBJECT
  33 +
  34 + Template read() const
  35 + {
  36 + QByteArray byteArray;
  37 + QtUtils::readFile(file.name, byteArray);
  38 + return Mat(1, byteArray.size(), CV_8UC1, byteArray.data()).clone();
  39 + }
  40 +
  41 + void write(const Template &t) const
  42 + {
  43 + QByteArray byteArray((const char*)t.m().data, t.m().total()*t.m().elemSize());
  44 + QtUtils::writeFile(file.name, byteArray);
  45 + }
  46 +};
  47 +
  48 +BR_REGISTER(Format, lffsFormat)
  49 +
  50 +} // namespace br
  51 +
  52 +#include "format/lffs.moc"
openbr/plugins/format/lmat.cpp 0 → 100644
  1 +#include <openbr/plugins/openbr_internal.h>
  2 +
  3 +namespace br
  4 +{
  5 +
  6 +/*!
  7 + * \ingroup formats
  8 + * \brief Likely matrix format
  9 + *
  10 + * www.liblikely.org
  11 + * \author Josh Klontz \cite jklontz
  12 + */
  13 +class lmatFormat : public Format
  14 +{
  15 + Q_OBJECT
  16 +
  17 + Template read() const
  18 + {
  19 + const likely_const_mat m = likely_read(qPrintable(file.name), likely_file_guess);
  20 + const Template result(likelyToOpenCVMat(m));
  21 + likely_release_mat(m);
  22 + return result;
  23 + }
  24 +
  25 + void write(const Template &t) const
  26 + {
  27 + const likely_const_mat m = likelyFromOpenCVMat(t);
  28 + likely_write(m, qPrintable(file.name));
  29 + likely_release_mat(m);
  30 + }
  31 +};
  32 +
  33 +BR_REGISTER(Format, lmatFormat)
  34 +
  35 +} // namespace br
  36 +
  37 +#include "format/lmat.moc"
openbr/plugins/format/mat.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup formats
  27 + * \brief MATLAB <tt>.mat</tt> format.
  28 + * \author Josh Klontz \cite jklontz
  29 + * http://www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf
  30 + * \note matFormat is known not to work with compressed matrices
  31 + */
  32 +class matFormat : public Format
  33 +{
  34 + Q_OBJECT
  35 +
  36 + struct Element
  37 + {
  38 + // It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing.
  39 + // This ensures that you always know exactly what size integers you are reading and writing, no matter what the
  40 + // underlying platform and architecture the application happens to be running on.
  41 + // http://qt-project.org/doc/qt-4.8/datastreamformat.html
  42 + quint32 type, bytes;
  43 + QByteArray data;
  44 + Element() : type(0), bytes(0) {}
  45 + Element(QDataStream &stream)
  46 + : type(0), bytes(0)
  47 + {
  48 + // Read first 4 bytes into type (32 bit integer),
  49 + // specifying the type of data used
  50 + if (stream.readRawData((char*)&type, 4) != 4)
  51 + qFatal("Unexpected end of file.");
  52 +
  53 + if (type >= 1 << 16) {
  54 + // Small data format
  55 + bytes = type;
  56 + type = type & 0x0000FFFF;
  57 + bytes = bytes >> 16;
  58 + } else {
  59 + // Regular format
  60 + // Read 4 bytes into bytes (32 bit integer),
  61 + // specifying the size of the element
  62 + if (stream.readRawData((char*)&bytes, 4) != 4)
  63 + qFatal("Unexpected end of file.");
  64 + }
  65 +
  66 + // Set the size of data to bytes
  67 + data.resize(bytes);
  68 +
  69 + // Read bytes amount of data from the file into data
  70 + if (int(bytes) != stream.readRawData(data.data(), bytes))
  71 + qFatal("Unexpected end of file.");
  72 +
  73 + // Alignment
  74 + int skipBytes = (bytes < 4) ? (4 - bytes) : (8 - bytes%8)%8;
  75 + if (skipBytes != 0) stream.skipRawData(skipBytes);
  76 + }
  77 + };
  78 +
  79 + Template read() const
  80 + {
  81 + QByteArray byteArray;
  82 + QtUtils::readFile(file, byteArray);
  83 + QDataStream f(byteArray);
  84 +
  85 + { // Check header
  86 + QByteArray header(128, 0);
  87 + f.readRawData(header.data(), 128);
  88 + if (!header.startsWith("MATLAB 5.0 MAT-file"))
  89 + qFatal("Invalid MAT header.");
  90 + }
  91 +
  92 + Template t(file);
  93 +
  94 + while (!f.atEnd()) {
  95 + Element element(f);
  96 +
  97 + // miCOMPRESSED
  98 + if (element.type == 15) {
  99 + // Prepend the number of bytes to element.data
  100 + element.data.prepend((char*)&element.bytes, 4); // Qt zlib wrapper requires this to preallocate the buffer
  101 + QDataStream uncompressed(qUncompress(element.data));
  102 + element = Element(uncompressed);
  103 + }
  104 +
  105 + // miMATRIX
  106 + if (element.type == 14) {
  107 + QDataStream matrix(element.data);
  108 + qint32 rows = 0, columns = 0;
  109 + int matrixType = 0;
  110 + QByteArray matrixData;
  111 + while (!matrix.atEnd()) {
  112 + Element subelement(matrix);
  113 + if (subelement.type == 5) { // Dimensions array
  114 + if (subelement.bytes == 8) {
  115 + rows = ((qint32*)subelement.data.data())[0];
  116 + columns = ((qint32*)subelement.data.data())[1];
  117 + } else {
  118 + qWarning("matFormat::read can only handle 2D arrays.");
  119 + }
  120 + } else if (subelement.type == 7) { //miSINGLE
  121 + matrixType = CV_32FC1;
  122 + matrixData = subelement.data;
  123 + } else if (subelement.type == 9) { //miDOUBLE
  124 + matrixType = CV_64FC1;
  125 + matrixData = subelement.data;
  126 + }
  127 + }
  128 +
  129 + if ((rows > 0) && (columns > 0) && (matrixType != 0) && !matrixData.isEmpty()) {
  130 + Mat transposed;
  131 + transpose(Mat(columns, rows, matrixType, matrixData.data()), transposed);
  132 + t.append(transposed);
  133 + }
  134 + }
  135 + }
  136 +
  137 + return t;
  138 + }
  139 +
  140 + void write(const Template &t) const
  141 + {
  142 + QByteArray data;
  143 + QDataStream stream(&data, QFile::WriteOnly);
  144 +
  145 + { // Header
  146 + QByteArray header = "MATLAB 5.0 MAT-file; Made with OpenBR | www.openbiometrics.org\n";
  147 + QByteArray buffer(116-header.size(), 0);
  148 + stream.writeRawData(header.data(), header.size());
  149 + stream.writeRawData(buffer.data(), buffer.size());
  150 + quint64 subsystem = 0;
  151 + quint16 version = 0x0100;
  152 + const char *endianness = "IM";
  153 + stream.writeRawData((const char*)&subsystem, 8);
  154 + stream.writeRawData((const char*)&version, 2);
  155 + stream.writeRawData(endianness, 2);
  156 + }
  157 +
  158 + for (int i=0; i<t.size(); i++) {
  159 + const Mat &m = t[i];
  160 + if (m.channels() != 1) qFatal("Only supports single channel matrices.");
  161 +
  162 + QByteArray subdata;
  163 + QDataStream substream(&subdata, QFile::WriteOnly);
  164 +
  165 + { // Array Flags
  166 + quint32 type = 6;
  167 + quint32 bytes = 8;
  168 + quint64 arrayClass = 0;
  169 + switch (m.type()) {
  170 + case CV_64FC1: arrayClass = 6; break;
  171 + case CV_32FC1: arrayClass = 7; break;
  172 + case CV_8UC1: arrayClass = 8; break;
  173 + case CV_8SC1: arrayClass = 9; break;
  174 + case CV_16UC1: arrayClass = 10; break;
  175 + case CV_16SC1: arrayClass = 11; break;
  176 + case CV_32SC1: arrayClass = 12; break;
  177 + default: qFatal("Unsupported matrix class.");
  178 + }
  179 + substream.writeRawData((const char*)&type, 4);
  180 + substream.writeRawData((const char*)&bytes, 4);
  181 + substream.writeRawData((const char*)&arrayClass, 8);
  182 + }
  183 +
  184 + { // Dimensions Array
  185 + quint32 type = 5;
  186 + quint32 bytes = 8;
  187 + substream.writeRawData((const char*)&type, 4);
  188 + substream.writeRawData((const char*)&bytes, 4);
  189 + substream.writeRawData((const char*)&m.rows, 4);
  190 + substream.writeRawData((const char*)&m.cols, 4);
  191 + }
  192 +
  193 + { // Array Name
  194 + QByteArray name(qPrintable(QString("OpenBR_%1").arg(QString::number(i))));
  195 + quint32 type = 1;
  196 + quint32 bytes = name.size();
  197 + QByteArray buffer((8 - bytes%8)%8, 0);
  198 + substream.writeRawData((const char*)&type, 4);
  199 + substream.writeRawData((const char*)&bytes, 4);
  200 + substream.writeRawData(name.data(), name.size());
  201 + substream.writeRawData(buffer.data(), buffer.size());
  202 + }
  203 +
  204 + { // Real part
  205 + quint32 type = 0;
  206 + switch (m.type()) {
  207 + case CV_8SC1: type = 1; break;
  208 + case CV_8UC1: type = 2; break;
  209 + case CV_16SC1: type = 3; break;
  210 + case CV_16UC1: type = 4; break;
  211 + case CV_32SC1: type = 5; break;
  212 + case CV_32FC1: type = 7; break;
  213 + case CV_64FC1: type = 9; break;
  214 + default: qFatal("Unsupported matrix type.");
  215 + }
  216 + quint32 bytes = m.elemSize() * m.rows * m.cols;
  217 + QByteArray buffer((8 - bytes%8)%8, 0);
  218 + Mat transposed;
  219 + transpose(m, transposed);
  220 + substream.writeRawData((const char*)&type, 4);
  221 + substream.writeRawData((const char*)&bytes, 4);
  222 + substream.writeRawData((const char*)transposed.data, bytes);
  223 + substream.writeRawData(buffer.data(), buffer.size());
  224 + }
  225 +
  226 + { // Matrix
  227 + quint32 type = 14;
  228 + quint32 bytes = subdata.size();
  229 + stream.writeRawData((const char*)&type, 4);
  230 + stream.writeRawData((const char*)&bytes, 4);
  231 + stream.writeRawData(subdata.data(), subdata.size());
  232 + }
  233 + }
  234 +
  235 + QtUtils::writeFile(file, data);
  236 + }
  237 +};
  238 +
  239 +BR_REGISTER(Format, matFormat)
  240 +
  241 +} // namespace br
  242 +
  243 +#include "format/mat.moc"
openbr/plugins/format/mtx.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/bee.h>
  19 +
  20 +namespace br
  21 +{
  22 +
  23 +/*!
  24 + * \ingroup formats
  25 + * \brief Reads a NIST BEE similarity matrix.
  26 + * \author Josh Klontz \cite jklontz
  27 + */
  28 +class mtxFormat : public Format
  29 +{
  30 + Q_OBJECT
  31 +
  32 + Template read() const
  33 + {
  34 + QString target, query;
  35 + Template result = BEE::readMatrix(file, &target, &query);
  36 + result.file.set("Target", target);
  37 + result.file.set("Query", query);
  38 + return result;
  39 + }
  40 +
  41 + void write(const Template &t) const
  42 + {
  43 + BEE::writeMatrix(t, file);
  44 + }
  45 +};
  46 +
  47 +BR_REGISTER(Format, mtxFormat)
  48 +
  49 +/*!
  50 + * \ingroup formats
  51 + * \brief Reads a NIST BEE mask matrix.
  52 + * \author Josh Klontz \cite jklontz
  53 + */
  54 +class maskFormat : public mtxFormat
  55 +{
  56 + Q_OBJECT
  57 +};
  58 +
  59 +BR_REGISTER(Format, maskFormat)
  60 +
  61 +} // namespace br
  62 +
  63 +#include "format/mtx.moc"
openbr/plugins/format/null.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +
  19 +namespace br
  20 +{
  21 +
  22 +/*!
  23 + * \ingroup formats
  24 + * \brief Returns an empty matrix.
  25 + * \author Josh Klontz \cite jklontz
  26 + */
  27 +class nullFormat : public Format
  28 +{
  29 + Q_OBJECT
  30 +
  31 + Template read() const
  32 + {
  33 + return Template(file, cv::Mat());
  34 + }
  35 +
  36 + void write(const Template &t) const
  37 + {
  38 + (void)t;
  39 + }
  40 +};
  41 +
  42 +BR_REGISTER(Format, nullFormat)
  43 +
  44 +} // namespace br
  45 +
  46 +#include "format/null.moc"
openbr/plugins/format/post.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <QTcpSocket>
  18 +#include <opencv2/highgui/highgui.hpp>
  19 +
  20 +#include <openbr/plugins/openbr_internal.h>
  21 +#include <http_parser.h>
  22 +
  23 +using namespace cv;
  24 +
  25 +namespace br
  26 +{
  27 +
  28 +/*!
  29 + * \ingroup formats
  30 + * \brief Handle POST requests
  31 + * \author Josh Klontz \cite jklontz
  32 + */
  33 +class postFormat : public Format
  34 +{
  35 + Q_OBJECT
  36 +
  37 + Template read() const
  38 + {
  39 + Template t(file);
  40 +
  41 + // Read from socket
  42 + QTcpSocket *socket = new QTcpSocket();
  43 + socket->setSocketDescriptor(file.get<qintptr>("socketDescriptor"));
  44 + socket->write("HTTP/1.1 200 OK\r\n"
  45 + "Content-Type: text/html; charset=UTF-8\r\n\r\n"
  46 + "Hello World!\r\n");
  47 + socket->waitForBytesWritten();
  48 + socket->waitForReadyRead();
  49 + QByteArray data = socket->readAll();
  50 + socket->close();
  51 + delete socket;
  52 +
  53 + qDebug() << data;
  54 +
  55 + // Parse data
  56 + http_parser_settings settings;
  57 + settings.on_body = bodyCallback;
  58 + settings.on_headers_complete = NULL;
  59 + settings.on_header_field = NULL;
  60 + settings.on_header_value = NULL;
  61 + settings.on_message_begin = NULL;
  62 + settings.on_message_complete = NULL;
  63 + settings.on_status_complete = NULL;
  64 + settings.on_url = NULL;
  65 +
  66 + {
  67 + QByteArray body;
  68 + http_parser parser;
  69 + http_parser_init(&parser, HTTP_REQUEST);
  70 + parser.data = &body;
  71 + http_parser_execute(&parser, &settings, data.data(), data.size());
  72 + data = body;
  73 + }
  74 +
  75 + data.prepend("HTTP/1.1 200 OK");
  76 + QByteArray body;
  77 + { // Image data is two layers deep
  78 + http_parser parser;
  79 + http_parser_init(&parser, HTTP_BOTH);
  80 + parser.data = &body;
  81 + http_parser_execute(&parser, &settings, data.data(), data.size());
  82 + }
  83 +
  84 + t.append(imdecode(Mat(1, body.size(), CV_8UC1, body.data()), 1));
  85 + return t;
  86 + }
  87 +
  88 + void write(const Template &t) const
  89 + {
  90 + (void) t;
  91 + qFatal("Not supported!");
  92 + }
  93 +
  94 + static int bodyCallback(http_parser *parser, const char *at, size_t length)
  95 + {
  96 + QByteArray *byteArray = (QByteArray*)parser->data;
  97 + *byteArray = QByteArray(at, length);
  98 + return 0;
  99 + }
  100 +};
  101 +
  102 +BR_REGISTER(Format, postFormat)
  103 +
  104 +} // namespace br
  105 +
  106 +#include "format/post.moc"
openbr/plugins/format/raw.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +
  20 +using namespace cv;
  21 +
  22 +namespace br
  23 +{
  24 +
  25 +/*!
  26 + * \ingroup formats
  27 + * \brief RAW format
  28 + *
  29 + * http://www.nist.gov/srd/nistsd27.cfm
  30 + * \author Josh Klontz \cite jklontz
  31 + */
  32 +class rawFormat : public Format
  33 +{
  34 + Q_OBJECT
  35 + static QHash<QString, QHash<QString,QSize> > imageSizes; // QHash<Path, QHash<File,Size> >
  36 +
  37 + Template read() const
  38 + {
  39 + QString path = file.path();
  40 + if (!imageSizes.contains(path)) {
  41 + static QMutex mutex;
  42 + QMutexLocker locker(&mutex);
  43 +
  44 + if (!imageSizes.contains(path)) {
  45 + const QString imageSize = path+"/ImageSize.txt";
  46 + QStringList lines;
  47 + if (QFileInfo(imageSize).exists()) {
  48 + lines = QtUtils::readLines(imageSize);
  49 + lines.removeFirst(); // Remove header
  50 + }
  51 +
  52 + QHash<QString,QSize> sizes;
  53 + QRegExp whiteSpace("\\s+");
  54 + foreach (const QString &line, lines) {
  55 + QStringList words = line.split(whiteSpace);
  56 + if (words.size() != 3) continue;
  57 + sizes.insert(words[0], QSize(words[2].toInt(), words[1].toInt()));
  58 + }
  59 +
  60 + imageSizes.insert(path, sizes);
  61 + }
  62 + }
  63 +
  64 + QByteArray data;
  65 + QtUtils::readFile(file, data);
  66 +
  67 + QSize size = imageSizes[path][file.baseName()];
  68 + if (!size.isValid()) size = QSize(800,768);
  69 + if (data.size() != size.width() * size.height())
  70 + qFatal("Expected %d*%d bytes, got %d.", size.height(), size.width(), data.size());
  71 + return Template(file, Mat(size.height(), size.width(), CV_8UC1, data.data()).clone());
  72 + }
  73 +
  74 + void write(const Template &t) const
  75 + {
  76 + QtUtils::writeFile(file, QByteArray().setRawData((const char*)t.m().data, t.m().total() * t.m().elemSize()));
  77 + }
  78 +};
  79 +
  80 +QHash<QString, QHash<QString,QSize> > rawFormat::imageSizes;
  81 +
  82 +BR_REGISTER(Format, rawFormat)
  83 +
  84 +} // namespace br
  85 +
  86 +#include "format/raw.moc"
openbr/plugins/format/scores.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <openbr/plugins/openbr_internal.h>
  18 +#include <openbr/core/qtutils.h>
  19 +#include <openbr/core/opencvutils.h>
  20 +#include <openbr/core/bee.h>
  21 +
  22 +using namespace cv;
  23 +
  24 +namespace br
  25 +{
  26 +
  27 +/*!
  28 + * \ingroup formats
  29 + * \brief Reads in scores or ground truth from a text table.
  30 + * \author Josh Klontz \cite jklontz
  31 + *
  32 + * Example of the format:
  33 + * \code
  34 + * 2.2531514 FALSE 99990377 99990164
  35 + * 2.2549822 TRUE 99990101 99990101
  36 + * \endcode
  37 + */
  38 +class scoresFormat : public Format
  39 +{
  40 + Q_OBJECT
  41 + Q_PROPERTY(int column READ get_column WRITE set_column RESET reset_column STORED false)
  42 + Q_PROPERTY(bool groundTruth READ get_groundTruth WRITE set_groundTruth RESET reset_groundTruth STORED false)
  43 + Q_PROPERTY(QString delimiter READ get_delimiter WRITE set_delimiter RESET reset_delimiter STORED false)
  44 + BR_PROPERTY(int, column, 0)
  45 + BR_PROPERTY(bool, groundTruth, false)
  46 + BR_PROPERTY(QString, delimiter, "\t")
  47 +
  48 + Template read() const
  49 + {
  50 + QFile f(file.name);
  51 + if (!f.open(QFile::ReadOnly | QFile::Text))
  52 + qFatal("Failed to open %s for reading.", qPrintable(f.fileName()));
  53 + QList<float> values;
  54 + while (!f.atEnd()) {
  55 + const QStringList words = QString(f.readLine()).split(delimiter);
  56 + if (words.size() <= column) qFatal("Expected file to have at least %d columns.", column+1);
  57 + const QString &word = words[column];
  58 + bool ok;
  59 + float value = word.toFloat(&ok);
  60 + if (!ok) value = (QtUtils::toBool(word) ? BEE::Match : BEE::NonMatch);
  61 + values.append(value);
  62 + }
  63 + if (values.size() == 1)
  64 + qWarning("Only one value read, double check file line endings.");
  65 + Mat result = OpenCVUtils::toMat(values);
  66 + if (groundTruth) result.convertTo(result, CV_8U);
  67 + return result;
  68 + }
  69 +
  70 + void write(const Template &t) const
  71 + {
  72 + (void) t;
  73 + qFatal("Not implemented.");
  74 + }
  75 +};
  76 +
  77 +BR_REGISTER(Format, scoresFormat)
  78 +
  79 +} // namespace br
  80 +
  81 +#include "format/scores.moc"