From 1bff5f2f8623f1c1355ca90228940def28ab5944 Mon Sep 17 00:00:00 2001 From: Josh Klontz Date: Wed, 10 May 2017 14:43:17 -0600 Subject: [PATCH] EvalLandmarking now corrects for systematic landmark bias --- openbr/core/eval.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++------- openbr/core/qtutils.cpp | 5 +++++ openbr/core/qtutils.h | 1 + 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/openbr/core/eval.cpp b/openbr/core/eval.cpp index a5faf9f..7af2383 100755 --- a/openbr/core/eval.cpp +++ b/openbr/core/eval.cpp @@ -850,7 +850,7 @@ float EvalLandmarking(const QString &predictedGallery, const QString &truthGalle QStringList truthNames = File::get(truth, "name"); int skipped = 0; - QList< QList > pointErrors; + QList< QList > pointErrorMagnitudes, pointErrorOrientations; QList imageErrors; QList normalizedLengths; for (int i=0; i= truthPoints.size()) qFatal("Normalization index A is out of range."); if (normalizationIndexB >= truthPoints.size()) qFatal("Normalization index B is out of range."); const float normalizedLength = QtUtils::euclideanLength(truthPoints[normalizationIndexB] - truthPoints[normalizationIndexA]); + const float normalizedOrientation = QtUtils::orientation(truthPoints[normalizationIndexB], truthPoints[normalizationIndexA]); if (predictedPoints.size() != truthPoints.size() || qIsNaN(normalizedLength)) { predicted.removeAt(i); @@ -886,8 +887,10 @@ float EvalLandmarking(const QString &predictedGallery, const QString &truthGalle continue; } - while (pointErrors.size() < predictedPoints.size()) - pointErrors.append(QList()); + while (pointErrorMagnitudes.size() < predictedPoints.size()) { + pointErrorMagnitudes.append(QList()); + pointErrorOrientations.append(QList()); + } // Want to know error for every image. normalizedLengths.append(normalizedLength); @@ -897,7 +900,8 @@ float EvalLandmarking(const QString &predictedGallery, const QString &truthGalle const float error = QtUtils::euclideanLength(predictedPoints[j] - truthPoints[j])/normalizedLength; if (!qIsNaN(error)) { totalError += error; - pointErrors[j].append(error); + pointErrorMagnitudes[j].append(error); + pointErrorOrientations[j].append(QtUtils::orientation(predictedPoints[j], truthPoints[j]) - normalizedOrientation); totalCount++; } } @@ -906,7 +910,47 @@ float EvalLandmarking(const QString &predictedGallery, const QString &truthGalle qDebug() << "Skipped" << skipped << "files due to point size mismatch or NaN normalized length."; - QList averagePointErrors; averagePointErrors.reserve(pointErrors.size()); + // Adjust the point error to not penalize for systematic biases... + // ... by first calculating the average bias for each point + QList averagePointBiases; + for (int i=0; i &magnitudes = pointErrorMagnitudes[i]; + const QList &orientations = pointErrorOrientations[i]; + QPointF cumulativePointBias; + for (int j=0; j &magnitudes = pointErrorMagnitudes[i]; + QList &orientations = pointErrorOrientations[i]; + const QPointF &bias = averagePointBiases[i]; + for (int j=0; j averagePointErrors; averagePointErrors.reserve(pointErrorMagnitudes.size()); QStringList lines; lines.append("Plot,X,Y"); @@ -948,8 +992,8 @@ float EvalLandmarking(const QString &predictedGallery, const QString &truthGalle lines.append("EXP,"+filePath+":"+predicted[exampleIndices[i].second].file.name+","+QString::number(exampleIndices[i].first)); } - for (int i=0; i &pointError = pointErrors[i]; + for (int i=0; i &pointError = pointErrorMagnitudes[i]; std::sort(pointError.begin(), pointError.end()); averagePointErrors.append(Common::Mean(pointError)); const int keep = qMin(Max_Points, pointError.size()); diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index 38b46a4..c6272b8 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -462,6 +462,11 @@ float euclideanLength(const QPointF &point) return sqrt(pow(point.x(), 2) + pow(point.y(), 2)); } +float orientation(const QPointF &pointA, const QPointF &pointB) +{ + return atan2(pointB.y() - pointA.y(), pointB.x() - pointA.x()); +} + float overlap(const QRectF &r, const QRectF &s) { QRectF intersection = r & s; diff --git a/openbr/core/qtutils.h b/openbr/core/qtutils.h index 607d82a..89513ec 100644 --- a/openbr/core/qtutils.h +++ b/openbr/core/qtutils.h @@ -90,6 +90,7 @@ namespace QtUtils /**** Point Utilities ****/ float euclideanLength(const QPointF &point); + float orientation(const QPointF &pointA, const QPointF &pointB); /**** Rect Utilities ****/ float overlap(const QRectF &r, const QRectF &s); -- libgit2 0.21.4