Commit 4fe4b46af90c622e8453c1f8fcf3f76b1b2ae071
Merge pull request #261 from biometrics/janus_eval
Updates for latest janus
Showing
2 changed files
with
91 additions
and
66 deletions
openbr/janus.cpp
| 1 | -#include "janus.h" | |
| 2 | -#include "janus_io.h" | |
| 1 | +#include "iarpa_janus.h" | |
| 2 | +#include "iarpa_janus_io.h" | |
| 3 | 3 | #include "openbr_plugin.h" |
| 4 | 4 | #include "openbr/core/opencvutils.h" |
| 5 | 5 | #include "openbr/core/common.h" |
| 6 | - | |
| 7 | 6 | using namespace br; |
| 8 | 7 | |
| 9 | 8 | static QSharedPointer<Transform> transform; |
| ... | ... | @@ -11,15 +10,16 @@ static QSharedPointer<Distance> distance; |
| 11 | 10 | |
| 12 | 11 | size_t janus_max_template_size() |
| 13 | 12 | { |
| 14 | - return 33554432; // 32 MB | |
| 13 | + return 102400;// 100 KB | |
| 15 | 14 | } |
| 16 | 15 | |
| 17 | -janus_error janus_initialize(const char *sdk_path, const char *model_file) | |
| 16 | +janus_error janus_initialize(const char *sdk_path, const char *temp_path, const char *model_file) | |
| 18 | 17 | { |
| 19 | 18 | int argc = 1; |
| 20 | 19 | const char *argv[1] = { "janus" }; |
| 21 | 20 | Context::initialize(argc, (char**)argv, sdk_path, false); |
| 22 | 21 | Globals->quiet = true; |
| 22 | + Globals->file.set(QString("temp_path"), QString(temp_path)); | |
| 23 | 23 | const QString algorithm = model_file; |
| 24 | 24 | if (algorithm.isEmpty()) { |
| 25 | 25 | transform.reset(Transform::make("Cvt(Gray)+Affine(88,88,0.25,0.35)+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>", NULL)); |
| ... | ... | @@ -42,7 +42,7 @@ janus_error janus_finalize() |
| 42 | 42 | struct janus_template_type : public Template |
| 43 | 43 | {}; |
| 44 | 44 | |
| 45 | -janus_error janus_allocate(janus_template *template_) | |
| 45 | +janus_error janus_allocate_template(janus_template *template_) | |
| 46 | 46 | { |
| 47 | 47 | *template_ = new janus_template_type(); |
| 48 | 48 | return JANUS_SUCCESS; |
| ... | ... | @@ -74,7 +74,7 @@ janus_error janus_augment(const janus_image image, const janus_attribute_list at |
| 74 | 74 | return (u.isEmpty() || !u.first().data) ? JANUS_FAILURE_TO_ENROLL : JANUS_SUCCESS; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | -janus_error janus_flatten(janus_template template_, janus_flat_template flat_template, size_t *bytes) | |
| 77 | +janus_error janus_flatten_template(janus_template template_, janus_flat_template flat_template, size_t *bytes) | |
| 78 | 78 | { |
| 79 | 79 | *bytes = 0; |
| 80 | 80 | foreach (const cv::Mat &m, *template_) { |
| ... | ... | @@ -99,12 +99,58 @@ janus_error janus_flatten(janus_template template_, janus_flat_template flat_tem |
| 99 | 99 | return JANUS_SUCCESS; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | -janus_error janus_free(janus_template template_) | |
| 102 | +janus_error janus_free_template(janus_template template_) | |
| 103 | 103 | { |
| 104 | 104 | delete template_; |
| 105 | 105 | return JANUS_SUCCESS; |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | +struct janus_gallery_type : public QList<janus_template> | |
| 109 | +{}; | |
| 110 | + | |
| 111 | +janus_error janus_allocate_gallery(janus_gallery *gallery_) | |
| 112 | +{ | |
| 113 | + *gallery_ = new janus_gallery_type(); | |
| 114 | + return JANUS_SUCCESS; | |
| 115 | +} | |
| 116 | + | |
| 117 | +janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) | |
| 118 | +{ | |
| 119 | + template_->file.set("TEMPLATE_ID", template_id); | |
| 120 | + gallery->push_back(template_); | |
| 121 | + return JANUS_SUCCESS; | |
| 122 | +} | |
| 123 | + | |
| 124 | +janus_error janus_free_gallery(janus_gallery gallery_) { | |
| 125 | + delete gallery_; | |
| 126 | + return JANUS_SUCCESS; | |
| 127 | +} | |
| 128 | + | |
| 129 | +janus_error janus_flatten_gallery(janus_gallery gallery, janus_flat_gallery flat_gallery, size_t *bytes) | |
| 130 | +{ | |
| 131 | + *bytes = 0; | |
| 132 | + foreach (const janus_template &t, *gallery) { | |
| 133 | + janus_template_id template_id = t->file.get<janus_template_id>("TEMPLATE_ID"); | |
| 134 | + | |
| 135 | + janus_flat_template u = new janus_data[janus_max_template_size()]; | |
| 136 | + size_t t_bytes = 0; | |
| 137 | + JANUS_ASSERT(janus_flatten_template(t, u, &t_bytes)) | |
| 138 | + memcpy(flat_gallery, &template_id, sizeof(template_id)); | |
| 139 | + flat_gallery += sizeof(template_id); | |
| 140 | + *bytes += sizeof(template_id); | |
| 141 | + | |
| 142 | + memcpy(flat_gallery, &t_bytes, sizeof(t_bytes)); | |
| 143 | + flat_gallery += sizeof(t_bytes); | |
| 144 | + *bytes += sizeof(t_bytes); | |
| 145 | + | |
| 146 | + memcpy(flat_gallery, u, t_bytes); | |
| 147 | + flat_gallery += t_bytes; | |
| 148 | + *bytes += t_bytes; | |
| 149 | + delete[] u; | |
| 150 | + } | |
| 151 | + return JANUS_SUCCESS; | |
| 152 | +} | |
| 153 | + | |
| 108 | 154 | janus_error janus_verify(const janus_flat_template a, const size_t a_bytes, const janus_flat_template b, const size_t b_bytes, float *similarity) |
| 109 | 155 | { |
| 110 | 156 | *similarity = 0; |
| ... | ... | @@ -114,12 +160,10 @@ janus_error janus_verify(const janus_flat_template a, const size_t a_bytes, cons |
| 114 | 160 | while (a_template < a + a_bytes) { |
| 115 | 161 | const size_t a_template_bytes = *reinterpret_cast<size_t*>(a_template); |
| 116 | 162 | a_template += sizeof(a_template_bytes); |
| 117 | - | |
| 118 | 163 | janus_flat_template b_template = b; |
| 119 | 164 | while (b_template < b + b_bytes) { |
| 120 | 165 | const size_t b_template_bytes = *reinterpret_cast<size_t*>(b_template); |
| 121 | 166 | b_template += sizeof(b_template_bytes); |
| 122 | - | |
| 123 | 167 | *similarity += distance->compare(cv::Mat(1, a_template_bytes, CV_8UC1, a_template), |
| 124 | 168 | cv::Mat(1, b_template_bytes, CV_8UC1, b_template)); |
| 125 | 169 | comparisons++; |
| ... | ... | @@ -138,62 +182,43 @@ janus_error janus_verify(const janus_flat_template a, const size_t a_bytes, cons |
| 138 | 182 | return JANUS_SUCCESS; |
| 139 | 183 | } |
| 140 | 184 | |
| 141 | -janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) | |
| 142 | -{ | |
| 143 | - template_->file.set("TEMPLATE_ID", template_id); | |
| 144 | - QFile file(gallery); | |
| 145 | - if (!file.open(QFile::WriteOnly | QFile::Append)) | |
| 146 | - return JANUS_WRITE_ERROR; | |
| 147 | - QDataStream stream(&file); | |
| 148 | - stream << *template_; | |
| 149 | - file.close(); | |
| 150 | - return JANUS_SUCCESS; | |
| 151 | -} | |
| 152 | - | |
| 153 | -janus_error janus_gallery_size(janus_gallery gallery, size_t *size) | |
| 154 | -{ | |
| 155 | - *size = TemplateList::fromGallery(gallery).size(); | |
| 156 | - return JANUS_SUCCESS; | |
| 157 | -} | |
| 158 | - | |
| 159 | -janus_error janus_search(const janus_template template_, janus_gallery gallery, int requested_returns, janus_template_id *template_ids, float *similarities, int *actual_returns) | |
| 185 | +janus_error janus_search(const janus_flat_template probe, const size_t probe_bytes, const janus_flat_gallery gallery, const size_t gallery_bytes, int requested_returns, janus_template_id *template_ids, float *similarities, int *actual_returns) | |
| 160 | 186 | { |
| 161 | - TemplateList query; | |
| 162 | - query.append(*template_); | |
| 163 | - | |
| 164 | - const TemplateList targets = TemplateList::fromGallery(gallery); | |
| 165 | - | |
| 166 | - if (targets.size() < requested_returns) *actual_returns = targets.size(); | |
| 167 | - else *actual_returns = requested_returns; | |
| 168 | - | |
| 169 | - QScopedPointer<MatrixOutput> matrix(MatrixOutput::make(targets.files(), query.files())); | |
| 170 | - distance->compare(targets, query, matrix.data()); | |
| 171 | - | |
| 172 | - typedef QPair<float,int> Pair; | |
| 173 | - QList<Pair> sortedSimilarities = Common::Sort(OpenCVUtils::matrixToVector<float>(matrix.data()->data.row(0)), true, *actual_returns); | |
| 174 | - | |
| 175 | - FileList targetFiles; | |
| 176 | - for (int i=0; i<sortedSimilarities.size(); i++) { | |
| 177 | - matrix.data()->data.at<float>(0,i) = sortedSimilarities[i].first; | |
| 178 | - targetFiles.append(targets[sortedSimilarities[i].second]); | |
| 187 | + typedef QPair<float, int> Pair; | |
| 188 | + QList<Pair> comparisons; comparisons.reserve(requested_returns); | |
| 189 | + janus_flat_gallery target_gallery = gallery; | |
| 190 | + while (target_gallery < gallery + gallery_bytes) { | |
| 191 | + janus_template_id target_id = *reinterpret_cast<janus_template_id*>(target_gallery); | |
| 192 | + target_gallery += sizeof(target_id); | |
| 193 | + | |
| 194 | + const size_t target_template_bytes = *reinterpret_cast<size_t*>(target_gallery); | |
| 195 | + target_gallery += sizeof(target_template_bytes); | |
| 196 | + janus_flat_template target_template_flat = new janus_data[target_template_bytes]; | |
| 197 | + memcpy(target_template_flat, target_gallery, target_template_bytes); | |
| 198 | + target_gallery += target_template_bytes; | |
| 199 | + | |
| 200 | + float similarity; | |
| 201 | + JANUS_ASSERT(janus_verify(probe, probe_bytes, target_template_flat, target_template_bytes, &similarity)) | |
| 202 | + if (comparisons.size() < requested_returns) { | |
| 203 | + comparisons.append(Pair(similarity, target_id)); | |
| 204 | + std::sort(comparisons.begin(), comparisons.end()); | |
| 205 | + } else { | |
| 206 | + Pair temp = comparisons.first(); | |
| 207 | + if (temp.first < similarity) { | |
| 208 | + comparisons.removeFirst(); | |
| 209 | + comparisons.append(Pair(similarity, target_id)); | |
| 210 | + std::sort(comparisons.begin(), comparisons.end()); | |
| 211 | + } | |
| 212 | + } | |
| 213 | + delete[] target_template_flat; | |
| 214 | + } | |
| 215 | + *actual_returns = comparisons.size(); | |
| 216 | + QList<Pair> temp; temp.reserve(comparisons.size()); | |
| 217 | + std::reverse_copy(comparisons.begin(), comparisons.end(), std::back_inserter(temp)); | |
| 218 | + comparisons = temp; | |
| 219 | + foreach(const Pair &comparison, comparisons) { | |
| 220 | + *similarities = comparison.first; similarities++; | |
| 221 | + *template_ids = comparison.second; template_ids++; | |
| 179 | 222 | } |
| 180 | - const QVector<janus_template_id> targetIds = File::get<janus_template_id,File>(targetFiles, "TEMPLATE_ID").toVector(); | |
| 181 | - | |
| 182 | - memcpy(similarities, matrix->data.data, *actual_returns * sizeof(float)); | |
| 183 | - memcpy(template_ids, targetIds.data(), *actual_returns * sizeof(janus_template_id)); | |
| 184 | - return JANUS_SUCCESS; | |
| 185 | -} | |
| 186 | - | |
| 187 | -janus_error janus_compare(janus_gallery target, janus_gallery query, float *similarity_matrix, janus_template_id *target_ids, janus_template_id *query_ids) | |
| 188 | -{ | |
| 189 | - const TemplateList targets = TemplateList::fromGallery(target); | |
| 190 | - const TemplateList queries = TemplateList::fromGallery(query); | |
| 191 | - QScopedPointer<MatrixOutput> matrix(MatrixOutput::make(targets.files(), queries.files())); | |
| 192 | - distance->compare(targets, queries, matrix.data()); | |
| 193 | - const QVector<janus_template_id> targetIds = File::get<janus_template_id,File>(matrix->targetFiles, "TEMPLATE_ID").toVector(); | |
| 194 | - const QVector<janus_template_id> queryIds = File::get<janus_template_id,File>(matrix->queryFiles, "TEMPLATE_ID").toVector(); | |
| 195 | - memcpy(similarity_matrix, matrix->data.data, matrix->data.rows * matrix->data.cols * sizeof(float)); | |
| 196 | - memcpy(target_ids, targetIds.data(), targetIds.size() * sizeof(janus_template_id)); | |
| 197 | - memcpy(query_ids, queryIds.data(), queryIds.size() * sizeof(janus_template_id)); | |
| 198 | 223 | return JANUS_SUCCESS; |
| 199 | 224 | } | ... | ... |