From 5edb29cab8bc5ffa553578e8c5ceb5a1a173b0e2 Mon Sep 17 00:00:00 2001 From: Josh Klontz Date: Thu, 12 Jun 2014 17:43:45 -0400 Subject: [PATCH] deprecated br-enroll --- app/CMakeLists.txt | 1 - app/br-download/br-download.cpp | 2 +- app/br-enroll/CMakeLists.txt | 4 ---- app/br-enroll/br-enroll.cpp | 95 ----------------------------------------------------------------------------------------------- openbr/plugins/algorithms.cpp | 2 +- openbr/plugins/gallery.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- openbr/plugins/misc.cpp | 29 ++++++++++++++++++++--------- openbr/plugins/stream.cpp | 2 ++ openbr/plugins/template.cpp | 22 ++++++++++++++++++++++ 9 files changed, 98 insertions(+), 130 deletions(-) delete mode 100644 app/br-enroll/CMakeLists.txt delete mode 100644 app/br-enroll/br-enroll.cpp diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 231d6d4..7e3c6c2 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -8,7 +8,6 @@ add_subdirectory(examples) if(NOT ${BR_EMBEDDED}) add_subdirectory(br-download) add_subdirectory(br-crawl) - add_subdirectory(br-enroll) add_subdirectory(br-gui) add_subdirectory(br-print) add_subdirectory(br-search) diff --git a/app/br-download/br-download.cpp b/app/br-download/br-download.cpp index 73d81d6..6fd6e03 100644 --- a/app/br-download/br-download.cpp +++ b/app/br-download/br-download.cpp @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) json ? line : QByteArray(), nam); - if (error.error != QJsonParseError::NoError) + if (json && (error.error != QJsonParseError::NoError)) qDebug() << error.errorString(); } } diff --git a/app/br-enroll/CMakeLists.txt b/app/br-enroll/CMakeLists.txt deleted file mode 100644 index b280866..0000000 --- a/app/br-enroll/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_executable(br-enroll br-enroll.cpp ${BR_RESOURCES}) -target_link_libraries(br-enroll openbr ${BR_THIRDPARTY_LIBS}) -qt5_use_modules(br-enroll ${QT_DEPENDENCIES}) -install(TARGETS br-enroll RUNTIME DESTINATION bin) diff --git a/app/br-enroll/br-enroll.cpp b/app/br-enroll/br-enroll.cpp deleted file mode 100644 index 7ca420f..0000000 --- a/app/br-enroll/br-enroll.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright 2014 Noblis * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include -#include -#include - -using namespace br; -using namespace cv; - -static void help() -{ - printf("br-enroll [args]\n" - "================\n" - "* __stdin__ - Templates (raw data)\n" - "* __stdout__ - Templates (feature vectors)\n" - "\n" - "_br-enroll_ is an application that creates feature vector template(s) from images.\n" - "For every input image template in _stdin_, enroll writes zero or more templates to _stdout_.\n" - "\n" - "Enroll may choose to store metadata in the feature vector in an algorithm-specific manner.\n" - "For example, a face recognition algorithm may devote the first 16-bytes of the feature vector to saving four 4-byte integers representing the face bounding box (X, Y, Width, Height).\n" - "It is expected that _br-search_ will understand and output algorithm-specific metadata for the top matching templates.\n"); -} - -static QSharedPointer algorithm; - -static void enroll_utemplate(br_const_utemplate utemplate, br_callback_context) -{ - if (utemplate->algorithmID != 3) - qFatal("Expected an encoded image."); - - TemplateList templates; - templates.append(Template(imdecode(Mat(1, utemplate->size, CV_8UC1, (void*) utemplate->data), IMREAD_UNCHANGED))); - templates >> *algorithm; - - foreach (const Template &t, templates) { - const Mat &m = t.m(); - QByteArray data((const char*) m.data, m.rows * m.cols * m.elemSize()); - - const QRectF frontalFace = t.file.get("FrontalFace"); - const QPointF firstEye = t.file.get("First_Eye"); - const QPointF secondEye = t.file.get("Second_Eye"); - const float x = frontalFace.x(); - const float y = frontalFace.y(); - const float width = frontalFace.width(); - const float height = frontalFace.height(); - const float rightEyeX = firstEye.x(); - const float rightEyeY = firstEye.y(); - const float leftEyeX = secondEye.x(); - const float leftEyeY = secondEye.y(); - - data.append((const char*)&x , sizeof(float)); - data.append((const char*)&y , sizeof(float)); - data.append((const char*)&width , sizeof(float)); - data.append((const char*)&height , sizeof(float)); - data.append((const char*)&rightEyeX, sizeof(float)); - data.append((const char*)&rightEyeY, sizeof(float)); - data.append((const char*)&leftEyeX , sizeof(float)); - data.append((const char*)&leftEyeY , sizeof(float)); - - const QByteArray templateID = QCryptographicHash::hash(data, QCryptographicHash::Md5); - br_append_utemplate_contents(stdout, utemplate->imageID, (const unsigned char*) templateID.data(), -1, data.size(), (const unsigned char*) data.data()); - } -} - -int main(int argc, char *argv[]) -{ - for (int i=1; iquiet = true; - Globals->enrollAll = true; - algorithm = Transform::fromAlgorithm("FaceRecognition"); - br_iterate_utemplates_file(stdin, enroll_utemplate, NULL, true); - Context::finalize(); - return EXIT_SUCCESS; -} diff --git a/openbr/plugins/algorithms.cpp b/openbr/plugins/algorithms.cpp index 0336996..40c08e7 100644 --- a/openbr/plugins/algorithms.cpp +++ b/openbr/plugins/algorithms.cpp @@ -31,7 +31,7 @@ class AlgorithmsInitializer : public Initializer void initialize() const { // Face - Globals->abbreviations.insert("FaceRecognition", "FaceDetection+Expand++Expand+++:MatchProbability(ByteL1)"); + Globals->abbreviations.insert("FaceRecognition", "FaceDetection+Expand++Expand++++SetMetadata(AlgorithmID,-1):MatchProbability(ByteL1)"); Globals->abbreviations.insert("GenderClassification", "FaceDetection+Expand++Expand+++Discard"); Globals->abbreviations.insert("AgeRegression", "FaceDetection+Expand++Expand+++Discard"); Globals->abbreviations.insert("FaceQuality", "Open+Expand+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard"); diff --git a/openbr/plugins/gallery.cpp b/openbr/plugins/gallery.cpp index 2022a54..54605ae 100644 --- a/openbr/plugins/gallery.cpp +++ b/openbr/plugins/gallery.cpp @@ -95,17 +95,26 @@ class BinaryGallery : public Gallery void init() { - gallery.setFileName(file); - if (file.get("remove")) - gallery.remove(); - QtUtils::touchDir(gallery); - QFile::OpenMode mode = QFile::ReadWrite; + const QString baseName = file.baseName(); + if (baseName == "stdin") { + gallery.open(stdin, QFile::ReadOnly); + } else if (baseName == "stdout") { + gallery.open(stdout, QFile::WriteOnly); + } else if (baseName == "stderr") { + gallery.open(stderr, QFile::WriteOnly); + } else { + gallery.setFileName(file); + if (file.get("remove")) + gallery.remove(); + QtUtils::touchDir(gallery); + QFile::OpenMode mode = QFile::ReadWrite; - if (file.get("append")) - mode |= QFile::Append; + if (file.get("append")) + mode |= QFile::Append; - if (!gallery.open(mode)) - qFatal("Can't open gallery: %s", qPrintable(gallery.fileName())); + if (!gallery.open(mode)) + qFatal("Can't open gallery: %s", qPrintable(gallery.fileName())); + } stream.setDevice(&gallery); } @@ -181,20 +190,44 @@ class utGallery : public BinaryGallery Template readTemplate() { - cv::Mat m; - br_utemplate t = (br_utemplate) malloc(sizeof(br_universal_template)); - if (gallery.read((char*)t, sizeof(br_universal_template)) == sizeof(br_universal_template)) { - m = cv::Mat(1, t->size, CV_8UC1); - if (gallery.read((char*)m.data, t->size) != t->size) - qFatal("Unexepected EOF when reading universal template data."); + Template t; + br_utemplate ut = (br_utemplate) malloc(sizeof(br_universal_template)); + if (gallery.read((char*)ut, sizeof(br_universal_template)) == sizeof(br_universal_template)) { + cv::Mat m = cv::Mat(1, ut->size, CV_8UC1); + char *dst = (char*) m.data; + qint64 bytesNeeded = ut->size; + while (bytesNeeded > 0) { + qint64 bytesRead = gallery.read(dst, bytesNeeded); + if (bytesRead <= 0) + qFatal("Unexepected EOF when reading universal template data."); + bytesNeeded -= bytesRead; + dst += bytesRead; + } + t.append(m); + t.file.set("ImageID", QVariant(QByteArray((const char*)ut->imageID, 16))); + t.file.set("TemplateID", QVariant(QByteArray((const char*)ut->templateID, 16))); + t.file.set("AlgorithmID", QVariant(ut->algorithmID)); } - free(t); - return m; + free(ut); + return t; } - void write(const Template &) + void write(const Template &t) { - qFatal("Not implemented."); + const QByteArray imageID = t.file.get("ImageID"); + if (imageID.size() != 16) + qFatal("Expected 16-byte ImageID, got: %d bytes.", imageID.size()); + + const int32_t algorithmID = t.file.get("AlgorithmID"); + const QByteArray data((const char*) t.m().data, t.m().rows * t.m().cols * t.m().elemSize()); + const QByteArray templateID = QCryptographicHash::hash(data, QCryptographicHash::Md5); + const uint32_t size = data.size(); + + gallery.write(imageID); + gallery.write(templateID); + gallery.write((const char*) &algorithmID, 4); + gallery.write((const char*) &size, 4); + gallery.write(data); } }; diff --git a/openbr/plugins/misc.cpp b/openbr/plugins/misc.cpp index 1152dcd..bae5b5e 100644 --- a/openbr/plugins/misc.cpp +++ b/openbr/plugins/misc.cpp @@ -37,17 +37,28 @@ class OpenTransform : public UntrainableMetaTransform void project(const Template &src, Template &dst) const { - if (!src.isEmpty()) { dst = src; return; } - if (Globals->verbose) qDebug("Opening %s", qPrintable(src.file.flat())); dst.file = src.file; - foreach (const File &file, src.file.split()) { - QScopedPointer format(Factory::make(file)); - Template t = format->read(); - if (t.isEmpty()) qWarning("Can't open %s from %s", qPrintable(file.flat()), qPrintable(QDir::currentPath())); - dst.append(t); - dst.file.append(t.file.localMetadata()); + if (src.empty()) { + if (Globals->verbose) + qDebug("Opening %s", qPrintable(src.file.flat())); + + // Read from disk otherwise + foreach (const File &file, src.file.split()) { + QScopedPointer format(Factory::make(file)); + Template t = format->read(); + if (t.isEmpty()) + qWarning("Can't open %s from %s", qPrintable(file.flat()), qPrintable(QDir::currentPath())); + dst.append(t); + dst.file.append(t.file.localMetadata()); + } + dst.file.set("FTO", dst.isEmpty()); + } else { + // Propogate or decode existing matricies + foreach (const Mat &m, src) { + if (((m.rows > 1) && (m.cols > 1)) || (m.type() != CV_8UC1)) dst += m; + else dst += imdecode(src.m(), IMREAD_UNCHANGED); + } } - dst.file.set("FTO", dst.isEmpty()); } }; diff --git a/openbr/plugins/stream.cpp b/openbr/plugins/stream.cpp index fb2d1fd..130aa47 100644 --- a/openbr/plugins/stream.cpp +++ b/openbr/plugins/stream.cpp @@ -334,6 +334,8 @@ public: // Otherwise, read another block if (!lastBlock) { currentData = gallery->readBlock(&lastBlock); + if (currentData.empty()) + qFatal("Expected at least one template."); nextIdx = 0; } else diff --git a/openbr/plugins/template.cpp b/openbr/plugins/template.cpp index fbf68ad..ab7f17e 100644 --- a/openbr/plugins/template.cpp +++ b/openbr/plugins/template.cpp @@ -52,6 +52,28 @@ BR_REGISTER(Transform, RemoveTemplatesTransform) /*! * \ingroup transforms + * \brief Sets the metadata key/value pair. + * \author Josh Klontz \cite jklontz + */ +class SetMetadataTransform : public UntrainableMetadataTransform +{ + Q_OBJECT + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false) + Q_PROPERTY(QString value READ get_value WRITE set_value RESET reset_value STORED false) + BR_PROPERTY(QString, key, "") + BR_PROPERTY(QString, value, "") + + void projectMetadata(const File &src, File &dst) const + { + dst = src; + dst.set(key, value); + } +}; + +BR_REGISTER(Transform, SetMetadataTransform) + +/*! + * \ingroup transforms * \brief Removes a metadata field from all templates * \author Brendan Klare \cite bklare */ -- libgit2 0.21.4