Commit fbb16fc3fc0271e0c6dd7f044fd0f4653cd8a1d5
Merge branch 'master' of https://github.com/biometrics/openbr into mosift
Showing
9 changed files
with
32 additions
and
89 deletions
CHANGELOG.md
openbr/core/core.cpp
| ... | ... | @@ -146,13 +146,7 @@ struct AlgorithmCore |
| 146 | 146 | data.removeAt(i); |
| 147 | 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 | 151 | g->writeBlock(data); |
| 158 | 152 | const FileList newFiles = data.files(); | ... | ... |
openbr/core/eval.cpp
| ... | ... | @@ -373,6 +373,8 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec |
| 373 | 373 | } |
| 374 | 374 | |
| 375 | 375 | const int keep = qMin(points.size(), Max_Points); |
| 376 | + if (keep < 2) qFatal("Insufficient points."); | |
| 377 | + | |
| 376 | 378 | QStringList lines; lines.reserve(keep); |
| 377 | 379 | for (int i=0; i<keep; i++) { |
| 378 | 380 | const DetectionOperatingPoint &point = points[double(i) / double(keep-1) * double(points.size()-1)]; |
| ... | ... | @@ -382,6 +384,15 @@ static QStringList computeDetectionResults(const QList<ResolvedDetection> &detec |
| 382 | 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 | 396 | float EvalDetection(const QString &predictedInput, const QString &truthInput, const QString &csv) |
| 386 | 397 | { |
| 387 | 398 | qDebug("Evaluating detection of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); |
| ... | ... | @@ -389,20 +400,22 @@ float EvalDetection(const QString &predictedInput, const QString &truthInput, co |
| 389 | 400 | const TemplateList truth(TemplateList::fromGallery(truthInput)); |
| 390 | 401 | |
| 391 | 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 | 414 | QMap<QString, Detections> allDetections; // Organized by file, QMap used to preserve order |
| 402 | 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 | 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 | 420 | QList<ResolvedDetection> resolvedDetections, falseNegativeDetections; |
| 408 | 421 | foreach (Detections detections, allDetections.values()) { | ... | ... |
openbr/core/qtutils.cpp
| ... | ... | @@ -334,8 +334,8 @@ QRectF QtUtils::toRect(const QString &string, bool *ok) |
| 334 | 334 | bool okX, okY, okWidth, okHeight; |
| 335 | 335 | x = words[0].toFloat(&okX); |
| 336 | 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 | 339 | if (okX && okY && okWidth && okHeight) { |
| 340 | 340 | if (ok) *ok = true; |
| 341 | 341 | return QRectF(x, y, width, height); | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -1171,28 +1171,6 @@ void Transform::project(const TemplateList &src, TemplateList &dst) const |
| 1171 | 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 | 1174 | QList<Transform *> Transform::getChildren() const |
| 1197 | 1175 | { |
| 1198 | 1176 | QList<Transform *> output; | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -602,13 +602,6 @@ public: |
| 602 | 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 | 605 | * \brief If \c true no messages will be sent to the terminal, \c false by default. |
| 613 | 606 | */ |
| 614 | 607 | Q_PROPERTY(bool quiet READ get_quiet WRITE set_quiet RESET reset_quiet) |
| ... | ... | @@ -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 | 1034 | class TemplateEvent : public QObject |
| 1038 | 1035 | { |
| 1039 | 1036 | Q_OBJECT |
| ... | ... | @@ -1048,7 +1045,6 @@ signals: |
| 1048 | 1045 | void theSignal(const Template & output) const; |
| 1049 | 1046 | }; |
| 1050 | 1047 | |
| 1051 | - | |
| 1052 | 1048 | /*! |
| 1053 | 1049 | * \brief Plugin base class for processing a template. |
| 1054 | 1050 | * |
| ... | ... | @@ -1078,8 +1074,6 @@ public: |
| 1078 | 1074 | virtual void train(const TemplateList &data) = 0; /*!< \brief Train the transform. */ |
| 1079 | 1075 | virtual void project(const Template &src, Template &dst) const = 0; /*!< \brief Apply the transform. */ |
| 1080 | 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 | 1078 | /*!< \brief Apply the transform, may update the transform's internal state */ |
| 1085 | 1079 | virtual void projectUpdate(const Template &src, Template &dst) | ... | ... |
openbr/plugins/cascade.cpp
| ... | ... | @@ -98,7 +98,7 @@ class CascadeTransform : public UntrainableMetaTransform |
| 98 | 98 | for (size_t j=0; j<rects.size(); j++) { |
| 99 | 99 | Template u(t.file, m); |
| 100 | 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 | 102 | const QRectF rect = OpenCVUtils::fromRect(rects[j]); |
| 103 | 103 | u.file.appendRect(rect); |
| 104 | 104 | u.file.set(model, rect); | ... | ... |
openbr/plugins/eigen3.cpp
| ... | ... | @@ -59,21 +59,6 @@ public: |
| 59 | 59 | PCATransform() : keep(0.95), drop(0), whiten(false) {} |
| 60 | 60 | |
| 61 | 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 | 62 | double residualReconstructionError(const Template &src) const |
| 78 | 63 | { |
| 79 | 64 | Template proj; | ... | ... |
openbr/plugins/meta.cpp
| ... | ... | @@ -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 | 132 | void projectUpdate(const Template &src, Template &dst) |
| 153 | 133 | { |
| 154 | 134 | dst = src; |
| ... | ... | @@ -306,8 +286,6 @@ class ForkTransform : public CompositeTransform |
| 306 | 286 | futures.waitForFinished(); |
| 307 | 287 | } |
| 308 | 288 | |
| 309 | - void backProject(const Template &dst, Template &src) const {Transform::backProject(dst, src);} | |
| 310 | - | |
| 311 | 289 | // same as _project, but calls projectUpdate on sub-transforms |
| 312 | 290 | void projectupdate(const Template & src, Template & dst) |
| 313 | 291 | { | ... | ... |