Commit 0f1ec326201af39b480f0781f20b2d9f90bebcdd
1 parent
5dad9e23
implemented janus_verify
Showing
2 changed files
with
76 additions
and
20 deletions
openbr/janus.cpp
| ... | ... | @@ -8,51 +8,107 @@ |
| 8 | 8 | // Use the provided default implementation of some functions |
| 9 | 9 | #include "janus/src/janus.cpp" |
| 10 | 10 | |
| 11 | +using namespace br; | |
| 12 | + | |
| 13 | +static QSharedPointer<Transform> transform; | |
| 14 | +static QSharedPointer<Distance> distance; | |
| 15 | + | |
| 11 | 16 | janus_error janus_initialize(const char *sdk_path, const char *model_file) |
| 12 | 17 | { |
| 13 | 18 | int argc = 1; |
| 14 | - const char *argv[1] = { "" }; | |
| 15 | - br::Context::initialize(argc, (char**)argv, sdk_path); | |
| 19 | + const char *argv[1] = { "janus" }; | |
| 20 | + Context::initialize(argc, (char**)argv, sdk_path); | |
| 16 | 21 | QString algorithm = model_file; |
| 17 | - if (algorithm.isEmpty()) algorithm = "FaceRecognition"; | |
| 18 | - br::Globals->algorithm = algorithm; | |
| 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); | |
| 19 | 25 | return JANUS_SUCCESS; |
| 20 | 26 | } |
| 21 | 27 | |
| 22 | 28 | janus_error janus_finalize() |
| 23 | 29 | { |
| 24 | - br::Context::finalize(); | |
| 30 | + Context::finalize(); | |
| 25 | 31 | return JANUS_SUCCESS; |
| 26 | 32 | } |
| 27 | 33 | |
| 34 | +struct janus_incomplete_template_type | |
| 35 | +{ | |
| 36 | + QList<cv::Mat> data; | |
| 37 | +}; | |
| 38 | + | |
| 28 | 39 | janus_error janus_initialize_template(janus_incomplete_template *incomplete_template) |
| 29 | 40 | { |
| 30 | - (void) incomplete_template; | |
| 41 | + *incomplete_template = new janus_incomplete_template_type(); | |
| 31 | 42 | return JANUS_SUCCESS; |
| 32 | 43 | } |
| 33 | 44 | |
| 34 | 45 | janus_error janus_add_image(const janus_image image, const janus_attribute_list attributes, janus_incomplete_template incomplete_template) |
| 35 | 46 | { |
| 36 | - (void) image; | |
| 37 | - (void) attributes; | |
| 38 | - (void) incomplete_template; | |
| 47 | + Template t; | |
| 48 | + t.append(cv::Mat(image.height, | |
| 49 | + image.width, | |
| 50 | + image.color_space == JANUS_GRAY8 ? CV_8UC1 : CV_8UC1, | |
| 51 | + image.data)); | |
| 52 | + for (size_t i=0; i<attributes.size; i++) | |
| 53 | + t.file.set(janus_attribute_to_string(attributes.attributes[i]), attributes.values[i]); | |
| 54 | + | |
| 55 | + if (!t.file.contains("JANUS_RIGHT_EYE_X") || | |
| 56 | + !t.file.contains("JANUS_RIGHT_EYE_Y") || | |
| 57 | + !t.file.contains("JANUS_LEFT_EYE_X") || | |
| 58 | + !t.file.contains("JANUS_LEFT_EYE_Y")) | |
| 59 | + return JANUS_SUCCESS; | |
| 60 | + | |
| 61 | + t.file.set("Affine_0", QPointF(t.file.get<float>("JANUS_RIGHT_EYE_X"), t.file.get<float>("JANUS_RIGHT_EYE_Y"))); | |
| 62 | + t.file.set("Affine_1", QPointF(t.file.get<float>("JANUS_LEFT_EYE_X"), t.file.get<float>("JANUS_LEFT_EYE_Y"))); | |
| 63 | + Template u; | |
| 64 | + transform->project(t, u); | |
| 65 | + incomplete_template->data.append(u); | |
| 39 | 66 | return JANUS_SUCCESS; |
| 40 | 67 | } |
| 41 | 68 | |
| 42 | 69 | janus_error janus_finalize_template(janus_incomplete_template incomplete_template, janus_template template_, size_t *bytes) |
| 43 | -{ | |
| 44 | - (void) incomplete_template; | |
| 45 | - (void) template_; | |
| 46 | - *bytes = 0; | |
| 70 | +{ | |
| 71 | + size_t templateBytes = 0; | |
| 72 | + size_t numTemplates = 0; | |
| 73 | + *bytes = sizeof(templateBytes) + sizeof(numTemplates); | |
| 74 | + janus_template pos = template_ + *bytes; | |
| 75 | + | |
| 76 | + foreach (const cv::Mat &m, incomplete_template->data) { | |
| 77 | + assert(m.isContinuous()); | |
| 78 | + const size_t currentTemplateBytes = m.rows * m.cols * m.elemSize(); | |
| 79 | + if (templateBytes == 0) | |
| 80 | + templateBytes = currentTemplateBytes; | |
| 81 | + if (templateBytes != currentTemplateBytes) | |
| 82 | + return JANUS_UNKNOWN_ERROR; | |
| 83 | + if (*bytes + templateBytes > JANUS_MAX_TEMPLATE_SIZE) | |
| 84 | + break; | |
| 85 | + memcpy(pos, m.data, templateBytes); | |
| 86 | + *bytes += templateBytes; | |
| 87 | + pos = pos + templateBytes; | |
| 88 | + numTemplates++; | |
| 89 | + } | |
| 90 | + | |
| 91 | + *(reinterpret_cast<size_t*>(template_)+0) = templateBytes; | |
| 92 | + *(reinterpret_cast<size_t*>(template_)+1) = numTemplates; | |
| 93 | + delete incomplete_template; | |
| 47 | 94 | return JANUS_SUCCESS; |
| 48 | 95 | } |
| 49 | 96 | |
| 50 | -janus_error janus_verify(const janus_template a, const size_t a_bytes, const janus_template b, const size_t b_bytes, float *similarity) | |
| 97 | +janus_error janus_verify(const janus_template a, const janus_template b, float *similarity) | |
| 51 | 98 | { |
| 52 | - (void) a; | |
| 53 | - (void) a_bytes; | |
| 54 | - (void) b; | |
| 55 | - (void) b_bytes; | |
| 56 | - *similarity = 0; | |
| 99 | + size_t a_bytes, a_templates, b_bytes, b_templates; | |
| 100 | + a_bytes = *(reinterpret_cast<size_t*>(a)+0); | |
| 101 | + a_templates = *(reinterpret_cast<size_t*>(a)+1); | |
| 102 | + b_bytes = *(reinterpret_cast<size_t*>(b)+0); | |
| 103 | + b_templates = *(reinterpret_cast<size_t*>(b)+1); | |
| 104 | + if (a_bytes != b_bytes) | |
| 105 | + return JANUS_UNKNOWN_ERROR; | |
| 106 | + | |
| 107 | + float dist = 0; | |
| 108 | + for (size_t i=0; i<a_templates; i++) | |
| 109 | + for (size_t j=0; j<b_templates; j++) | |
| 110 | + dist += distance->compare(cv::Mat(1, a_bytes, CV_8UC1, a+2*sizeof(size_t)+i*a_bytes), | |
| 111 | + cv::Mat(1, b_bytes, CV_8UC1, b+2*sizeof(size_t)+i*b_bytes)); | |
| 112 | + *similarity = a_templates * b_templates / dist; | |
| 57 | 113 | return JANUS_SUCCESS; |
| 58 | 114 | } | ... | ... |