Commit 57423a277d90de6b7f9c46279013ffc746e125bd
1 parent
32b35bfb
Updated stasm to allow pinning of points
Showing
6 changed files
with
36 additions
and
53 deletions
openbr/core/eval.cpp
| ... | ... | @@ -114,8 +114,6 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) |
| 114 | 114 | |
| 115 | 115 | float result = -1; |
| 116 | 116 | |
| 117 | - qDebug() << simmat.rows << simmat.cols; | |
| 118 | - | |
| 119 | 117 | // Make comparisons |
| 120 | 118 | QList<Comparison> comparisons; comparisons.reserve(simmat.rows*simmat.cols); |
| 121 | 119 | int genuineCount = 0, impostorCount = 0, numNaNs = 0; |
| ... | ... | @@ -178,7 +176,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) |
| 178 | 176 | if ((falsePositives > previousFalsePositives) && |
| 179 | 177 | (truePositives > previousTruePositives)) { |
| 180 | 178 | // Restrict the extreme ends of the curve |
| 181 | - //if ((truePositives >= 10) && (falsePositives < impostorCount/2)) | |
| 179 | + if ((truePositives >= 10) && (falsePositives < impostorCount/2)) | |
| 182 | 180 | operatingPoints.append(OperatingPoint(thresh, float(falsePositives)/impostorCount, float(truePositives)/genuineCount)); |
| 183 | 181 | previousFalsePositives = falsePositives; |
| 184 | 182 | previousTruePositives = truePositives; | ... | ... |
openbr/core/plot.cpp
| ... | ... | @@ -228,7 +228,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) |
| 228 | 228 | QString(", xlab=\"False Accept Rate\", ylab=\"True Accept Rate\") + theme_minimal()") + |
| 229 | 229 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 230 | 230 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 231 | - QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_log10(labels=percent) + annotation_logticks()\n\n"))); | |
| 231 | + QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_continuous(labels=percent) + annotation_logticks(sides=\"b\")\n\n"))); | |
| 232 | 232 | |
| 233 | 233 | p.file.write(qPrintable(QString("qplot(X, Y, data=DET%1").arg((p.major.smooth || p.minor.smooth) ? ", geom=\"smooth\", method=loess, level=0.99" : ", geom=\"line\"") + |
| 234 | 234 | (p.major.size > 1 ? QString(", colour=factor(%1)").arg(p.major.header) : QString()) + |
| ... | ... | @@ -236,7 +236,7 @@ bool Plot(const QStringList &files, const File &destination, bool show) |
| 236 | 236 | QString(", xlab=\"False Accept Rate\", ylab=\"False Reject Rate\") + geom_abline(alpha=0.5, colour=\"grey\", linetype=\"dashed\") + theme_minimal()") + |
| 237 | 237 | (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) + |
| 238 | 238 | (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) + |
| 239 | - QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_continuous(labels=percent)\n\n"))); | |
| 239 | + QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_log10(labels=percent) + annotation_logticks()\n\n"))); | |
| 240 | 240 | |
| 241 | 241 | p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") + |
| 242 | 242 | QString(", xlab=\"Score%1\"").arg((p.flip ? p.major.size : p.minor.size) > 1 ? " / " + (p.flip ? p.major.header : p.minor.header) : QString()) + | ... | ... |
openbr/plugins/gallery.cpp
openbr/plugins/misc.cpp
| ... | ... | @@ -382,35 +382,6 @@ BR_REGISTER(Transform, RegexPropertyTransform) |
| 382 | 382 | |
| 383 | 383 | /*! |
| 384 | 384 | * \ingroup transforms |
| 385 | - * \brief Calculate metadata statistics | |
| 386 | - * \author Scott Klum \cite sklum | |
| 387 | - */ | |
| 388 | -class MetadataStatisticsTransform : public UntrainableTransform | |
| 389 | -{ | |
| 390 | - Q_OBJECT | |
| 391 | - Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false) | |
| 392 | - BR_PROPERTY(QStringList, keys, QStringList()) | |
| 393 | - | |
| 394 | - mutable QHash<QString,int> statHash; | |
| 395 | - | |
| 396 | - void project(const Template &src, Template &dst) const | |
| 397 | - { | |
| 398 | - dst = src; | |
| 399 | - foreach (const QString &key, keys) { | |
| 400 | - QString value = src.file.get<QString>(key, QString()); | |
| 401 | - | |
| 402 | - if (value.isEmpty()) continue; | |
| 403 | - int count = statHash.value(value,0); | |
| 404 | - statHash.insert(value,count+1); | |
| 405 | - } | |
| 406 | - foreach (const QString &key, statHash.keys()) qDebug() << key << statHash.value(key); | |
| 407 | - } | |
| 408 | -}; | |
| 409 | - | |
| 410 | -BR_REGISTER(Transform, MetadataStatisticsTransform) | |
| 411 | - | |
| 412 | -/*! | |
| 413 | - * \ingroup transforms | |
| 414 | 385 | * \brief Store the last matrix of the input template as a metadata key with input property name. |
| 415 | 386 | * \author Charles Otto \cite caotto |
| 416 | 387 | */ | ... | ... |
openbr/plugins/regions.cpp
| ... | ... | @@ -348,7 +348,6 @@ class RectFromPointsTransform : public UntrainableTransform |
| 348 | 348 | |
| 349 | 349 | if (crop) dst.m() = src.m()(Rect(std::max(0.0, minX - deltaWidth/2.0), std::max(0.0, minY - deltaHeight/2.0), std::min((double)src.m().cols, width), std::min((double)src.m().rows, height))); |
| 350 | 350 | else { |
| 351 | - qDebug() << QRectF(std::max(0.0, minX - deltaWidth/2.0), std::max(0.0, minY - deltaHeight/2.0), std::min((double)src.m().cols, width), std::min((double)src.m().rows, height)).size(); | |
| 352 | 351 | dst.file.appendRect(QRectF(std::max(0.0, minX - deltaWidth/2.0), std::max(0.0, minY - deltaHeight/2.0), std::min((double)src.m().cols, width), std::min((double)src.m().rows, height))); |
| 353 | 352 | dst.m() = src.m(); |
| 354 | 353 | } | ... | ... |
openbr/plugins/stasm4.cpp
| ... | ... | @@ -58,6 +58,8 @@ class StasmTransform : public UntrainableTransform |
| 58 | 58 | BR_PROPERTY(bool, stasm3Format, false) |
| 59 | 59 | Q_PROPERTY(bool clearLandmarks READ get_clearLandmarks WRITE set_clearLandmarks RESET reset_clearLandmarks STORED false) |
| 60 | 60 | BR_PROPERTY(bool, clearLandmarks, false) |
| 61 | + Q_PROPERTY(QStringList pinEyes READ get_pinEyes WRITE set_pinEyes RESET reset_pinEyes STORED false) | |
| 62 | + BR_PROPERTY(QStringList, pinEyes, QStringList()) | |
| 61 | 63 | |
| 62 | 64 | Resource<StasmCascadeClassifier> stasmCascadeResource; |
| 63 | 65 | |
| ... | ... | @@ -79,28 +81,41 @@ class StasmTransform : public UntrainableTransform |
| 79 | 81 | int nLandmarks = stasm_NLANDMARKS; |
| 80 | 82 | float landmarks[2 * stasm_NLANDMARKS]; |
| 81 | 83 | |
| 82 | - bool pinned = true; | |
| 84 | + if (!pinEyes.isEmpty()) { | |
| 85 | + // Two use cases are accounted for: | |
| 86 | + // 1. Pin eyes without normalization: in this case the string list should contain the KEYS for right then left eyes, respectively. | |
| 87 | + // 2. Pin eyes with normalization: in this case the string list should contain the COORDINATES of the right then left eyes, respectively. | |
| 88 | + // Note that for case 2, if Affine_0 and Affine_1 are not present (indicating no normalization has taken place), we default to stasm_search_single. | |
| 83 | 89 | |
| 84 | - if (pinned) { | |
| 85 | - if (src.file.contains("Affine_0")) { | |
| 86 | - float eyes[2 * stasm_NLANDMARKS]; | |
| 90 | + bool ok = false; | |
| 91 | + QPointF rightEye; | |
| 92 | + QPointF leftEye; | |
| 87 | 93 | |
| 88 | - for (int i = 0; i < nLandmarks; i++) { | |
| 89 | - if (i == 38) { eyes[2*i] = 66.24; eyes[2*i+1] = 126; } | |
| 90 | - else if (i == 39) { eyes[2*i] = 125.76; eyes[2*i+1] = 126; } | |
| 91 | - else { eyes[2*i] = 0; eyes[2*i+1] = 0; } | |
| 94 | + if (src.file.contains("Affine_0") && src.file.contains("Affine_1")) { | |
| 95 | + rightEye = QtUtils::toPoint(pinEyes.at(0),&ok); | |
| 96 | + leftEye = QtUtils::toPoint(pinEyes.at(1),&ok); | |
| 97 | + } | |
| 98 | + | |
| 99 | + if (!ok) { | |
| 100 | + rightEye = QtUtils::toPoint(src.file.get<QString>(pinEyes.at(0), QString()),&ok); | |
| 101 | + leftEye = QtUtils::toPoint(src.file.get<QString>(pinEyes.at(1), QString()),&ok); | |
| 92 | 102 | } |
| 93 | 103 | |
| 104 | + float eyes[2 * stasm_NLANDMARKS]; | |
| 105 | + | |
| 106 | + if (ok) { | |
| 107 | + for (int i = 0; i < nLandmarks; i++) { | |
| 108 | + if (i == 38) /*Stasm Right Eye*/ { eyes[2*i] = rightEye.x(); eyes[2*i+1] = rightEye.y(); } | |
| 109 | + else if (i == 39) /*Stasm Left Eye*/ { eyes[2*i] = leftEye.x(); eyes[2*i+1] = leftEye.y(); } | |
| 110 | + else { eyes[2*i] = 0; eyes[2*i+1] = 0; } | |
| 111 | + } | |
| 112 | + } else qFatal("Unable to interpret pinned eyes."); | |
| 113 | + | |
| 94 | 114 | stasm_search_pinned(landmarks, eyes, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, NULL); |
| 95 | 115 | |
| 116 | + // The ASM in Stasm is guaranteed to converge in this case | |
| 96 | 117 | foundface = 1; |
| 97 | - } else { | |
| 98 | - qDebug() << "Single search..."; | |
| 99 | - stasm_search_single(&foundface, landmarks, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); | |
| 100 | - } | |
| 101 | - } else { | |
| 102 | - stasm_search_single(&foundface, landmarks, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); | |
| 103 | - } | |
| 118 | + } stasm_search_single(&foundface, landmarks, reinterpret_cast<const char*>(src.m().data), src.m().cols, src.m().rows, *stasmCascade, NULL, NULL); | |
| 104 | 119 | |
| 105 | 120 | if (stasm3Format) { |
| 106 | 121 | nLandmarks = 76; |
| ... | ... | @@ -109,6 +124,7 @@ class StasmTransform : public UntrainableTransform |
| 109 | 124 | |
| 110 | 125 | stasmCascadeResource.release(stasmCascade); |
| 111 | 126 | |
| 127 | + // For convenience, if these are the only points/rects we want to deal with as the algorithm progresses | |
| 112 | 128 | if (clearLandmarks) { |
| 113 | 129 | dst.file.clearPoints(); |
| 114 | 130 | dst.file.clearRects(); |
| ... | ... | @@ -124,8 +140,6 @@ class StasmTransform : public UntrainableTransform |
| 124 | 140 | else if (i == 39) dst.file.set("StasmLeftEye", point); |
| 125 | 141 | } |
| 126 | 142 | } |
| 127 | - | |
| 128 | - dst.m() = src.m(); | |
| 129 | 143 | } |
| 130 | 144 | }; |
| 131 | 145 | ... | ... |