diff --git a/data/README.md b/data/README.md index d5808fa..7f6bebc 100644 --- a/data/README.md +++ b/data/README.md @@ -7,9 +7,9 @@ * [FRGC](FRGC/README.md) * [LFW](LFW/LFW.md) * [MEDS](MEDS/README.md) +* [MNIST](MNIST/README.md) * [PCSO](PCSO/README.md) -For both practical and legal reasons we don't include images in this repository. -Open source datasets can be downloaded using `../scripts/downloadDatasets.sh`. +For both practical and legal reasons we only include images for some of the datasets in this repository. Researchers should contact the respective owners of the other datasets in order to obtain a copy. The provided sigsets indicate how the images are expected to be arranged in directories, generally following the conventions established by the original authors. diff --git a/openbr/core/classify.cpp b/openbr/core/classify.cpp index ad2937e..e54fbc3 100644 --- a/openbr/core/classify.cpp +++ b/openbr/core/classify.cpp @@ -45,8 +45,12 @@ void br::EvalClassification(const QString &predictedInput, const QString &truthI qFatal("Input order mismatch."); // Typically these lists will be of length one, but this generalization allows measuring multi-class labeling accuracy. - QStringList predictedSubjects = predicted[i].file.get("Subject"); - QStringList trueSubjects = truth[i].file.get("Subject"); + QString predictedSubject = predicted[i].file.subject(); + QString trueSubject = truth[i].file.subject(); + + QStringList predictedSubjects(predictedSubject); + QStringList trueSubjects(trueSubject); + foreach (const QString &subject, trueSubjects.toVector() /* Hack to copy the list. */) { if (predictedSubjects.contains(subject)) { counters[subject].truePositive++; diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 1312dd1..09e5370 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -248,9 +248,8 @@ struct AlgorithmCore if (!partitionSizes.empty()) targetPartitions = targets.partition(partitionSizes); else targetPartitions.append(targets); - if (queryPartitions[i].first().size() != targetPartitions[i].first().size()) qFatal("Query and target templates have different number of matrices."); - outputs[i]->setBlock(queryBlock, targetBlock); + distance->compare(targetPartitions[i], queryPartitions[i], outputs[i]); Globals->currentStep += double(targets.size()) * double(queries.size()); diff --git a/openbr/core/plot.cpp b/openbr/core/plot.cpp index c0e3c4d..51e5439 100644 --- a/openbr/core/plot.cpp +++ b/openbr/core/plot.cpp @@ -248,24 +248,29 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); + // Write SD & KDE points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); QList sampledGenuineScores; sampledGenuineScores.reserve(points); QList sampledImpostorScores; sampledImpostorScores.reserve(points); - for (int i=0; i::max()) genuineScore = minGenuineScore; - if (impostorScore == -std::numeric_limits::max()) impostorScore = minImpostorScore; - lines.append(QString("SD,%1,Genuine").arg(QString::number(genuineScore))); - lines.append(QString("SD,%1,Impostor").arg(QString::number(impostorScore))); - sampledGenuineScores.append(genuineScore); - sampledImpostorScores.append(impostorScore); + + if (points > 1) { + for (int i=0; i::max()) genuineScore = minGenuineScore; + if (impostorScore == -std::numeric_limits::max()) impostorScore = minImpostorScore; + lines.append(QString("SD,%1,Genuine").arg(QString::number(genuineScore))); + lines.append(QString("SD,%1,Impostor").arg(QString::number(impostorScore))); + sampledGenuineScores.append(genuineScore); + sampledImpostorScores.append(impostorScore); + } } // Write Cumulative Match Characteristic (CMC) curve - const int Max_Retrieval = 100; + const int Max_Retrieval = 200; const int Report_Retrieval = 5; + float reportRetrievalRate = -1; for (int i=1; i<=Max_Retrieval; i++) { int realizedReturns = 0, possibleReturns = 0; @@ -467,6 +472,8 @@ struct RPlot } }; +// Does not work if dataset folder starts with a number + bool Plot(const QStringList &files, const br::File &destination, bool show) { qDebug("Plotting %d file(s) to %s", files.size(), qPrintable(destination)); diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 61b760c..18c1688 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -52,7 +52,7 @@ QString File::flat() const const QVariant value = this->value(key); if (value.isNull()) values.append(key); else { - if (QString(value.typeName()) == "QVariantList" || QString(value.typeName()) == "QStringList") { + if (QString(value.typeName()) == "QVariantList") { QStringList variants; foreach(const QVariant &variant, qvariant_cast(value)) { variants.append(QtUtils::toString(variant)); @@ -137,7 +137,7 @@ QVariant File::value(const QString &key) const QVariant File::parse(const QString &value) { - bool ok; + bool ok = false; const QPointF point = QtUtils::toPoint(value, &ok); if (ok) return point; const QRectF rect = QtUtils::toRect(value, &ok); @@ -183,6 +183,11 @@ float File::label() const if (s.isNull()) return -1; const QString subject = s.toString(); + + bool is_num = false; + float num = subject.toFloat(&is_num); + if (is_num) return num; + static QMutex mutex; QMutexLocker mutexLocker(&mutex); if (!Globals->subjects.contains(subject)) @@ -1003,7 +1008,7 @@ void Output::reformat(const FileList &targetFiles, const FileList &queryFiles, c const int columns = targetFiles.size(); for (int i=0; isetRelative(m.at(i,i), i, j); + o->setRelative(m.at(i,j), i, j); } /* Output - protected methods */ diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index e5290b4..f6a2419 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -410,7 +410,7 @@ struct TemplateList : public QList