diff --git a/CHANGELOG.md b/CHANGELOG.md index 06317e8..828766e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 0.3.0 - ??/??/?? ================ +* YouTubeFacesDBTransform implements Dr. Wolf's experimental protocol 0.2.0 - 2/23/13 =============== diff --git a/sdk/core/bee.cpp b/sdk/core/bee.cpp index 430d949..3e6d5d1 100644 --- a/sdk/core/bee.cpp +++ b/sdk/core/bee.cpp @@ -42,8 +42,8 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata) QDomDocument doc(sigset); QFile file(sigset); bool success; - success = file.open(QIODevice::ReadOnly); if (!success) qFatal("BEE::readSigset unable to open %s for reading.", qPrintable(sigset)); - success = doc.setContent(&file); if (!success) qFatal("BEE::readSigset unable to parse %s.", qPrintable(sigset)); + success = file.open(QIODevice::ReadOnly); if (!success) qFatal("Unable to open %s for reading.", qPrintable(sigset)); + success = doc.setContent(&file); if (!success) qFatal("Unable to parse %s.", qPrintable(sigset)); file.close(); QDomElement docElem = doc.documentElement(); @@ -75,7 +75,7 @@ FileList BEE::readSigset(const QString &sigset, bool ignoreMetadata) } } - if (file.isNull()) qFatal("BEE::readSigset empty file-name in %s.", qPrintable(sigset)); + if (file.isNull()) qFatal("Empty file-name in %s.", qPrintable(sigset)); fileList.append(file); fileNode = fileNode.nextSibling(); @@ -115,7 +115,7 @@ Mat readMatrix(const br::File &matrix) if (matrix == "Matrix") { const int size = matrix.getInt("Size"); const int step = matrix.getInt("Step", 1); - if (size % step != 0) qFatal("bee.cpp readMatrix step does not divide size evenly."); + if (size % step != 0) qFatal("Step does not divide size evenly."); if (sizeof(T) == sizeof(BEE::Mask_t)) { const bool selfSimilar = matrix.getBool("SelfSimilar"); @@ -140,12 +140,12 @@ Mat readMatrix(const br::File &matrix) QFile file(matrix); bool success = file.open(QFile::ReadOnly); - if (!success) qFatal("bee.cpp readMatrix unable to open %s for reading.", qPrintable((QString)matrix)); + if (!success) qFatal("Unable to open %s for reading.", qPrintable((QString)matrix)); // Check format QByteArray format = file.readLine(); bool isDistance = (format[0] == 'D'); - if (format[1] != '2') qFatal("bee.cpp readMatrix invalid matrix header."); + if (format[1] != '2') qFatal("Invalid matrix header."); // Skip sigset lines file.readLine(); @@ -160,7 +160,7 @@ Mat readMatrix(const br::File &matrix) qint64 bytesExpected = (qint64)rows*(qint64)cols*(qint64)sizeof(T); Mat m(rows, cols, OpenCVType::make()); if (file.read((char*)m.data, bytesExpected) != bytesExpected) - qFatal("bee.cpp readMatrix invalid matrix size."); + qFatal("Invalid matrix size."); file.close(); Mat result; @@ -182,17 +182,17 @@ Mat BEE::readMask(const br::File &mask) template void writeMatrix(const Mat &m, const QString &matrix, const QString &targetSigset, const QString &querySigset) { - if (m.type() != OpenCVType::make()) qFatal("bee.cpp writeMatrix invalid matrix type."); + if (m.type() != OpenCVType::make()) qFatal("Invalid matrix type."); int elemSize = sizeof(T); QString matrixType; if (elemSize == 1) matrixType = "B"; else if (elemSize == 4) matrixType = "F"; - else qFatal("bee.cpp writeMatrix invalid element size.\n"); + else qFatal("Invalid element size."); char buff[4]; QFile file(matrix); - bool success = file.open(QFile::WriteOnly); if (!success) qFatal("bee.cpp writeMatrix unable to open %s for writing.", qPrintable(matrix)); + bool success = file.open(QFile::WriteOnly); if (!success) qFatal("Unable to open %s for writing.", qPrintable(matrix)); file.write("S2\n"); file.write(qPrintable(QFileInfo(targetSigset).fileName())); file.write("\n"); @@ -227,8 +227,8 @@ void BEE::makeMask(const QString &targetInput, const QString &queryInput, const { qDebug("Making mask from %s and %s to %s", qPrintable(targetInput), qPrintable(queryInput), qPrintable(mask)); - FileList targetFiles = TemplateList::fromInput(targetInput).files(); - FileList queryFiles = TemplateList::fromInput(queryInput).files(); + FileList targetFiles = TemplateList::fromGallery(targetInput).files(); + FileList queryFiles = TemplateList::fromGallery(queryInput).files(); QList targetLabels = targetFiles.labels(); QList queryLabels = queryFiles.labels(); QList targetPartitions = targetFiles.crossValidationPartitions(); @@ -265,12 +265,12 @@ void BEE::combineMasks(const QStringList &inputMasks, const QString &outputMask, bool AND = true; if (method == "And") AND = true; else if (method == "Or") AND = false; - else qFatal("combineMasks invalid method"); + else qFatal("Invalid method."); QList masks; foreach (const QString &inputMask, inputMasks) masks.append(readMask(inputMask)); - if (masks.size() < 2) qFatal("BEE::mergeMasks expects at least two masks."); + if (masks.size() < 2) qFatal("Expected at least two masks."); const int rows = masks.first().rows; const int columns = masks.first().cols; @@ -294,7 +294,7 @@ void BEE::combineMasks(const QStringList &inputMasks, const QString &outputMask, break; } } - if ((genuineCount != 0) && (imposterCount != 0)) qFatal("BEE::combinedMasks comparison is both a genuine and an imposter."); + if ((genuineCount != 0) && (imposterCount != 0)) qFatal("Comparison is both a genuine and an imposter."); Mask_t val; if (genuineCount > 0) val = Match; diff --git a/sdk/core/classify.cpp b/sdk/core/classify.cpp index 4bdc620..958f676 100644 --- a/sdk/core/classify.cpp +++ b/sdk/core/classify.cpp @@ -37,14 +37,14 @@ void br::EvalClassification(const QString &predictedInput, const QString &truthI { qDebug("Evaluating classification of %s against %s", qPrintable(predictedInput), qPrintable(truthInput)); - TemplateList predicted(TemplateList::fromInput(predictedInput)); - TemplateList truth(TemplateList::fromInput(truthInput)); - if (predicted.size() != truth.size()) qFatal("br::EvalClassification input size mismatch."); + TemplateList predicted(TemplateList::fromGallery(predictedInput)); + TemplateList truth(TemplateList::fromGallery(truthInput)); + if (predicted.size() != truth.size()) qFatal("Input size mismatch."); QHash counters; for (int i=0; i::max(); int numGalleries = (int)sqrt((float)simmats.size()); if (numGalleries*numGalleries != simmats.size()) - qFatal("cluser.cpp readGalleries incorrect number of similarity matrices."); + qFatal("Incorrect number of similarity matrices."); // Process each simmat for (int i=0; i labels = TemplateList::fromInput(input).files().labels(); + QList labels = TemplateList::fromGallery(input).files().labels(); QHash labelToIndex; int nClusters = 0; @@ -322,7 +322,7 @@ br::Clusters br::ReadClusters(const QString &csv) Clusters clusters; QFile file(csv); bool success = file.open(QFile::ReadOnly); - if (!success) qFatal("br::ReadClusters failed to open %s for reading.", qPrintable(csv)); + if (!success) qFatal("Failed to open %s for reading.", qPrintable(csv)); QStringList lines = QString(file.readAll()).split("\n"); file.close(); @@ -332,7 +332,7 @@ br::Clusters br::ReadClusters(const QString &csv) foreach (const QString &id, ids) { bool ok; cluster.append(id.toInt(&ok)); - if (!ok) qFatal("br::ReadClusters non-interger id."); + if (!ok) qFatal("Non-interger id."); } clusters.append(cluster); } @@ -343,7 +343,7 @@ void br::WriteClusters(const Clusters &clusters, const QString &csv) { QFile file(csv); bool success = file.open(QFile::WriteOnly); - if (!success) qFatal("br::WriteClusters failed to open %s for writing.", qPrintable(csv)); + if (!success) qFatal("Failed to open %s for writing.", qPrintable(csv)); foreach (Cluster cluster, clusters) { if (cluster.empty()) continue; diff --git a/sdk/core/common.cpp b/sdk/core/common.cpp index 1f9091f..17584ec 100644 --- a/sdk/core/common.cpp +++ b/sdk/core/common.cpp @@ -33,7 +33,7 @@ QList Common::RandSample(int n, int max, int min, bool unique) QList samples; samples.reserve(n); int range = max-min; - if (range <= 0) qFatal("Common::RandSample non-positive range."); + if (range <= 0) qFatal("Non-positive range."); if (unique && (n >= range)) { for (int i=min; i algorithmCore(new AlgorithmCore(algorithm)); + algorithmsLock.lock(); if (!algorithms.contains(algorithm)) - algorithms.insert(algorithm, QSharedPointer(new AlgorithmCore(algorithm))); + algorithms.insert(algorithm, algorithmCore); algorithmsLock.unlock(); } diff --git a/sdk/core/fuse.cpp b/sdk/core/fuse.cpp index ceeb39f..a7b11e4 100644 --- a/sdk/core/fuse.cpp +++ b/sdk/core/fuse.cpp @@ -60,7 +60,7 @@ static void normalizeMatrix(Mat &matrix, const Mat &mask, const QString &method) } } } else if (method == "ZScore") { - if (stddev == 0) qFatal("fuse.cpp normalizeMatrix stddev is 0."); + if (stddev == 0) qFatal("Stddev is 0."); for (int i=0; i(i,j) == BEE::DontCare) continue; @@ -71,7 +71,7 @@ static void normalizeMatrix(Mat &matrix, const Mat &mask, const QString &method) } } } else { - qFatal("fuse.cpp normalizeMatrix invalid normalization method %s.", qPrintable(method)); + qFatal("Invalid normalization method %s.", qPrintable(method)); } } @@ -81,8 +81,8 @@ void br::Fuse(const QStringList &inputSimmats, const QString &mask, const QStrin QList matrices; foreach (const QString &simmat, inputSimmats) matrices.append(BEE::readSimmat(simmat)); - if ((matrices.size() < 2) && (fusion != "None")) qFatal("br::Fuse expected at least two similarity matrices."); - if ((matrices.size() > 1) && (fusion == "None")) qFatal("mm:Fuse expected exactly one similarity matrix."); + if ((matrices.size() < 2) && (fusion != "None")) qFatal("Expected at least two similarity matrices."); + if ((matrices.size() > 1) && (fusion == "None")) qFatal("Expected exactly one similarity matrix."); Mat matrix_mask = BEE::readMask(mask); for (int i=0; i &src, int rows) { if (rows == -1) rows = src.size(); int columns = src.isEmpty() ? 0 : src.size() / rows; - if (rows*columns != src.size()) qFatal("OpenCVUtils::toMat invalid matrix size."); + if (rows*columns != src.size()) qFatal("Invalid matrix size."); Mat dst(rows, columns, CV_32FC1); for (int i=0; i(i/columns,i%columns) = src[i]; @@ -131,7 +131,7 @@ Mat OpenCVUtils::toMat(const QList &src) for (int i=0; i &src) int row = 0; foreach (const Mat &m, src) { if ((m.cols != cols) || (m.type() != type) || (!m.isContinuous())) - qFatal("OpenCVUtils::toMatByRow invalid matrix."); + qFatal("Invalid matrix."); memcpy(dst.ptr(row), m.ptr(), m.rows*m.cols*m.elemSize()); row += m.rows; } @@ -167,7 +167,7 @@ QString OpenCVUtils::elemToString(const Mat &m, int r, int c) case CV_32S: return QString::number(m.at(r,c)); case CV_32F: return QString::number(m.at(r,c)); case CV_64F: return QString::number(m.at(r,c)); - default: qFatal("OpenCVUtils::elemToString unknown matrix depth"); + default: qFatal("Unknown matrix depth"); } return "?"; } @@ -183,7 +183,7 @@ float OpenCVUtils::elemToFloat(const Mat &m, int r, int c) case CV_32S: return float(m.at(r,c)); case CV_32F: return float(m.at(r,c)); case CV_64F: return float(m.at(r,c)); - default: qFatal("OpenCVUtils::elemToFloat unknown matrix depth"); + default: qFatal("Unknown matrix depth"); } return 0; } @@ -300,10 +300,9 @@ QDataStream &operator<<(QDataStream &stream, const Mat &m) int len = rows*cols*m.elemSize(); stream << len; if (len > 0) { - if (!m.isContinuous()) qFatal("opencvutils.cpp operator<< Mat can't serialize non-continuous matrices."); + if (!m.isContinuous()) qFatal("Can't serialize non-continuous matrices."); int written = stream.writeRawData((const char*)m.data, len); - - if (written != len) qFatal("opencvutils.cpp operator<< Mat serialization failure."); + if (written != len) qFatal("Serialization failure."); } return stream; } diff --git a/sdk/core/plot.cpp b/sdk/core/plot.cpp index 9ce14fb..9e053e4 100644 --- a/sdk/core/plot.cpp +++ b/sdk/core/plot.cpp @@ -309,7 +309,7 @@ struct RPlot RPlot(QStringList files, const br::File &destination, bool isEvalFormat = true) { - if (files.isEmpty()) qFatal("RPlot::RPlot() empty file list."); + if (files.isEmpty()) qFatal("Empty file list."); qSort(files.begin(), files.end(), sortFiles); // Parse destination @@ -320,7 +320,7 @@ struct RPlot file.setFileName(basename+".R"); bool success = file.open(QFile::WriteOnly); - if (!success) qFatal("RPlot::RPlot() failed to open %s for writing.", qPrintable(file.fileName())); + if (!success) qFatal("Failed to open %s for writing.", qPrintable(file.fileName())); file.write("# Load libraries\n" "library(ggplot2)\n" diff --git a/sdk/core/qtutils.cpp b/sdk/core/qtutils.cpp index 563b9d7..be837d1 100644 --- a/sdk/core/qtutils.cpp +++ b/sdk/core/qtutils.cpp @@ -44,7 +44,7 @@ QStringList QtUtils::getFiles(QDir dir, bool recursive) foreach (const QString &folder, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { QDir subdir(dir); - bool success = subdir.cd(folder); if (!success) qFatal("QtUtils::getFiles cd failure."); + bool success = subdir.cd(folder); if (!success) qFatal("cd failure."); files.append(getFiles(subdir, true)); } return files; @@ -74,7 +74,7 @@ QStringList QtUtils::readLines(const QString &file) void QtUtils::readFile(const QString &file, QStringList &lines) { QFile f(file); - if (!f.open(QFile::ReadOnly)) qFatal("QtUtils::readFile unable to open %s for reading.", qPrintable(file)); + if (!f.open(QFile::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file)); lines = QString(f.readAll()).split('\n', QString::SkipEmptyParts); for (int i=0; i QtUtils::toFloats(const QStringList &strings) bool ok; foreach (const QString &string, strings) { floats.append(string.toFloat(&ok)); - if (!ok) qFatal("QtUtils::toFloats failed to convert %s to floating point format.", qPrintable(string)); + if (!ok) qFatal("Failed to convert %s to floating point format.", qPrintable(string)); } return floats; } @@ -239,13 +239,13 @@ QStringList QtUtils::parse(QString args, char split) } else if ((args[i] == '(') || (args[i] == '[') || (args[i] == '<') || (args[i] == '{')) { subexpressions.push(args[i]); } else if (args[i] == ')') { - if (subexpressions.pop() != '(') qFatal("QtUtils::parse unexpected ')'."); + if (subexpressions.pop() != '(') qFatal("Unexpected ')'."); } else if (args[i] == ']') { - if (subexpressions.pop() != '[') qFatal("QtUtils::parse unexpected ']'."); + if (subexpressions.pop() != '[') qFatal("Unexpected ']'."); } else if (args[i] == '>') { - if (subexpressions.pop() != '<') qFatal("QtUtils::parse unexpected '>'."); + if (subexpressions.pop() != '<') qFatal("Unexpected '>'."); } else if (args[i] == '}') { - if (subexpressions.pop() != '{') qFatal("QtUtils::parse unexpected '}'."); + if (subexpressions.pop() != '{') qFatal("Unexpected '}'."); } else if (subexpressions.isEmpty() && (args[i] == split)) { words.append(args.mid(start, i-start).trimmed()); start = i+1; diff --git a/sdk/openbr.cpp b/sdk/openbr.cpp index 6ef8b21..a8897f9 100644 --- a/sdk/openbr.cpp +++ b/sdk/openbr.cpp @@ -204,7 +204,7 @@ void br_read_line(int *argc, const char ***argv) void br_reformat(const char *target_input, const char *query_input, const char *simmat, const char *output) { - Output::reformat(TemplateList::fromInput(target_input).files(), TemplateList::fromInput(query_input).files(), simmat, output); + Output::reformat(TemplateList::fromGallery(target_input).files(), TemplateList::fromGallery(query_input).files(), simmat, output); } const char *br_scratch_path() diff --git a/sdk/openbr_plugin.cpp b/sdk/openbr_plugin.cpp index e77f6d4..fe00e26 100644 --- a/sdk/openbr_plugin.cpp +++ b/sdk/openbr_plugin.cpp @@ -95,6 +95,11 @@ QList File::split(const QString &separator) const return files; } +QString File::resolved() const +{ + return exists() ? name : Globals->path + "/" + name; +} + bool File::contains(const QString &key) const { return m_metadata.contains(key) || Globals->contains(key); @@ -150,7 +155,7 @@ void File::set(const QString &key, const QVariant &value) QVariant File::get(const QString &key) const { - if (!contains(key)) qFatal("File::get missing key: %s", qPrintable(key)); + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key)); return value(key); } @@ -177,9 +182,9 @@ void File::setBool(const QString &key, bool value) int File::getInt(const QString &key) const { - if (!contains(key)) qFatal("File::getInt missing key: %s", qPrintable(key)); + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key)); bool ok; int result = value(key).toInt(&ok); - if (!ok) qFatal("File::getInt invalid conversion from: %s", qPrintable(getString(key))); + if (!ok) qFatal("Invalid conversion from: %s", qPrintable(getString(key))); return result; } @@ -193,9 +198,9 @@ int File::getInt(const QString &key, int defaultValue) const float File::getFloat(const QString &key) const { - if (!contains(key)) qFatal("File::getFloat missing key: %s", qPrintable(key)); + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key)); bool ok; float result = value(key).toFloat(&ok); - if (!ok) qFatal("File::getFloat invalid conversion from: %s", qPrintable(getString(key))); + if (!ok) qFatal("Invalid conversion from: %s", qPrintable(getString(key))); return result; } @@ -209,7 +214,7 @@ float File::getFloat(const QString &key, float defaultValue) const QString File::getString(const QString &key) const { - if (!contains(key)) qFatal("File::getString missing key: %s", qPrintable(key)); + if (!contains(key)) qFatal("Missing key: %s", qPrintable(key)); return value(key).toString(); } @@ -440,14 +445,14 @@ QDataStream &br::operator>>(QDataStream &stream, Template &t) } /* TemplateList - public methods */ -TemplateList TemplateList::fromInput(const br::File &input) +TemplateList TemplateList::fromGallery(const br::File &gallery) { TemplateList templates; - foreach (const br::File &file, input.split()) { + foreach (const br::File &file, gallery.split()) { QScopedPointer i(Gallery::make(file)); TemplateList newTemplates = i->read(); - const int crossValidate = input.getInt("crossValidate"); + const int crossValidate = gallery.getInt("crossValidate"); if (crossValidate > 0) srand(0); // If file is a Format not a Gallery @@ -456,13 +461,13 @@ TemplateList TemplateList::fromInput(const br::File &input) // Propogate metadata for (int i=0; i 0) newTemplates[i].file.insert("Cross_Validation_Partition", rand()%crossValidate); } - if (!templates.isEmpty() && input.getBool("merge")) { + if (!templates.isEmpty() && gallery.getBool("merge")) { if (newTemplates.size() != templates.size()) qFatal("Inputs must be the same size in order to merge."); for (int i=0; i")) { - if (!value.startsWith('[')) qFatal("Object::setProperty expected a list."); + if (!value.startsWith('[')) qFatal("Expected a list."); const QStringList strings = parse(value.mid(1, value.size()-2)); if (type == "QList") { @@ -1014,6 +1019,11 @@ void MatrixOutput::initialize(const FileList &targetFiles, const FileList &query data.create(queryFiles.size(), targetFiles.size(), CV_32FC1); } +MatrixOutput *MatrixOutput::make(const FileList &targetFiles, const FileList &queryFiles) +{ + return dynamic_cast(Output::make(".Matrix", targetFiles, queryFiles)); +} + /* MatrixOutput - protected methods */ QString MatrixOutput::toString(int row, int column) const { diff --git a/sdk/openbr_plugin.h b/sdk/openbr_plugin.h index 5fdc954..83a901a 100644 --- a/sdk/openbr_plugin.h +++ b/sdk/openbr_plugin.h @@ -126,7 +126,7 @@ void reset_##NAME() { NAME = DEFAULT; } * path | QString | Resolve complete file paths from file names * enrollAll | bool | Enroll zero or more templates per file * separator | QString | Seperate #name into multiple files - * Input_Index | int | Index of a template in a template list + * Index | int | Index of a template in a template list * Label | float | Classification/Regression class * Confidence | float | Classification/Regression quality * FTE | bool | Failure to enroll @@ -153,7 +153,7 @@ struct BR_EXPORT File File(const QString &file) { init(file); } /*!< \brief Construct a file from a string. */ File(const QString &file, const QVariant &label) { init(file); insert("Label", label); } /*!< \brief Construct a file from a string and assign a label. */ File(const char *file) { init(file); } /*!< \brief Construct a file from a c-style string. */ - operator QString() const { return name; } /*!< \brief Returns #name. */ + inline operator QString() const { return name; } /*!< \brief Returns #name. */ QString flat() const; /*!< \brief A stringified version of the file with metadata. */ QString hash() const; /*!< \brief A hash of the file. */ inline void clear() { name.clear(); m_metadata.clear(); } /*!< \brief Clears the file's name and metadata. */ @@ -187,6 +187,7 @@ struct BR_EXPORT File inline QString baseName() const { const QString baseName = QFileInfo(name).baseName(); return baseName.isEmpty() ? QDir(name).dirName() : baseName; } /*!< \brief Returns the file's base name. */ inline QString suffix() const { return QFileInfo(name).suffix(); } /*!< \brief Returns the file's extension. */ + QString resolved() const; /*!< \brief Returns name prepended with Globals->path if name does not exist. */ bool contains(const QString &key) const; /*!< \brief Returns \c true if the key has an associated value, \c false otherwise. */ QVariant value(const QString &key) const; /*!< \brief Returns the value for the specified key. */ @@ -276,7 +277,7 @@ struct Template : public QList Template(const cv::Mat &mat) { append(mat); } /*!< \brief Append a matrix. */ inline const cv::Mat &m() const { static const cv::Mat NullMatrix; - return isEmpty() ? qFatal("Template::m() empty template."), NullMatrix : last(); } /*!< \brief Idiom to treat the template as a matrix. */ + return isEmpty() ? qFatal("Empty template."), NullMatrix : last(); } /*!< \brief Idiom to treat the template as a matrix. */ inline cv::Mat &m() { return isEmpty() ? append(cv::Mat()), last() : last(); } /*!< \brief Idiom to treat the template as a matrix. */ inline cv::Mat &operator=(const cv::Mat &other) { return m() = other; } /*!< \brief Idiom to treat the template as a matrix. */ inline operator const cv::Mat&() const { return m(); } /*!< \brief Idiom to treat the template as a matrix. */ @@ -330,9 +331,10 @@ struct TemplateList : public QList