Commit fbb16fc3fc0271e0c6dd7f044fd0f4653cd8a1d5

Authored by Austin Van Blanton
2 parents 87021a62 8b3c745f

Merge branch 'master' of https://github.com/biometrics/openbr into mosift

CHANGELOG.md
1 0.4.0 - ??/??/?? 1 0.4.0 - ??/??/??
2 ================ 2 ================
3 * Added -evalDetection and -plotDetection for evaluating and plotting object detection accuracy (#9) 3 * Added -evalDetection and -plotDetection for evaluating and plotting object detection accuracy (#9)
  4 +* Deprecated Transform::backProject
4 5
5 0.3.0 - 5/22/13 6 0.3.0 - 5/22/13
6 =============== 7 ===============
openbr/core/core.cpp
@@ -146,13 +146,7 @@ struct AlgorithmCore @@ -146,13 +146,7 @@ struct AlgorithmCore
146 data.removeAt(i); 146 data.removeAt(i);
147 const int numFiles = data.size(); 147 const int numFiles = data.size();
148 148
149 - if (Globals->backProject) {  
150 - TemplateList backProjectedData;  
151 - transform->backProject(data, backProjectedData);  
152 - data = backProjectedData;  
153 - } else {  
154 - data >> *transform;  
155 - } 149 + data >> *transform;
156 150
157 g->writeBlock(data); 151 g->writeBlock(data);
158 const FileList newFiles = data.files(); 152 const FileList newFiles = data.files();
openbr/core/eval.cpp
@@ -373,6 +373,8 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec @@ -373,6 +373,8 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec
373 } 373 }
374 374
375 const int keep = qMin(points.size(), Max_Points); 375 const int keep = qMin(points.size(), Max_Points);
  376 + if (keep < 2) qFatal("Insufficient points.");
  377 +
376 QStringList lines; lines.reserve(keep); 378 QStringList lines; lines.reserve(keep);
377 for (int i=0; i<keep; i++) { 379 for (int i=0; i<keep; i++) {
378 const DetectionOperatingPoint &point = points[double(i) / double(keep-1) * double(points.size()-1)]; 380 const DetectionOperatingPoint &point = points[double(i) / double(keep-1) * double(points.size()-1)];
@@ -382,6 +384,15 @@ static QStringList computeDetectionResults(const QList&lt;ResolvedDetection&gt; &amp;detec @@ -382,6 +384,15 @@ static QStringList computeDetectionResults(const QList&lt;ResolvedDetection&gt; &amp;detec
382 return lines; 384 return lines;
383 } 385 }
384 386
  387 +QString getDetectKey(const TemplateList &templates)
  388 +{
  389 + const File &f = templates.first().file;
  390 + foreach (const QString &key, f.localKeys())
  391 + if (!f.get<QRectF>(key, QRectF()).isNull())
  392 + return key;
  393 + return "";
  394 +}
  395 +
385 float EvalDetection(const QString &predictedInput, const QString &truthInput, const QString &csv) 396 float EvalDetection(const QString &predictedInput, const QString &truthInput, const QString &csv)
386 { 397 {
387 qDebug("Evaluating detection of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); 398 qDebug("Evaluating detection of %s against %s", qPrintable(predictedInput), qPrintable(truthInput));
@@ -389,20 +400,22 @@ float EvalDetection(const QString &amp;predictedInput, const QString &amp;truthInput, co @@ -389,20 +400,22 @@ float EvalDetection(const QString &amp;predictedInput, const QString &amp;truthInput, co
389 const TemplateList truth(TemplateList::fromGallery(truthInput)); 400 const TemplateList truth(TemplateList::fromGallery(truthInput));
390 401
391 // Figure out which metadata field contains a bounding box 402 // Figure out which metadata field contains a bounding box
392 - QString detectKey;  
393 - foreach (const QString &key, truth.first().file.localKeys())  
394 - if (!truth.first().file.get<QRectF>(key, QRectF()).isNull()) {  
395 - detectKey = key;  
396 - break;  
397 - }  
398 - if (detectKey.isNull()) qFatal("No suitable metadata key found.");  
399 - else qDebug("Using metadata key: %s", qPrintable(detectKey)); 403 + QString truthDetectKey = getDetectKey(truth);
  404 + if (truthDetectKey.isEmpty()) qFatal("No suitable ground truth metadata key found.");
  405 + QString predictedDetectKey = truthDetectKey;
  406 + if (predicted.first().file.get<QRectF>(predictedDetectKey, QRectF()).isNull())
  407 + predictedDetectKey = getDetectKey(predicted);
  408 + if (predictedDetectKey.isEmpty()) qFatal("No suitable predicted metadata key found.");
  409 +
  410 + qDebug("Using metadata key: %s%s",
  411 + qPrintable(predictedDetectKey),
  412 + qPrintable(predictedDetectKey == truthDetectKey ? QString() : "/"+truthDetectKey));
400 413
401 QMap<QString, Detections> allDetections; // Organized by file, QMap used to preserve order 414 QMap<QString, Detections> allDetections; // Organized by file, QMap used to preserve order
402 foreach (const Template &t, predicted) 415 foreach (const Template &t, predicted)
403 - allDetections[t.file.baseName()].predicted.append(Detection(t.file.get<QRectF>(detectKey), t.file.get<float>("Confidence", -1))); 416 + allDetections[t.file.baseName()].predicted.append(Detection(t.file.get<QRectF>(predictedDetectKey), t.file.get<float>("Confidence", -1)));
404 foreach (const Template &t, truth) 417 foreach (const Template &t, truth)
405 - allDetections[t.file.baseName()].truth.append(Detection(t.file.get<QRectF>(detectKey))); 418 + allDetections[t.file.baseName()].truth.append(Detection(t.file.get<QRectF>(truthDetectKey)));
406 419
407 QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; 420 QList<ResolvedDetection> resolvedDetections, falseNegativeDetections;
408 foreach (Detections detections, allDetections.values()) { 421 foreach (Detections detections, allDetections.values()) {
openbr/core/qtutils.cpp
@@ -334,8 +334,8 @@ QRectF QtUtils::toRect(const QString &amp;string, bool *ok) @@ -334,8 +334,8 @@ QRectF QtUtils::toRect(const QString &amp;string, bool *ok)
334 bool okX, okY, okWidth, okHeight; 334 bool okX, okY, okWidth, okHeight;
335 x = words[0].toFloat(&okX); 335 x = words[0].toFloat(&okX);
336 y = words[1].toFloat(&okY); 336 y = words[1].toFloat(&okY);
337 - width = words[0].toFloat(&okWidth);  
338 - height = words[1].toFloat(&okHeight); 337 + width = words[2].toFloat(&okWidth);
  338 + height = words[3].toFloat(&okHeight);
339 if (okX && okY && okWidth && okHeight) { 339 if (okX && okY && okWidth && okHeight) {
340 if (ok) *ok = true; 340 if (ok) *ok = true;
341 return QRectF(x, y, width, height); 341 return QRectF(x, y, width, height);
openbr/openbr_plugin.cpp
@@ -1171,28 +1171,6 @@ void Transform::project(const TemplateList &amp;src, TemplateList &amp;dst) const @@ -1171,28 +1171,6 @@ void Transform::project(const TemplateList &amp;src, TemplateList &amp;dst) const
1171 futures.waitForFinished(); 1171 futures.waitForFinished();
1172 } 1172 }
1173 1173
1174 -static void _backProject(const Transform *transform, const Template *dst, Template *src)  
1175 -{  
1176 - try {  
1177 - transform->backProject(*dst, *src);  
1178 - } catch (...) {  
1179 - qWarning("Exception triggered when processing %s with transform %s", qPrintable(src->file.flat()), qPrintable(transform->objectName()));  
1180 - *src = Template(dst->file);  
1181 - src->file.set("FTE", true);  
1182 - }  
1183 -}  
1184 -  
1185 -void Transform::backProject(const TemplateList &dst, TemplateList &src) const  
1186 -{  
1187 - src.reserve(dst.size());  
1188 - for (int i=0; i<dst.size(); i++) src.append(Template());  
1189 -  
1190 - QFutureSynchronizer<void> futures;  
1191 - for (int i=0; i<dst.size(); i++)  
1192 - futures.addFuture(QtConcurrent::run(_backProject, this, &dst[i], &src[i]));  
1193 - futures.waitForFinished();  
1194 -}  
1195 -  
1196 QList<Transform *> Transform::getChildren() const 1174 QList<Transform *> Transform::getChildren() const
1197 { 1175 {
1198 QList<Transform *> output; 1176 QList<Transform *> output;
openbr/openbr_plugin.h
@@ -602,13 +602,6 @@ public: @@ -602,13 +602,6 @@ public:
602 BR_PROPERTY(int, blockSize, parallelism * ((sizeof(void*) == 4) ? 128 : 1024)) 602 BR_PROPERTY(int, blockSize, parallelism * ((sizeof(void*) == 4) ? 128 : 1024))
603 603
604 /*! 604 /*!
605 - * \brief true if backProject should be used instead of project (the algorithm should be inverted)  
606 - */  
607 - Q_PROPERTY(bool backProject READ get_backProject WRITE set_backProject RESET reset_backProject)  
608 - BR_PROPERTY(bool, backProject, false)  
609 -  
610 -  
611 - /*!  
612 * \brief If \c true no messages will be sent to the terminal, \c false by default. 605 * \brief If \c true no messages will be sent to the terminal, \c false by default.
613 */ 606 */
614 Q_PROPERTY(bool quiet READ get_quiet WRITE set_quiet RESET reset_quiet) 607 Q_PROPERTY(bool quiet READ get_quiet WRITE set_quiet RESET reset_quiet)
@@ -1034,6 +1027,10 @@ private: @@ -1034,6 +1027,10 @@ private:
1034 * @{ 1027 * @{
1035 */ 1028 */
1036 1029
  1030 +/*!
  1031 + * \brief For asynchronous events during template projection.
  1032 + * \see #Transform::getEvent
  1033 + */
1037 class TemplateEvent : public QObject 1034 class TemplateEvent : public QObject
1038 { 1035 {
1039 Q_OBJECT 1036 Q_OBJECT
@@ -1048,7 +1045,6 @@ signals: @@ -1048,7 +1045,6 @@ signals:
1048 void theSignal(const Template & output) const; 1045 void theSignal(const Template & output) const;
1049 }; 1046 };
1050 1047
1051 -  
1052 /*! 1048 /*!
1053 * \brief Plugin base class for processing a template. 1049 * \brief Plugin base class for processing a template.
1054 * 1050 *
@@ -1078,8 +1074,6 @@ public: @@ -1078,8 +1074,6 @@ public:
1078 virtual void train(const TemplateList &data) = 0; /*!< \brief Train the transform. */ 1074 virtual void train(const TemplateList &data) = 0; /*!< \brief Train the transform. */
1079 virtual void project(const Template &src, Template &dst) const = 0; /*!< \brief Apply the transform. */ 1075 virtual void project(const Template &src, Template &dst) const = 0; /*!< \brief Apply the transform. */
1080 virtual void project(const TemplateList &src, TemplateList &dst) const; /*!< \brief Apply the transform. */ 1076 virtual void project(const TemplateList &src, TemplateList &dst) const; /*!< \brief Apply the transform. */
1081 - virtual void backProject(const Template &dst, Template &src) const { src = dst; } /*!< \brief Invert the transform. */  
1082 - virtual void backProject(const TemplateList &dst, TemplateList &src) const; /*!< \brief Invert the transform. */  
1083 1077
1084 /*!< \brief Apply the transform, may update the transform's internal state */ 1078 /*!< \brief Apply the transform, may update the transform's internal state */
1085 virtual void projectUpdate(const Template &src, Template &dst) 1079 virtual void projectUpdate(const Template &src, Template &dst)
openbr/plugins/cascade.cpp
@@ -98,7 +98,7 @@ class CascadeTransform : public UntrainableMetaTransform @@ -98,7 +98,7 @@ class CascadeTransform : public UntrainableMetaTransform
98 for (size_t j=0; j<rects.size(); j++) { 98 for (size_t j=0; j<rects.size(); j++) {
99 Template u(t.file, m); 99 Template u(t.file, m);
100 if (rejectLevels.size() > j) 100 if (rejectLevels.size() > j)
101 - u.file.set("Confidence", rejectLevels[j]*1000.0 + levelWeights[j]*1.0); 101 + u.file.set("Confidence", rejectLevels[j]*levelWeights[j]);
102 const QRectF rect = OpenCVUtils::fromRect(rects[j]); 102 const QRectF rect = OpenCVUtils::fromRect(rects[j]);
103 u.file.appendRect(rect); 103 u.file.appendRect(rect);
104 u.file.set(model, rect); 104 u.file.set(model, rect);
openbr/plugins/eigen3.cpp
@@ -59,21 +59,6 @@ public: @@ -59,21 +59,6 @@ public:
59 PCATransform() : keep(0.95), drop(0), whiten(false) {} 59 PCATransform() : keep(0.95), drop(0), whiten(false) {}
60 60
61 private: 61 private:
62 - /*  
63 - void backProject(const Template &src, Template &dst) const  
64 - {  
65 - const cv::Mat &m = src;  
66 - dst = cv::Mat(originalRows, m.rows*m.cols/originalRows, CV_32FC1);  
67 -  
68 - // Map Eigen into OpenCV  
69 - Eigen::Map<const Eigen::MatrixXf> inMap(m.ptr<float>(), keep, 1);  
70 - Eigen::Map<Eigen::MatrixXf> outMap(dst.m().ptr<float>(), m.rows*m.cols, 1);  
71 -  
72 - // Do projection  
73 - outMap = (eVecs * inMap) + mean;  
74 - }  
75 - */  
76 -  
77 double residualReconstructionError(const Template &src) const 62 double residualReconstructionError(const Template &src) const
78 { 63 {
79 Template proj; 64 Template proj;
openbr/plugins/meta.cpp
@@ -129,26 +129,6 @@ class PipeTransform : public CompositeTransform @@ -129,26 +129,6 @@ class PipeTransform : public CompositeTransform
129 } 129 }
130 } 130 }
131 131
132 - void backProject(const Template &dst, Template &src) const  
133 - {  
134 - // Backprojecting a time-varying transform is probably not going to work.  
135 - if (timeVarying()) qFatal("No backProject defined for time-varying transform");  
136 -  
137 - src = dst;  
138 - // Reverse order in which transforms are processed  
139 - int length = transforms.length();  
140 - for (int i=length-1; i>=0; i--) {  
141 - Transform *f = transforms.at(i);  
142 - try {  
143 - src >> *f;  
144 - } catch (...) {  
145 - qWarning("Exception triggered when processing %s with transform %s", qPrintable(dst.file.flat()), qPrintable(f->objectName()));  
146 - src = Template(src.file);  
147 - src.file.set("FTE", true);  
148 - }  
149 - }  
150 - }  
151 -  
152 void projectUpdate(const Template &src, Template &dst) 132 void projectUpdate(const Template &src, Template &dst)
153 { 133 {
154 dst = src; 134 dst = src;
@@ -306,8 +286,6 @@ class ForkTransform : public CompositeTransform @@ -306,8 +286,6 @@ class ForkTransform : public CompositeTransform
306 futures.waitForFinished(); 286 futures.waitForFinished();
307 } 287 }
308 288
309 - void backProject(const Template &dst, Template &src) const {Transform::backProject(dst, src);}  
310 -  
311 // same as _project, but calls projectUpdate on sub-transforms 289 // same as _project, but calls projectUpdate on sub-transforms
312 void projectupdate(const Template & src, Template & dst) 290 void projectupdate(const Template & src, Template & dst)
313 { 291 {