Commit 05d60bddb89cbfe7dd08a88b4572d51b7d05aefc
Merge branch 'master' of https://github.com/biometrics/openbr into no_scale
Showing
14 changed files
with
157 additions
and
47 deletions
data/README.md
| @@ -7,9 +7,9 @@ | @@ -7,9 +7,9 @@ | ||
| 7 | * [FRGC](FRGC/README.md) | 7 | * [FRGC](FRGC/README.md) |
| 8 | * [LFW](LFW/LFW.md) | 8 | * [LFW](LFW/LFW.md) |
| 9 | * [MEDS](MEDS/README.md) | 9 | * [MEDS](MEDS/README.md) |
| 10 | +* [MNIST](MNIST/README.md) | ||
| 10 | * [PCSO](PCSO/README.md) | 11 | * [PCSO](PCSO/README.md) |
| 11 | 12 | ||
| 12 | -For both practical and legal reasons we don't include images in this repository. | ||
| 13 | -Open source datasets can be downloaded using `../scripts/downloadDatasets.sh`. | 13 | +For both practical and legal reasons we only include images for some of the datasets in this repository. |
| 14 | Researchers should contact the respective owners of the other datasets in order to obtain a copy. | 14 | Researchers should contact the respective owners of the other datasets in order to obtain a copy. |
| 15 | The provided sigsets indicate how the images are expected to be arranged in directories, generally following the conventions established by the original authors. | 15 | The provided sigsets indicate how the images are expected to be arranged in directories, generally following the conventions established by the original authors. |
openbr/core/classify.cpp
| @@ -45,8 +45,12 @@ void br::EvalClassification(const QString &predictedInput, const QString &truthI | @@ -45,8 +45,12 @@ void br::EvalClassification(const QString &predictedInput, const QString &truthI | ||
| 45 | qFatal("Input order mismatch."); | 45 | qFatal("Input order mismatch."); |
| 46 | 46 | ||
| 47 | // Typically these lists will be of length one, but this generalization allows measuring multi-class labeling accuracy. | 47 | // Typically these lists will be of length one, but this generalization allows measuring multi-class labeling accuracy. |
| 48 | - QStringList predictedSubjects = predicted[i].file.get<QStringList>("Subject"); | ||
| 49 | - QStringList trueSubjects = truth[i].file.get<QStringList>("Subject"); | 48 | + QString predictedSubject = predicted[i].file.subject(); |
| 49 | + QString trueSubject = truth[i].file.subject(); | ||
| 50 | + | ||
| 51 | + QStringList predictedSubjects(predictedSubject); | ||
| 52 | + QStringList trueSubjects(trueSubject); | ||
| 53 | + | ||
| 50 | foreach (const QString &subject, trueSubjects.toVector() /* Hack to copy the list. */) { | 54 | foreach (const QString &subject, trueSubjects.toVector() /* Hack to copy the list. */) { |
| 51 | if (predictedSubjects.contains(subject)) { | 55 | if (predictedSubjects.contains(subject)) { |
| 52 | counters[subject].truePositive++; | 56 | counters[subject].truePositive++; |
openbr/core/core.cpp
| @@ -248,9 +248,8 @@ struct AlgorithmCore | @@ -248,9 +248,8 @@ struct AlgorithmCore | ||
| 248 | if (!partitionSizes.empty()) targetPartitions = targets.partition(partitionSizes); | 248 | if (!partitionSizes.empty()) targetPartitions = targets.partition(partitionSizes); |
| 249 | else targetPartitions.append(targets); | 249 | else targetPartitions.append(targets); |
| 250 | 250 | ||
| 251 | - if (queryPartitions[i].first().size() != targetPartitions[i].first().size()) qFatal("Query and target templates have different number of matrices."); | ||
| 252 | - | ||
| 253 | outputs[i]->setBlock(queryBlock, targetBlock); | 251 | outputs[i]->setBlock(queryBlock, targetBlock); |
| 252 | + | ||
| 254 | distance->compare(targetPartitions[i], queryPartitions[i], outputs[i]); | 253 | distance->compare(targetPartitions[i], queryPartitions[i], outputs[i]); |
| 255 | 254 | ||
| 256 | Globals->currentStep += double(targets.size()) * double(queries.size()); | 255 | Globals->currentStep += double(targets.size()) * double(queries.size()); |
openbr/core/plot.cpp
| @@ -248,24 +248,29 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | @@ -248,24 +248,29 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | ||
| 248 | lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); | 248 | lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3)))); |
| 249 | lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); | 249 | lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3)))); |
| 250 | 250 | ||
| 251 | + | ||
| 251 | // Write SD & KDE | 252 | // Write SD & KDE |
| 252 | points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); | 253 | points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); |
| 253 | QList<double> sampledGenuineScores; sampledGenuineScores.reserve(points); | 254 | QList<double> sampledGenuineScores; sampledGenuineScores.reserve(points); |
| 254 | QList<double> sampledImpostorScores; sampledImpostorScores.reserve(points); | 255 | QList<double> sampledImpostorScores; sampledImpostorScores.reserve(points); |
| 255 | - for (int i=0; i<points; i++) { | ||
| 256 | - float genuineScore = genuines[double(i) / double(points-1) * double(genuines.size()-1)]; | ||
| 257 | - float impostorScore = impostors[double(i) / double(points-1) * double(impostors.size()-1)]; | ||
| 258 | - if (genuineScore == -std::numeric_limits<float>::max()) genuineScore = minGenuineScore; | ||
| 259 | - if (impostorScore == -std::numeric_limits<float>::max()) impostorScore = minImpostorScore; | ||
| 260 | - lines.append(QString("SD,%1,Genuine").arg(QString::number(genuineScore))); | ||
| 261 | - lines.append(QString("SD,%1,Impostor").arg(QString::number(impostorScore))); | ||
| 262 | - sampledGenuineScores.append(genuineScore); | ||
| 263 | - sampledImpostorScores.append(impostorScore); | 256 | + |
| 257 | + if (points > 1) { | ||
| 258 | + for (int i=0; i<points; i++) { | ||
| 259 | + float genuineScore = genuines[double(i) / double(points-1) * double(genuines.size()-1)]; | ||
| 260 | + float impostorScore = impostors[double(i) / double(points-1) * double(impostors.size()-1)]; | ||
| 261 | + if (genuineScore == -std::numeric_limits<float>::max()) genuineScore = minGenuineScore; | ||
| 262 | + if (impostorScore == -std::numeric_limits<float>::max()) impostorScore = minImpostorScore; | ||
| 263 | + lines.append(QString("SD,%1,Genuine").arg(QString::number(genuineScore))); | ||
| 264 | + lines.append(QString("SD,%1,Impostor").arg(QString::number(impostorScore))); | ||
| 265 | + sampledGenuineScores.append(genuineScore); | ||
| 266 | + sampledImpostorScores.append(impostorScore); | ||
| 267 | + } | ||
| 264 | } | 268 | } |
| 265 | 269 | ||
| 266 | // Write Cumulative Match Characteristic (CMC) curve | 270 | // Write Cumulative Match Characteristic (CMC) curve |
| 267 | - const int Max_Retrieval = 100; | 271 | + const int Max_Retrieval = 200; |
| 268 | const int Report_Retrieval = 5; | 272 | const int Report_Retrieval = 5; |
| 273 | + | ||
| 269 | float reportRetrievalRate = -1; | 274 | float reportRetrievalRate = -1; |
| 270 | for (int i=1; i<=Max_Retrieval; i++) { | 275 | for (int i=1; i<=Max_Retrieval; i++) { |
| 271 | int realizedReturns = 0, possibleReturns = 0; | 276 | int realizedReturns = 0, possibleReturns = 0; |
| @@ -467,6 +472,8 @@ struct RPlot | @@ -467,6 +472,8 @@ struct RPlot | ||
| 467 | } | 472 | } |
| 468 | }; | 473 | }; |
| 469 | 474 | ||
| 475 | +// Does not work if dataset folder starts with a number | ||
| 476 | + | ||
| 470 | bool Plot(const QStringList &files, const br::File &destination, bool show) | 477 | bool Plot(const QStringList &files, const br::File &destination, bool show) |
| 471 | { | 478 | { |
| 472 | qDebug("Plotting %d file(s) to %s", files.size(), qPrintable(destination)); | 479 | qDebug("Plotting %d file(s) to %s", files.size(), qPrintable(destination)); |
openbr/openbr_plugin.cpp
| @@ -52,7 +52,7 @@ QString File::flat() const | @@ -52,7 +52,7 @@ QString File::flat() const | ||
| 52 | const QVariant value = this->value(key); | 52 | const QVariant value = this->value(key); |
| 53 | if (value.isNull()) values.append(key); | 53 | if (value.isNull()) values.append(key); |
| 54 | else { | 54 | else { |
| 55 | - if (QString(value.typeName()) == "QVariantList" || QString(value.typeName()) == "QStringList") { | 55 | + if (QString(value.typeName()) == "QVariantList") { |
| 56 | QStringList variants; | 56 | QStringList variants; |
| 57 | foreach(const QVariant &variant, qvariant_cast<QVariantList>(value)) { | 57 | foreach(const QVariant &variant, qvariant_cast<QVariantList>(value)) { |
| 58 | variants.append(QtUtils::toString(variant)); | 58 | variants.append(QtUtils::toString(variant)); |
| @@ -137,7 +137,7 @@ QVariant File::value(const QString &key) const | @@ -137,7 +137,7 @@ QVariant File::value(const QString &key) const | ||
| 137 | 137 | ||
| 138 | QVariant File::parse(const QString &value) | 138 | QVariant File::parse(const QString &value) |
| 139 | { | 139 | { |
| 140 | - bool ok; | 140 | + bool ok = false; |
| 141 | const QPointF point = QtUtils::toPoint(value, &ok); | 141 | const QPointF point = QtUtils::toPoint(value, &ok); |
| 142 | if (ok) return point; | 142 | if (ok) return point; |
| 143 | const QRectF rect = QtUtils::toRect(value, &ok); | 143 | const QRectF rect = QtUtils::toRect(value, &ok); |
| @@ -183,6 +183,11 @@ float File::label() const | @@ -183,6 +183,11 @@ float File::label() const | ||
| 183 | if (s.isNull()) return -1; | 183 | if (s.isNull()) return -1; |
| 184 | 184 | ||
| 185 | const QString subject = s.toString(); | 185 | const QString subject = s.toString(); |
| 186 | + | ||
| 187 | + bool is_num = false; | ||
| 188 | + float num = subject.toFloat(&is_num); | ||
| 189 | + if (is_num) return num; | ||
| 190 | + | ||
| 186 | static QMutex mutex; | 191 | static QMutex mutex; |
| 187 | QMutexLocker mutexLocker(&mutex); | 192 | QMutexLocker mutexLocker(&mutex); |
| 188 | if (!Globals->subjects.contains(subject)) | 193 | if (!Globals->subjects.contains(subject)) |
| @@ -1003,7 +1008,7 @@ void Output::reformat(const FileList &targetFiles, const FileList &queryFiles, c | @@ -1003,7 +1008,7 @@ void Output::reformat(const FileList &targetFiles, const FileList &queryFiles, c | ||
| 1003 | const int columns = targetFiles.size(); | 1008 | const int columns = targetFiles.size(); |
| 1004 | for (int i=0; i<rows; i++) | 1009 | for (int i=0; i<rows; i++) |
| 1005 | for (int j=0; j<columns; j++) | 1010 | for (int j=0; j<columns; j++) |
| 1006 | - o->setRelative(m.at<float>(i,i), i, j); | 1011 | + o->setRelative(m.at<float>(i,j), i, j); |
| 1007 | } | 1012 | } |
| 1008 | 1013 | ||
| 1009 | /* Output - protected methods */ | 1014 | /* Output - protected methods */ |
openbr/openbr_plugin.h
| @@ -410,7 +410,7 @@ struct TemplateList : public QList<Template> | @@ -410,7 +410,7 @@ struct TemplateList : public QList<Template> | ||
| 410 | sum+=partitionSizes[i]; | 410 | sum+=partitionSizes[i]; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | - if (sum != first().size()) qFatal("Partition sizes do not span template matrices properly"); | 413 | + if (sum != first().size()) qFatal("Partition sizes %i do not span template matrices %i properly", sum, first().size()); |
| 414 | 414 | ||
| 415 | foreach (const Template &t, *this) { | 415 | foreach (const Template &t, *this) { |
| 416 | int index = 0; | 416 | int index = 0; |
openbr/plugins/ct8.cpp
| @@ -11,9 +11,9 @@ | @@ -11,9 +11,9 @@ | ||
| 11 | #include <exception> | 11 | #include <exception> |
| 12 | #include <string> | 12 | #include <string> |
| 13 | #include <vector> | 13 | #include <vector> |
| 14 | -#include "openbr_internal.h" | ||
| 15 | 14 | ||
| 16 | -#include "core/resource.h" | 15 | +#include "openbr_internal.h" |
| 16 | +#include "openbr/core/resource.h" | ||
| 17 | 17 | ||
| 18 | using namespace cv; | 18 | using namespace cv; |
| 19 | using namespace br; | 19 | using namespace br; |
openbr/plugins/eigen3.cpp
| @@ -330,6 +330,7 @@ class LDATransform : public Transform | @@ -330,6 +330,7 @@ class LDATransform : public Transform | ||
| 330 | void train(const TemplateList &_trainingSet) | 330 | void train(const TemplateList &_trainingSet) |
| 331 | { | 331 | { |
| 332 | TemplateList trainingSet = TemplateList::relabel(_trainingSet); | 332 | TemplateList trainingSet = TemplateList::relabel(_trainingSet); |
| 333 | + | ||
| 333 | int instances = trainingSet.size(); | 334 | int instances = trainingSet.size(); |
| 334 | 335 | ||
| 335 | // Perform PCA dimensionality reduction | 336 | // Perform PCA dimensionality reduction |
openbr/plugins/format.cpp
| @@ -317,6 +317,7 @@ BR_REGISTER(Format, maskFormat) | @@ -317,6 +317,7 @@ BR_REGISTER(Format, maskFormat) | ||
| 317 | * \brief MATLAB <tt>.mat</tt> format. | 317 | * \brief MATLAB <tt>.mat</tt> format. |
| 318 | * \author Josh Klontz \cite jklontz | 318 | * \author Josh Klontz \cite jklontz |
| 319 | * http://www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf | 319 | * http://www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf |
| 320 | + * \note matFormat is known not to work with compressed matrices | ||
| 320 | */ | 321 | */ |
| 321 | class matFormat : public Format | 322 | class matFormat : public Format |
| 322 | { | 323 | { |
| @@ -324,12 +325,18 @@ class matFormat : public Format | @@ -324,12 +325,18 @@ class matFormat : public Format | ||
| 324 | 325 | ||
| 325 | struct Element | 326 | struct Element |
| 326 | { | 327 | { |
| 328 | + // It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing. | ||
| 329 | + // This ensures that you always know exactly what size integers you are reading and writing, no matter what the | ||
| 330 | + // underlying platform and architecture the application happens to be running on. | ||
| 331 | + // http://qt-project.org/doc/qt-4.8/datastreamformat.html | ||
| 327 | quint32 type, bytes; | 332 | quint32 type, bytes; |
| 328 | QByteArray data; | 333 | QByteArray data; |
| 329 | Element() : type(0), bytes(0) {} | 334 | Element() : type(0), bytes(0) {} |
| 330 | Element(QDataStream &stream) | 335 | Element(QDataStream &stream) |
| 331 | : type(0), bytes(0) | 336 | : type(0), bytes(0) |
| 332 | { | 337 | { |
| 338 | + // Read first 4 bytes into type (32 bit integer), | ||
| 339 | + // specifying the type of data used | ||
| 333 | if (stream.readRawData((char*)&type, 4) != 4) | 340 | if (stream.readRawData((char*)&type, 4) != 4) |
| 334 | qFatal("Unexpected end of file."); | 341 | qFatal("Unexpected end of file."); |
| 335 | 342 | ||
| @@ -340,11 +347,16 @@ class matFormat : public Format | @@ -340,11 +347,16 @@ class matFormat : public Format | ||
| 340 | bytes = bytes >> 16; | 347 | bytes = bytes >> 16; |
| 341 | } else { | 348 | } else { |
| 342 | // Regular format | 349 | // Regular format |
| 350 | + // Read 4 bytes into bytes (32 bit integer), | ||
| 351 | + // specifying the size of the element | ||
| 343 | if (stream.readRawData((char*)&bytes, 4) != 4) | 352 | if (stream.readRawData((char*)&bytes, 4) != 4) |
| 344 | qFatal("Unexpected end of file."); | 353 | qFatal("Unexpected end of file."); |
| 345 | } | 354 | } |
| 346 | 355 | ||
| 356 | + // Set the size of data to bytes | ||
| 347 | data.resize(bytes); | 357 | data.resize(bytes); |
| 358 | + | ||
| 359 | + // Read bytes amount of data from the file into data | ||
| 348 | if (int(bytes) != stream.readRawData(data.data(), bytes)) | 360 | if (int(bytes) != stream.readRawData(data.data(), bytes)) |
| 349 | qFatal("Unexpected end of file."); | 361 | qFatal("Unexpected end of file."); |
| 350 | 362 | ||
| @@ -372,8 +384,9 @@ class matFormat : public Format | @@ -372,8 +384,9 @@ class matFormat : public Format | ||
| 372 | while (!f.atEnd()) { | 384 | while (!f.atEnd()) { |
| 373 | Element element(f); | 385 | Element element(f); |
| 374 | 386 | ||
| 375 | - // miCOMPRESS | 387 | + // miCOMPRESSED |
| 376 | if (element.type == 15) { | 388 | if (element.type == 15) { |
| 389 | + // Prepend the number of bytes to element.data | ||
| 377 | element.data.prepend((char*)&element.bytes, 4); // Qt zlib wrapper requires this to preallocate the buffer | 390 | element.data.prepend((char*)&element.bytes, 4); // Qt zlib wrapper requires this to preallocate the buffer |
| 378 | QDataStream uncompressed(qUncompress(element.data)); | 391 | QDataStream uncompressed(qUncompress(element.data)); |
| 379 | element = Element(uncompressed); | 392 | element = Element(uncompressed); |
openbr/plugins/meta.cpp
| @@ -76,7 +76,7 @@ class PipeTransform : public CompositeTransform | @@ -76,7 +76,7 @@ class PipeTransform : public CompositeTransform | ||
| 76 | { | 76 | { |
| 77 | Q_OBJECT | 77 | Q_OBJECT |
| 78 | 78 | ||
| 79 | - void _projectPartial(Template *srcdst, int startIndex, int stopIndex) | 79 | + void _projectPartial(TemplateList *srcdst, int startIndex, int stopIndex) |
| 80 | { | 80 | { |
| 81 | for (int i=startIndex; i<stopIndex; i++) | 81 | for (int i=startIndex; i<stopIndex; i++) |
| 82 | *srcdst >> *transforms[i]; | 82 | *srcdst >> *transforms[i]; |
| @@ -87,6 +87,14 @@ class PipeTransform : public CompositeTransform | @@ -87,6 +87,14 @@ class PipeTransform : public CompositeTransform | ||
| 87 | if (!trainable) return; | 87 | if (!trainable) return; |
| 88 | 88 | ||
| 89 | TemplateList copy(data); | 89 | TemplateList copy(data); |
| 90 | + QList<TemplateList> singleItemLists; | ||
| 91 | + for (int i=0; i < copy.size(); i++) | ||
| 92 | + { | ||
| 93 | + TemplateList temp; | ||
| 94 | + temp.append(copy[i]); | ||
| 95 | + singleItemLists.append(temp); | ||
| 96 | + } | ||
| 97 | + | ||
| 90 | int i = 0; | 98 | int i = 0; |
| 91 | while (i < transforms.size()) { | 99 | while (i < transforms.size()) { |
| 92 | fprintf(stderr, "\n%s", qPrintable(transforms[i]->objectName())); | 100 | fprintf(stderr, "\n%s", qPrintable(transforms[i]->objectName())); |
| @@ -109,9 +117,14 @@ class PipeTransform : public CompositeTransform | @@ -109,9 +117,14 @@ class PipeTransform : public CompositeTransform | ||
| 109 | 117 | ||
| 110 | fprintf(stderr, " projecting..."); | 118 | fprintf(stderr, " projecting..."); |
| 111 | QFutureSynchronizer<void> futures; | 119 | QFutureSynchronizer<void> futures; |
| 112 | - for (int j=0; j<copy.size(); j++) | ||
| 113 | - futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, ©[j], i, nextTrainableTransform)); | 120 | + for (int j=0; j < singleItemLists.size(); j++) |
| 121 | + futures.addFuture(QtConcurrent::run(this, &PipeTransform::_projectPartial, &singleItemLists[j], i, nextTrainableTransform)); | ||
| 114 | futures.waitForFinished(); | 122 | futures.waitForFinished(); |
| 123 | + | ||
| 124 | + copy.clear(); | ||
| 125 | + for (int j=0; j < singleItemLists.size(); j++) | ||
| 126 | + copy.append(singleItemLists[j]); | ||
| 127 | + | ||
| 115 | i = nextTrainableTransform; | 128 | i = nextTrainableTransform; |
| 116 | } | 129 | } |
| 117 | } | 130 | } |
openbr/plugins/stasm.cpp
| @@ -34,7 +34,7 @@ BR_REGISTER(Initializer, StasmInitializer) | @@ -34,7 +34,7 @@ BR_REGISTER(Initializer, StasmInitializer) | ||
| 34 | * \author Scott Klum \cite sklum | 34 | * \author Scott Klum \cite sklum |
| 35 | */ | 35 | */ |
| 36 | // TODO: Use a global mutex to prevent concurrent calls to AsmSearchDll | 36 | // TODO: Use a global mutex to prevent concurrent calls to AsmSearchDll |
| 37 | -#if 0 | 37 | + |
| 38 | class StasmTransform : public UntrainableTransform | 38 | class StasmTransform : public UntrainableTransform |
| 39 | { | 39 | { |
| 40 | Q_OBJECT | 40 | Q_OBJECT |
| @@ -46,6 +46,9 @@ class StasmTransform : public UntrainableTransform | @@ -46,6 +46,9 @@ class StasmTransform : public UntrainableTransform | ||
| 46 | 46 | ||
| 47 | void project(const Template &src, Template &dst) const | 47 | void project(const Template &src, Template &dst) const |
| 48 | { | 48 | { |
| 49 | + static QMutex mutex; | ||
| 50 | + QMutexLocker locker(&mutex); | ||
| 51 | + | ||
| 49 | int nlandmarks; | 52 | int nlandmarks; |
| 50 | int landmarks[500]; | 53 | int landmarks[500]; |
| 51 | 54 | ||
| @@ -68,7 +71,6 @@ class StasmTransform : public UntrainableTransform | @@ -68,7 +71,6 @@ class StasmTransform : public UntrainableTransform | ||
| 68 | }; | 71 | }; |
| 69 | 72 | ||
| 70 | BR_REGISTER(Transform, StasmTransform) | 73 | BR_REGISTER(Transform, StasmTransform) |
| 71 | -#endif | ||
| 72 | 74 | ||
| 73 | } // namespace br | 75 | } // namespace br |
| 74 | 76 |
openbr/plugins/validate.cpp
| @@ -52,8 +52,13 @@ class CrossValidateTransform : public MetaTransform | @@ -52,8 +52,13 @@ class CrossValidateTransform : public MetaTransform | ||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | void project(const Template &src, Template &dst) const | 54 | void project(const Template &src, Template &dst) const |
| 55 | - { | ||
| 56 | - transforms[src.file.get<int>("Partition", 0)]->project(src, dst); | 55 | + { |
| 56 | + // If the src partition is greater than the number of training partitions, | ||
| 57 | + // assume that projection should be done using the same training data for all partitions. | ||
| 58 | + int partition = src.file.get<int>("Partition", 0); | ||
| 59 | + if (partition >= transforms.size()-1) partition = 0; | ||
| 60 | + | ||
| 61 | + transforms[partition]->project(src, dst); | ||
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | void store(QDataStream &stream) const | 64 | void store(QDataStream &stream) const |
share/openbr/openbr.bib
| @@ -40,6 +40,11 @@ | @@ -40,6 +40,11 @@ | ||
| 40 | Title = {{OpenBR} - {Open} {Biometric} {Recognition}}, | 40 | Title = {{OpenBR} - {Open} {Biometric} {Recognition}}, |
| 41 | Year = {2012}} | 41 | Year = {2012}} |
| 42 | 42 | ||
| 43 | +@misc{libface, | ||
| 44 | + Howpublished = {http://libface.sourceforge.net/file/Home.html}, | ||
| 45 | + Title = {libface}, | ||
| 46 | + Year = {2011}} | ||
| 47 | + | ||
| 43 | @misc{CT8, | 48 | @misc{CT8, |
| 44 | Author = {Cognitec}, | 49 | Author = {Cognitec}, |
| 45 | Howpublished = {www.cognitec-systems.de/FaceVACS-SDK.19.0.html}, | 50 | Howpublished = {www.cognitec-systems.de/FaceVACS-SDK.19.0.html}, |
| @@ -77,21 +82,49 @@ | @@ -77,21 +82,49 @@ | ||
| 77 | Year = 2000} | 82 | Year = 2000} |
| 78 | 83 | ||
| 79 | @manual{R, | 84 | @manual{R, |
| 80 | - Title = {R: A Language and Environment for Statistical Computing}, | ||
| 81 | - Author = {{R Core Team}}, | ||
| 82 | - Organization = {R Foundation for Statistical Computing}, | ||
| 83 | - Address = {Vienna, Austria}, | ||
| 84 | - Year = 2013, | ||
| 85 | - Url = {http://www.R-project.org}} | 85 | + Title = {R: A Language and Environment for Statistical Computing}, |
| 86 | + Author = {{R Core Team}}, | ||
| 87 | + Organization = {R Foundation for Statistical Computing}, | ||
| 88 | + Address = {Vienna, Austria}, | ||
| 89 | + Year = 2013, | ||
| 90 | + Url = {http://www.R-project.org}} | ||
| 86 | 91 | ||
| 87 | % Papers | 92 | % Papers |
| 93 | +@incollection{ahonen04, | ||
| 94 | + Author = {Ahonen, Timo and Hadid, Abdenour and Pietik{\"a}inen, Matti}, | ||
| 95 | + Booktitle = {Computer Vision-ECCV 2004}, | ||
| 96 | + Pages = {469-481}, | ||
| 97 | + Publisher = {Springer}, | ||
| 98 | + Title = {Face recognition with local binary patterns}, | ||
| 99 | + Year = {2004}} | ||
| 100 | + | ||
| 88 | @inproceedings{arandjelovic12, | 101 | @inproceedings{arandjelovic12, |
| 89 | - Author={Arandjelovic, R. and Zisserman, A.}, | ||
| 90 | - Booktitle={Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on}, | ||
| 91 | - Title={Three things everyone should know to improve object retrieval}, | ||
| 92 | - Month={June}, | ||
| 93 | - Year={2012}, | ||
| 94 | - Pages={2911-2918}} | 102 | + Author = {Arandjelovic, R. and Zisserman, A.}, |
| 103 | + Booktitle = {Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on}, | ||
| 104 | + Title = {Three things everyone should know to improve object retrieval}, | ||
| 105 | + Month = {June}, | ||
| 106 | + Year = {2012}, | ||
| 107 | + Pages = {2911-2918}} | ||
| 108 | + | ||
| 109 | +@article{bradski00, | ||
| 110 | + Author = {Bradski, Gary}, | ||
| 111 | + Journal = {Doctor Dobbs Journal}, | ||
| 112 | + Number = {11}, | ||
| 113 | + Pages = {120-126}, | ||
| 114 | + Publisher = {M AND T PUBLISHING INC}, | ||
| 115 | + Title = {The {OpenCV} library}, | ||
| 116 | + Volume = {25}, | ||
| 117 | + Year = {2000}} | ||
| 118 | + | ||
| 119 | +@article{belhumeur97, | ||
| 120 | + Author = {Belhumeur, Peter N. and Hespanha, Joao P. and Kriegman, David J.}, | ||
| 121 | + Journal = {Pattern Analysis and Machine Intelligence, IEEE Transactions on}, | ||
| 122 | + Number = {7}, | ||
| 123 | + Pages = {711-720}, | ||
| 124 | + Publisher = {IEEE}, | ||
| 125 | + Title = {Eigenfaces vs. fisherfaces: Recognition using class specific linear projection}, | ||
| 126 | + Volume = {19}, | ||
| 127 | + Year = {1997}} | ||
| 95 | 128 | ||
| 96 | @inproceedings{belhumeur11, | 129 | @inproceedings{belhumeur11, |
| 97 | Author = {Belhumeur, P.N. and Jacobs, D.W. and Kriegman, D.J. and Kumar, N.}, | 130 | Author = {Belhumeur, P.N. and Jacobs, D.W. and Kriegman, D.J. and Kumar, N.}, |
| @@ -136,11 +169,31 @@ | @@ -136,11 +169,31 @@ | ||
| 136 | Month = {jan}, | 169 | Month = {jan}, |
| 137 | Year = {2013}} | 170 | Year = {2013}} |
| 138 | 171 | ||
| 172 | +@article{hall09, | ||
| 173 | + Author = {Hall, Mark and Frank, Eibe and Holmes, Geoffrey and Pfahringer, Bernhard and Reutemann, Peter and Witten, Ian H}, | ||
| 174 | + Journal = {ACM SIGKDD Explorations Newsletter}, | ||
| 175 | + Number = {1}, | ||
| 176 | + Pages = {10-18}, | ||
| 177 | + Publisher = {ACM}, | ||
| 178 | + Title = {The WEKA data mining software: an update}, | ||
| 179 | + Volume = {11}, | ||
| 180 | + Year = {2009}} | ||
| 181 | + | ||
| 139 | @inproceedings{huang08, | 182 | @inproceedings{huang08, |
| 140 | - Author={Huang, Gary B and Mattar, Marwan and Berg, Tamara and Learned-Miller, Eric and others}, | ||
| 141 | - Booktitle={Workshop on Faces in 'Real-Life' Images: Detection, Alignment, and Recognition}, | ||
| 142 | - Title={Labeled faces in the wild: A database forstudying face recognition in unconstrained environments}, | ||
| 143 | - Year={2008}} | 183 | + Author = {Huang, Gary B and Mattar, Marwan and Berg, Tamara and Learned-Miller, Eric and others}, |
| 184 | + Booktitle = {Workshop on Faces in 'Real-Life' Images: Detection, Alignment, and Recognition}, | ||
| 185 | + Title = {Labeled faces in the wild: A database forstudying face recognition in unconstrained environments}, | ||
| 186 | + Year = {2008}} | ||
| 187 | + | ||
| 188 | +@article{ihaka96, | ||
| 189 | + Author = {Ihaka, Ross and Gentleman, Robert}, | ||
| 190 | + Journal = {Journal of computational and graphical statistics}, | ||
| 191 | + Number = {3}, | ||
| 192 | + Pages = {299-314}, | ||
| 193 | + Publisher = {Taylor \& Francis}, | ||
| 194 | + Title = {R: A language for data analysis and graphics}, | ||
| 195 | + Volume = {5}, | ||
| 196 | + Year = {1996}} | ||
| 144 | 197 | ||
| 145 | @article{jegou11, | 198 | @article{jegou11, |
| 146 | Author = {J{\'e}gou, H. and Douze, M. and Schmid, C.}, | 199 | Author = {J{\'e}gou, H. and Douze, M. and Schmid, C.}, |
| @@ -173,6 +226,14 @@ | @@ -173,6 +226,14 @@ | ||
| 173 | Title = {{The HFB Face Database} for {Heterogeneous Face Biometrics} Research}, | 226 | Title = {{The HFB Face Database} for {Heterogeneous Face Biometrics} Research}, |
| 174 | Year = {2009}} | 227 | Year = {2009}} |
| 175 | 228 | ||
| 229 | +@inproceedings{lui12, | ||
| 230 | + Author = {Lui, Yui Man and Bolme, D and Phillips, PJ and Beveridge, JR and Draper, BA}, | ||
| 231 | + Booktitle = {Computer Vision and Pattern Recognition Workshops (CVPRW), 2012 IEEE Computer Society Conference on}, | ||
| 232 | + Organization = {IEEE}, | ||
| 233 | + Pages = {9-16}, | ||
| 234 | + Title = {Preliminary studies on the Good, the Bad, and the Ugly face recognition challenge problem}, | ||
| 235 | + Year = {2012}} | ||
| 236 | + | ||
| 176 | @article{martinez98, | 237 | @article{martinez98, |
| 177 | Author = {Martinez, A.M.}, | 238 | Author = {Martinez, A.M.}, |
| 178 | Journal = {CVC Technical Report}, | 239 | Journal = {CVC Technical Report}, |