Commit ef45e04258bf85a32079e832cff7178be09a0e4e
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
4 changed files
with
66 additions
and
67 deletions
openbr/core/bee.cpp
| ... | ... | @@ -172,6 +172,8 @@ Mat BEE::readMat(const br::File &matrix, QString *targetSigset, QString *querySi |
| 172 | 172 | qint64 read = file.read((char*)m.data, bytesExpected); |
| 173 | 173 | if (read != bytesExpected) |
| 174 | 174 | qFatal("Invalid matrix size."); |
| 175 | + if (!file.atEnd()) | |
| 176 | + qFatal("Expected matrix end of file."); | |
| 175 | 177 | file.close(); |
| 176 | 178 | |
| 177 | 179 | Mat result; | ... | ... |
openbr/janus.cpp
| ... | ... | @@ -3,30 +3,42 @@ |
| 3 | 3 | #endif |
| 4 | 4 | |
| 5 | 5 | #include "janus.h" |
| 6 | +#include "janus_io.h" | |
| 6 | 7 | #include "openbr_plugin.h" |
| 7 | 8 | |
| 8 | -// Use the provided default implementation of some functions | |
| 9 | -#include "janus/src/janus.cpp" | |
| 10 | - | |
| 11 | 9 | using namespace br; |
| 12 | 10 | |
| 13 | 11 | static QSharedPointer<Transform> transform; |
| 14 | 12 | static QSharedPointer<Distance> distance; |
| 15 | 13 | |
| 14 | +size_t janus_max_template_size() | |
| 15 | +{ | |
| 16 | + return JANUS_MAX_TEMPLATE_SIZE_LIMIT; | |
| 17 | +} | |
| 18 | + | |
| 16 | 19 | janus_error janus_initialize(const char *sdk_path, const char *model_file) |
| 17 | 20 | { |
| 18 | 21 | int argc = 1; |
| 19 | 22 | const char *argv[1] = { "janus" }; |
| 20 | 23 | Context::initialize(argc, (char**)argv, sdk_path); |
| 21 | 24 | QString algorithm = model_file; |
| 22 | - if (algorithm.isEmpty()) algorithm = "Cvt(Gray)+Affine(88,88,0.25,0.35)+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:ByteL1"; | |
| 23 | - transform = Transform::fromAlgorithm(algorithm, false); | |
| 24 | - distance = Distance::fromAlgorithm(algorithm); | |
| 25 | + if (algorithm.isEmpty()) { | |
| 26 | + transform = Transform::fromAlgorithm("Cvt(Gray)+Affine(88,88,0.25,0.35)+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>", false); | |
| 27 | + distance = Distance::fromAlgorithm("FaceRecognition"); | |
| 28 | + } else if (algorithm == "PP5") { | |
| 29 | + transform.reset(Transform::make("PP5Enroll", NULL)); | |
| 30 | + distance.reset(Distance::make("PP5Compare", NULL)); | |
| 31 | + } else { | |
| 32 | + transform = Transform::fromAlgorithm(algorithm, false); | |
| 33 | + distance = Distance::fromAlgorithm(algorithm); | |
| 34 | + } | |
| 25 | 35 | return JANUS_SUCCESS; |
| 26 | 36 | } |
| 27 | 37 | |
| 28 | 38 | janus_error janus_finalize() |
| 29 | 39 | { |
| 40 | + transform.reset(); | |
| 41 | + distance.reset(); | |
| 30 | 42 | Context::finalize(); |
| 31 | 43 | return JANUS_SUCCESS; |
| 32 | 44 | } |
| ... | ... | @@ -40,24 +52,24 @@ janus_error janus_initialize_template(janus_template *template_) |
| 40 | 52 | return JANUS_SUCCESS; |
| 41 | 53 | } |
| 42 | 54 | |
| 43 | -janus_error janus_add_image(const janus_image image, const janus_attribute_list attributes, janus_template template_) | |
| 55 | +janus_error janus_augment(const janus_image image, const janus_attribute_list attributes, janus_template template_) | |
| 44 | 56 | { |
| 45 | 57 | Template t; |
| 46 | 58 | t.append(cv::Mat(image.height, |
| 47 | 59 | image.width, |
| 48 | - image.color_space == JANUS_GRAY8 ? CV_8UC1 : CV_8UC1, | |
| 60 | + image.color_space == JANUS_GRAY8 ? CV_8UC1 : CV_8UC3, | |
| 49 | 61 | image.data)); |
| 50 | 62 | for (size_t i=0; i<attributes.size; i++) |
| 51 | 63 | t.file.set(janus_attribute_to_string(attributes.attributes[i]), attributes.values[i]); |
| 52 | 64 | |
| 53 | - if (!t.file.contains("JANUS_RIGHT_EYE_X") || | |
| 54 | - !t.file.contains("JANUS_RIGHT_EYE_Y") || | |
| 55 | - !t.file.contains("JANUS_LEFT_EYE_X") || | |
| 56 | - !t.file.contains("JANUS_LEFT_EYE_Y")) | |
| 65 | + if (!t.file.contains("RIGHT_EYE_X") || | |
| 66 | + !t.file.contains("RIGHT_EYE_Y") || | |
| 67 | + !t.file.contains("LEFT_EYE_X") || | |
| 68 | + !t.file.contains("LEFT_EYE_Y")) | |
| 57 | 69 | return JANUS_SUCCESS; |
| 58 | 70 | |
| 59 | - t.file.set("Affine_0", QPointF(t.file.get<float>("JANUS_RIGHT_EYE_X"), t.file.get<float>("JANUS_RIGHT_EYE_Y"))); | |
| 60 | - t.file.set("Affine_1", QPointF(t.file.get<float>("JANUS_LEFT_EYE_X"), t.file.get<float>("JANUS_LEFT_EYE_Y"))); | |
| 71 | + t.file.set("Affine_0", QPointF(t.file.get<float>("RIGHT_EYE_X"), t.file.get<float>("RIGHT_EYE_Y"))); | |
| 72 | + t.file.set("Affine_1", QPointF(t.file.get<float>("LEFT_EYE_X"), t.file.get<float>("LEFT_EYE_Y"))); | |
| 61 | 73 | Template u; |
| 62 | 74 | transform->project(t, u); |
| 63 | 75 | template_->append(u); |
| ... | ... | @@ -66,78 +78,63 @@ janus_error janus_add_image(const janus_image image, const janus_attribute_list |
| 66 | 78 | |
| 67 | 79 | janus_error janus_finalize_template(janus_template template_, janus_flat_template flat_template, size_t *bytes) |
| 68 | 80 | { |
| 69 | - size_t templateBytes = 0; | |
| 70 | - size_t numTemplates = 0; | |
| 71 | - *bytes = sizeof(templateBytes) + sizeof(numTemplates); | |
| 72 | - janus_flat_template pos = flat_template + *bytes; | |
| 73 | - | |
| 74 | 81 | foreach (const cv::Mat &m, *template_) { |
| 75 | 82 | assert(m.isContinuous()); |
| 76 | - const size_t currentTemplateBytes = m.rows * m.cols * m.elemSize(); | |
| 77 | - if (templateBytes == 0) | |
| 78 | - templateBytes = currentTemplateBytes; | |
| 79 | - if (templateBytes != currentTemplateBytes) | |
| 80 | - return JANUS_UNKNOWN_ERROR; | |
| 81 | - if (*bytes + templateBytes > janus_max_template_size()) | |
| 83 | + const size_t templateBytes = m.rows * m.cols * m.elemSize(); | |
| 84 | + if (*bytes + sizeof(size_t) + templateBytes > janus_max_template_size()) | |
| 82 | 85 | break; |
| 83 | - memcpy(pos, m.data, templateBytes); | |
| 84 | - *bytes += templateBytes; | |
| 85 | - pos = pos + templateBytes; | |
| 86 | - numTemplates++; | |
| 86 | + memcpy(flat_template, &templateBytes, sizeof(templateBytes)); | |
| 87 | + flat_template += sizeof(templateBytes); | |
| 88 | + memcpy(flat_template, m.data, templateBytes); | |
| 89 | + flat_template += templateBytes; | |
| 90 | + *bytes += sizeof(size_t) + templateBytes; | |
| 87 | 91 | } |
| 88 | 92 | |
| 89 | - *(reinterpret_cast<size_t*>(flat_template)+0) = templateBytes; | |
| 90 | - *(reinterpret_cast<size_t*>(flat_template)+1) = numTemplates; | |
| 91 | 93 | delete template_; |
| 92 | 94 | return JANUS_SUCCESS; |
| 93 | 95 | } |
| 94 | 96 | |
| 95 | 97 | 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) |
| 96 | 98 | { |
| 97 | - (void) a_bytes; | |
| 98 | - (void) b_bytes; | |
| 99 | - | |
| 100 | - size_t a_template_bytes, a_templates, b_template_bytes, b_templates; | |
| 101 | - a_template_bytes = *(reinterpret_cast<size_t*>(a)+0); | |
| 102 | - a_templates = *(reinterpret_cast<size_t*>(a)+1); | |
| 103 | - b_template_bytes = *(reinterpret_cast<size_t*>(b)+0); | |
| 104 | - b_templates = *(reinterpret_cast<size_t*>(b)+1); | |
| 105 | - if (a_template_bytes != b_template_bytes) | |
| 106 | - return JANUS_UNKNOWN_ERROR; | |
| 99 | + *similarity = 0; | |
| 107 | 100 | |
| 108 | - float dist = 0; | |
| 109 | - for (size_t i=0; i<a_templates; i++) | |
| 110 | - for (size_t j=0; j<b_templates; j++) | |
| 111 | - dist += distance->compare(cv::Mat(1, a_template_bytes, CV_8UC1, a+2*sizeof(size_t)+i*a_template_bytes), | |
| 112 | - cv::Mat(1, b_template_bytes, CV_8UC1, b+2*sizeof(size_t)+i*b_template_bytes)); | |
| 113 | - *similarity = a_templates * b_templates / dist; | |
| 114 | - return JANUS_SUCCESS; | |
| 115 | -} | |
| 101 | + int comparisons = 0; | |
| 102 | + janus_flat_template a_template = a; | |
| 103 | + while (a_template < a + a_bytes) { | |
| 104 | + const size_t a_template_bytes = *reinterpret_cast<size_t*>(a_template); | |
| 105 | + a_template += sizeof(a_template_bytes); | |
| 116 | 106 | |
| 117 | -struct janus_gallery_type : public TemplateList | |
| 118 | -{}; | |
| 107 | + janus_flat_template b_template = b; | |
| 108 | + while (b_template < b + b_bytes) { | |
| 109 | + const size_t b_template_bytes = *reinterpret_cast<size_t*>(b_template); | |
| 110 | + b_template += sizeof(b_template_bytes); | |
| 119 | 111 | |
| 120 | -janus_error janus_initialize_gallery(janus_gallery *gallery) | |
| 121 | -{ | |
| 122 | - *gallery = new janus_gallery_type(); | |
| 123 | - return JANUS_SUCCESS; | |
| 124 | -} | |
| 112 | + *similarity += distance->compare(cv::Mat(1, a_template_bytes, CV_8UC1, a_template), | |
| 113 | + cv::Mat(1, b_template_bytes, CV_8UC1, b_template)); | |
| 114 | + comparisons++; | |
| 125 | 115 | |
| 126 | -janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) | |
| 127 | -{ | |
| 128 | - template_->file.set("Template_ID", template_id); | |
| 129 | - gallery->append(*template_); | |
| 130 | - delete template_; | |
| 116 | + b_template += b_template_bytes; | |
| 117 | + } | |
| 118 | + | |
| 119 | + a_template += a_template_bytes; | |
| 120 | + } | |
| 121 | + | |
| 122 | + if (*similarity != *similarity) // True for NaN | |
| 123 | + return JANUS_UNKNOWN_ERROR; | |
| 124 | + | |
| 125 | + *similarity /= comparisons; | |
| 131 | 126 | return JANUS_SUCCESS; |
| 132 | 127 | } |
| 133 | 128 | |
| 134 | -janus_error janus_finalize_gallery(janus_gallery gallery, janus_gallery_file gallery_file) | |
| 129 | +janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) | |
| 135 | 130 | { |
| 136 | - QFile file(gallery_file); | |
| 137 | - if (!file.open(QFile::WriteOnly)) | |
| 131 | + template_->file.set("TEMPLATE_ID", template_id); | |
| 132 | + QFile file(gallery); | |
| 133 | + if (!file.open(QFile::WriteOnly | QFile::Append)) | |
| 138 | 134 | return JANUS_WRITE_ERROR; |
| 139 | 135 | QDataStream stream(&file); |
| 140 | - stream << gallery; | |
| 136 | + stream << *template_; | |
| 141 | 137 | file.close(); |
| 138 | + delete template_; | |
| 142 | 139 | return JANUS_SUCCESS; |
| 143 | 140 | } | ... | ... |
openbr/plugins/algorithms.cpp
| ... | ... | @@ -79,7 +79,7 @@ class AlgorithmsInitializer : public Initializer |
| 79 | 79 | 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"); |
| 80 | 80 | |
| 81 | 81 | // Transforms |
| 82 | - Globals->abbreviations.insert("FaceDetection", "(Open+Cvt(Gray)+Cascade(FrontalFace))"); | |
| 82 | + Globals->abbreviations.insert("FaceDetection", "Open+Cvt(Gray)+Cascade(FrontalFace)"); | |
| 83 | 83 | 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))"); |
| 84 | 84 | Globals->abbreviations.insert("DenseSIFT", "(Grid(10,10)+SIFTDescriptor(12)+ByRow)"); |
| 85 | 85 | Globals->abbreviations.insert("FaceRecognitionRegistration", "(ASEFEyes+Affine(88,88,0.25,0.35)+DownsampleTraining(FTE(DFFS),instances=1))"); | ... | ... |