diff --git a/CHANGELOG.md b/CHANGELOG.md index 21efc83..c56439e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ 0.4.0 - ??/??/?? ================ * Added -evalDetection and -plotDetection for evaluating and plotting object detection accuracy (#9) +* Deprecated Transform::backProject 0.3.0 - 5/22/13 =============== diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 5f97d70..1378302 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -146,13 +146,7 @@ struct AlgorithmCore data.removeAt(i); const int numFiles = data.size(); - if (Globals->backProject) { - TemplateList backProjectedData; - transform->backProject(data, backProjectedData); - data = backProjectedData; - } else { - data >> *transform; - } + data >> *transform; g->writeBlock(data); const FileList newFiles = data.files(); diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index 13f761a..9e813d8 100644 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -373,6 +373,8 @@ static QStringList computeDetectionResults(const QList &detec } const int keep = qMin(points.size(), Max_Points); + if (keep < 2) qFatal("Insufficient points."); + QStringList lines; lines.reserve(keep); for (int i=0; i &detec return lines; } +QString getDetectKey(const TemplateList &templates) +{ + const File &f = templates.first().file; + foreach (const QString &key, f.localKeys()) + if (!f.get(key, QRectF()).isNull()) + return key; + return ""; +} + float EvalDetection(const QString &predictedInput, const QString &truthInput, const QString &csv) { qDebug("Evaluating detection of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); @@ -389,20 +400,22 @@ float EvalDetection(const QString &predictedInput, const QString &truthInput, co const TemplateList truth(TemplateList::fromGallery(truthInput)); // Figure out which metadata field contains a bounding box - QString detectKey; - foreach (const QString &key, truth.first().file.localKeys()) - if (!truth.first().file.get(key, QRectF()).isNull()) { - detectKey = key; - break; - } - if (detectKey.isNull()) qFatal("No suitable metadata key found."); - else qDebug("Using metadata key: %s", qPrintable(detectKey)); + QString truthDetectKey = getDetectKey(truth); + if (truthDetectKey.isEmpty()) qFatal("No suitable ground truth metadata key found."); + QString predictedDetectKey = truthDetectKey; + if (predicted.first().file.get(predictedDetectKey, QRectF()).isNull()) + predictedDetectKey = getDetectKey(predicted); + if (predictedDetectKey.isEmpty()) qFatal("No suitable predicted metadata key found."); + + qDebug("Using metadata key: %s%s", + qPrintable(predictedDetectKey), + qPrintable(predictedDetectKey == truthDetectKey ? QString() : "/"+truthDetectKey)); QMap allDetections; // Organized by file, QMap used to preserve order foreach (const Template &t, predicted) - allDetections[t.file.baseName()].predicted.append(Detection(t.file.get(detectKey), t.file.get("Confidence", -1))); + allDetections[t.file.baseName()].predicted.append(Detection(t.file.get(predictedDetectKey), t.file.get("Confidence", -1))); foreach (const Template &t, truth) - allDetections[t.file.baseName()].truth.append(Detection(t.file.get(detectKey))); + allDetections[t.file.baseName()].truth.append(Detection(t.file.get(truthDetectKey))); QList resolvedDetections, falseNegativeDetections; foreach (Detections detections, allDetections.values()) { diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index 0fa103e..fe295cf 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -334,8 +334,8 @@ QRectF QtUtils::toRect(const QString &string, bool *ok) bool okX, okY, okWidth, okHeight; x = words[0].toFloat(&okX); y = words[1].toFloat(&okY); - width = words[0].toFloat(&okWidth); - height = words[1].toFloat(&okHeight); + width = words[2].toFloat(&okWidth); + height = words[3].toFloat(&okHeight); if (okX && okY && okWidth && okHeight) { if (ok) *ok = true; return QRectF(x, y, width, height); diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index bc0515e..1becbbf 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -1171,28 +1171,6 @@ void Transform::project(const TemplateList &src, TemplateList &dst) const futures.waitForFinished(); } -static void _backProject(const Transform *transform, const Template *dst, Template *src) -{ - try { - transform->backProject(*dst, *src); - } catch (...) { - qWarning("Exception triggered when processing %s with transform %s", qPrintable(src->file.flat()), qPrintable(transform->objectName())); - *src = Template(dst->file); - src->file.set("FTE", true); - } -} - -void Transform::backProject(const TemplateList &dst, TemplateList &src) const -{ - src.reserve(dst.size()); - for (int i=0; i futures; - for (int i=0; i Transform::getChildren() const { QList output; diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 4ae25a7..a5171b2 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -602,13 +602,6 @@ public: BR_PROPERTY(int, blockSize, parallelism * ((sizeof(void*) == 4) ? 128 : 1024)) /*! - * \brief true if backProject should be used instead of project (the algorithm should be inverted) - */ - Q_PROPERTY(bool backProject READ get_backProject WRITE set_backProject RESET reset_backProject) - BR_PROPERTY(bool, backProject, false) - - - /*! * \brief If \c true no messages will be sent to the terminal, \c false by default. */ Q_PROPERTY(bool quiet READ get_quiet WRITE set_quiet RESET reset_quiet) @@ -1034,6 +1027,10 @@ private: * @{ */ +/*! + * \brief For asynchronous events during template projection. + * \see #Transform::getEvent + */ class TemplateEvent : public QObject { Q_OBJECT @@ -1048,7 +1045,6 @@ signals: void theSignal(const Template & output) const; }; - /*! * \brief Plugin base class for processing a template. * @@ -1078,8 +1074,6 @@ public: virtual void train(const TemplateList &data) = 0; /*!< \brief Train the transform. */ virtual void project(const Template &src, Template &dst) const = 0; /*!< \brief Apply the transform. */ virtual void project(const TemplateList &src, TemplateList &dst) const; /*!< \brief Apply the transform. */ - virtual void backProject(const Template &dst, Template &src) const { src = dst; } /*!< \brief Invert the transform. */ - virtual void backProject(const TemplateList &dst, TemplateList &src) const; /*!< \brief Invert the transform. */ /*!< \brief Apply the transform, may update the transform's internal state */ virtual void projectUpdate(const Template &src, Template &dst) diff --git a/openbr/plugins/cascade.cpp b/openbr/plugins/cascade.cpp index f54e240..e05d9d2 100644 --- a/openbr/plugins/cascade.cpp +++ b/openbr/plugins/cascade.cpp @@ -98,7 +98,7 @@ class CascadeTransform : public UntrainableMetaTransform for (size_t j=0; j j) - u.file.set("Confidence", rejectLevels[j]*1000.0 + levelWeights[j]*1.0); + u.file.set("Confidence", rejectLevels[j]*levelWeights[j]); const QRectF rect = OpenCVUtils::fromRect(rects[j]); u.file.appendRect(rect); u.file.set(model, rect); diff --git a/openbr/plugins/eigen3.cpp b/openbr/plugins/eigen3.cpp index d1b877b..89765db 100644 --- a/openbr/plugins/eigen3.cpp +++ b/openbr/plugins/eigen3.cpp @@ -59,21 +59,6 @@ public: PCATransform() : keep(0.95), drop(0), whiten(false) {} private: - /* - void backProject(const Template &src, Template &dst) const - { - const cv::Mat &m = src; - dst = cv::Mat(originalRows, m.rows*m.cols/originalRows, CV_32FC1); - - // Map Eigen into OpenCV - Eigen::Map inMap(m.ptr(), keep, 1); - Eigen::Map outMap(dst.m().ptr(), m.rows*m.cols, 1); - - // Do projection - outMap = (eVecs * inMap) + mean; - } - */ - double residualReconstructionError(const Template &src) const { Template proj; diff --git a/openbr/plugins/meta.cpp b/openbr/plugins/meta.cpp index ab82d05..b5e14cb 100644 --- a/openbr/plugins/meta.cpp +++ b/openbr/plugins/meta.cpp @@ -129,26 +129,6 @@ class PipeTransform : public CompositeTransform } } - void backProject(const Template &dst, Template &src) const - { - // Backprojecting a time-varying transform is probably not going to work. - if (timeVarying()) qFatal("No backProject defined for time-varying transform"); - - src = dst; - // Reverse order in which transforms are processed - int length = transforms.length(); - for (int i=length-1; i>=0; i--) { - Transform *f = transforms.at(i); - try { - src >> *f; - } catch (...) { - qWarning("Exception triggered when processing %s with transform %s", qPrintable(dst.file.flat()), qPrintable(f->objectName())); - src = Template(src.file); - src.file.set("FTE", true); - } - } - } - void projectUpdate(const Template &src, Template &dst) { dst = src; @@ -306,8 +286,6 @@ class ForkTransform : public CompositeTransform futures.waitForFinished(); } - void backProject(const Template &dst, Template &src) const {Transform::backProject(dst, src);} - // same as _project, but calls projectUpdate on sub-transforms void projectupdate(const Template & src, Template & dst) {