diff --git a/openbr/core/bee.cpp b/openbr/core/bee.cpp index 940ddf2..db67479 100644 --- a/openbr/core/bee.cpp +++ b/openbr/core/bee.cpp @@ -172,6 +172,8 @@ Mat BEE::readMat(const br::File &matrix, QString *targetSigset, QString *querySi qint64 read = file.read((char*)m.data, bytesExpected); if (read != bytesExpected) qFatal("Invalid matrix size."); + if (!file.atEnd()) + qFatal("Expected matrix end of file."); file.close(); Mat result; diff --git a/openbr/janus b/openbr/janus index 319c13e..02fd545 160000 --- a/openbr/janus +++ b/openbr/janus @@ -1 +1 @@ -Subproject commit 319c13efbb4f84a4fd68c98b7892a7583bf9e741 +Subproject commit 02fd545b2dbb8ea2ba10dbf67e429da598545d75 diff --git a/openbr/janus.cpp b/openbr/janus.cpp index 657de15..50e402b 100644 --- a/openbr/janus.cpp +++ b/openbr/janus.cpp @@ -3,30 +3,42 @@ #endif #include "janus.h" +#include "janus_io.h" #include "openbr_plugin.h" -// Use the provided default implementation of some functions -#include "janus/src/janus.cpp" - using namespace br; static QSharedPointer transform; static QSharedPointer distance; +size_t janus_max_template_size() +{ + return JANUS_MAX_TEMPLATE_SIZE_LIMIT; +} + janus_error janus_initialize(const char *sdk_path, const char *model_file) { int argc = 1; const char *argv[1] = { "janus" }; Context::initialize(argc, (char**)argv, sdk_path); QString algorithm = model_file; - if (algorithm.isEmpty()) algorithm = "Cvt(Gray)+Affine(88,88,0.25,0.35)+++:ByteL1"; - transform = Transform::fromAlgorithm(algorithm, false); - distance = Distance::fromAlgorithm(algorithm); + if (algorithm.isEmpty()) { + transform = Transform::fromAlgorithm("Cvt(Gray)+Affine(88,88,0.25,0.35)+++", false); + distance = Distance::fromAlgorithm("FaceRecognition"); + } else if (algorithm == "PP5") { + transform.reset(Transform::make("PP5Enroll", NULL)); + distance.reset(Distance::make("PP5Compare", NULL)); + } else { + transform = Transform::fromAlgorithm(algorithm, false); + distance = Distance::fromAlgorithm(algorithm); + } return JANUS_SUCCESS; } janus_error janus_finalize() { + transform.reset(); + distance.reset(); Context::finalize(); return JANUS_SUCCESS; } @@ -40,24 +52,24 @@ janus_error janus_initialize_template(janus_template *template_) return JANUS_SUCCESS; } -janus_error janus_add_image(const janus_image image, const janus_attribute_list attributes, janus_template template_) +janus_error janus_augment(const janus_image image, const janus_attribute_list attributes, janus_template template_) { Template t; t.append(cv::Mat(image.height, image.width, - image.color_space == JANUS_GRAY8 ? CV_8UC1 : CV_8UC1, + image.color_space == JANUS_GRAY8 ? CV_8UC1 : CV_8UC3, image.data)); for (size_t i=0; i("JANUS_RIGHT_EYE_X"), t.file.get("JANUS_RIGHT_EYE_Y"))); - t.file.set("Affine_1", QPointF(t.file.get("JANUS_LEFT_EYE_X"), t.file.get("JANUS_LEFT_EYE_Y"))); + t.file.set("Affine_0", QPointF(t.file.get("RIGHT_EYE_X"), t.file.get("RIGHT_EYE_Y"))); + t.file.set("Affine_1", QPointF(t.file.get("LEFT_EYE_X"), t.file.get("LEFT_EYE_Y"))); Template u; transform->project(t, u); template_->append(u); @@ -66,78 +78,63 @@ janus_error janus_add_image(const janus_image image, const janus_attribute_list janus_error janus_finalize_template(janus_template template_, janus_flat_template flat_template, size_t *bytes) { - size_t templateBytes = 0; - size_t numTemplates = 0; - *bytes = sizeof(templateBytes) + sizeof(numTemplates); - janus_flat_template pos = flat_template + *bytes; - foreach (const cv::Mat &m, *template_) { assert(m.isContinuous()); - const size_t currentTemplateBytes = m.rows * m.cols * m.elemSize(); - if (templateBytes == 0) - templateBytes = currentTemplateBytes; - if (templateBytes != currentTemplateBytes) - return JANUS_UNKNOWN_ERROR; - if (*bytes + templateBytes > janus_max_template_size()) + const size_t templateBytes = m.rows * m.cols * m.elemSize(); + if (*bytes + sizeof(size_t) + templateBytes > janus_max_template_size()) break; - memcpy(pos, m.data, templateBytes); - *bytes += templateBytes; - pos = pos + templateBytes; - numTemplates++; + memcpy(flat_template, &templateBytes, sizeof(templateBytes)); + flat_template += sizeof(templateBytes); + memcpy(flat_template, m.data, templateBytes); + flat_template += templateBytes; + *bytes += sizeof(size_t) + templateBytes; } - *(reinterpret_cast(flat_template)+0) = templateBytes; - *(reinterpret_cast(flat_template)+1) = numTemplates; delete template_; return JANUS_SUCCESS; } janus_error janus_verify(const janus_flat_template a, const size_t a_bytes, const janus_flat_template b, const size_t b_bytes, double *similarity) { - (void) a_bytes; - (void) b_bytes; - - size_t a_template_bytes, a_templates, b_template_bytes, b_templates; - a_template_bytes = *(reinterpret_cast(a)+0); - a_templates = *(reinterpret_cast(a)+1); - b_template_bytes = *(reinterpret_cast(b)+0); - b_templates = *(reinterpret_cast(b)+1); - if (a_template_bytes != b_template_bytes) - return JANUS_UNKNOWN_ERROR; + *similarity = 0; - float dist = 0; - for (size_t i=0; icompare(cv::Mat(1, a_template_bytes, CV_8UC1, a+2*sizeof(size_t)+i*a_template_bytes), - cv::Mat(1, b_template_bytes, CV_8UC1, b+2*sizeof(size_t)+i*b_template_bytes)); - *similarity = a_templates * b_templates / dist; - return JANUS_SUCCESS; -} + int comparisons = 0; + janus_flat_template a_template = a; + while (a_template < a + a_bytes) { + const size_t a_template_bytes = *reinterpret_cast(a_template); + a_template += sizeof(a_template_bytes); -struct janus_gallery_type : public TemplateList -{}; + janus_flat_template b_template = b; + while (b_template < b + b_bytes) { + const size_t b_template_bytes = *reinterpret_cast(b_template); + b_template += sizeof(b_template_bytes); -janus_error janus_initialize_gallery(janus_gallery *gallery) -{ - *gallery = new janus_gallery_type(); - return JANUS_SUCCESS; -} + *similarity += distance->compare(cv::Mat(1, a_template_bytes, CV_8UC1, a_template), + cv::Mat(1, b_template_bytes, CV_8UC1, b_template)); + comparisons++; -janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) -{ - template_->file.set("Template_ID", template_id); - gallery->append(*template_); - delete template_; + b_template += b_template_bytes; + } + + a_template += a_template_bytes; + } + + if (*similarity != *similarity) // True for NaN + return JANUS_UNKNOWN_ERROR; + + *similarity /= comparisons; return JANUS_SUCCESS; } -janus_error janus_finalize_gallery(janus_gallery gallery, janus_gallery_file gallery_file) +janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) { - QFile file(gallery_file); - if (!file.open(QFile::WriteOnly)) + template_->file.set("TEMPLATE_ID", template_id); + QFile file(gallery); + if (!file.open(QFile::WriteOnly | QFile::Append)) return JANUS_WRITE_ERROR; QDataStream stream(&file); - stream << gallery; + stream << *template_; file.close(); + delete template_; return JANUS_SUCCESS; } diff --git a/openbr/plugins/algorithms.cpp b/openbr/plugins/algorithms.cpp index 8a64018..4aa619d 100644 --- a/openbr/plugins/algorithms.cpp +++ b/openbr/plugins/algorithms.cpp @@ -79,7 +79,7 @@ class AlgorithmsInitializer : public Initializer Globals->abbreviations.insert("ColoredLBP", "Open+Affine(128,128,0.37,0.45)+Cvt(Gray)+Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+ColoredU2"); // Transforms - Globals->abbreviations.insert("FaceDetection", "(Open+Cvt(Gray)+Cascade(FrontalFace))"); + Globals->abbreviations.insert("FaceDetection", "Open+Cvt(Gray)+Cascade(FrontalFace)"); Globals->abbreviations.insert("DenseLBP", "(Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+RectRegions(8,8,6,6)+Hist(59))"); Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)"); Globals->abbreviations.insert("FaceRecognitionRegistration", "(ASEFEyes+Affine(88,88,0.25,0.35)+DownsampleTraining(FTE(DFFS),instances=1))");