Commit 9f6444f8e9892c46693bce439251b1a12585549f
Merge pull request #386 from biometrics/janus
Janus gallery updates
Showing
3 changed files
with
90 additions
and
62 deletions
openbr/janus.cpp
| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | #include "openbr_plugin.h" |
| 4 | 4 | #include "openbr/core/opencvutils.h" |
| 5 | 5 | #include "openbr/core/common.h" |
| 6 | +#include <fstream> | |
| 6 | 7 | using namespace br; |
| 7 | 8 | |
| 8 | 9 | static QSharedPointer<Transform> detect; |
| ... | ... | @@ -168,46 +169,71 @@ janus_error janus_free_template(janus_template template_) |
| 168 | 169 | struct janus_gallery_type : public QList<janus_template> |
| 169 | 170 | {}; |
| 170 | 171 | |
| 171 | -janus_error janus_allocate_gallery(janus_gallery *gallery_) | |
| 172 | +void unflatten_template(const janus_flat_template flat_template, const size_t template_bytes, janus_gallery gallery, const janus_template_id template_id) | |
| 172 | 173 | { |
| 173 | - *gallery_ = new janus_gallery_type(); | |
| 174 | - return JANUS_SUCCESS; | |
| 174 | + janus_template t; | |
| 175 | + JANUS_ASSERT(janus_allocate_template(&t)) | |
| 176 | + t->file.set("TEMPLATE_ID", QString::number((int)template_id)); | |
| 177 | + janus_flat_template flat_template_ = flat_template; | |
| 178 | + | |
| 179 | + while (flat_template_ < flat_template + template_bytes) { | |
| 180 | + size_t bytes = *reinterpret_cast<size_t*>(flat_template_); | |
| 181 | + flat_template_ += sizeof(bytes); | |
| 182 | + | |
| 183 | + t->append(cv::Mat(1, bytes, CV_8UC1, flat_template_).clone()); | |
| 184 | + flat_template_ += bytes; | |
| 185 | + } | |
| 186 | + gallery->append(t); | |
| 175 | 187 | } |
| 176 | 188 | |
| 177 | -janus_error janus_enroll(const janus_template template_, const janus_template_id template_id, janus_gallery gallery) | |
| 178 | -{ | |
| 179 | - template_->file.set("TEMPLATE_ID", template_id); | |
| 180 | - gallery->push_back(template_); | |
| 189 | +janus_error janus_write_gallery(const janus_flat_template *templates, const size_t *templates_bytes, const janus_template_id *template_ids, const size_t num_templates, janus_gallery_path gallery_path) | |
| 190 | +{ | |
| 191 | + std::ofstream file; | |
| 192 | + file.open(gallery_path, std::ios::out | std::ios::binary); | |
| 193 | + | |
| 194 | + for (size_t i=0; i<num_templates; i++) { | |
| 195 | + file.write((char*)&template_ids[i], sizeof(janus_template_id)); | |
| 196 | + file.write((char*)&templates_bytes[i], sizeof(size_t)); | |
| 197 | + file.write((char*)templates[i], templates_bytes[i]); | |
| 198 | + } | |
| 199 | + | |
| 200 | + file.close(); | |
| 181 | 201 | return JANUS_SUCCESS; |
| 182 | 202 | } |
| 183 | 203 | |
| 184 | -janus_error janus_free_gallery(janus_gallery gallery_) { | |
| 185 | - delete gallery_; | |
| 204 | +janus_error janus_open_gallery(janus_gallery_path gallery_path, janus_gallery *gallery) | |
| 205 | +{ | |
| 206 | + *gallery = new janus_gallery_type(); | |
| 207 | + std::ifstream file; | |
| 208 | + file.open(gallery_path, std::ios::in | std::ios::binary | std::ios::ate); | |
| 209 | + const size_t bytes = file.tellg(); | |
| 210 | + file.seekg(0, std::ios::beg); | |
| 211 | + janus_data *templates = new janus_data[bytes]; | |
| 212 | + file.read((char*)templates, bytes); | |
| 213 | + file.close(); | |
| 214 | + | |
| 215 | + janus_data *templates_ = templates; | |
| 216 | + while (templates_ < templates + bytes) { | |
| 217 | + janus_template_id template_id = *reinterpret_cast<janus_template_id*>(templates_); | |
| 218 | + templates_ += sizeof(janus_template_id); | |
| 219 | + const size_t template_bytes = *reinterpret_cast<size_t*>(templates_); | |
| 220 | + templates_ += sizeof(size_t); | |
| 221 | + | |
| 222 | + janus_flat_template flat_template = new janus_data[template_bytes]; | |
| 223 | + memcpy(flat_template, templates_, template_bytes); | |
| 224 | + templates_ += template_bytes; | |
| 225 | + | |
| 226 | + unflatten_template(flat_template, template_bytes, *gallery, template_id); | |
| 227 | + delete[] flat_template; | |
| 228 | + } | |
| 229 | + | |
| 230 | + delete[] templates; | |
| 186 | 231 | return JANUS_SUCCESS; |
| 187 | 232 | } |
| 188 | 233 | |
| 189 | -janus_error janus_flatten_gallery(janus_gallery gallery, janus_flat_gallery flat_gallery, size_t *bytes) | |
| 234 | +janus_error janus_close_gallery(janus_gallery gallery) | |
| 190 | 235 | { |
| 191 | - *bytes = 0; | |
| 192 | - foreach (const janus_template &t, *gallery) { | |
| 193 | - janus_template_id template_id = t->file.get<janus_template_id>("TEMPLATE_ID"); | |
| 194 | - | |
| 195 | - janus_flat_template u = new janus_data[janus_max_template_size()]; | |
| 196 | - size_t t_bytes = 0; | |
| 197 | - JANUS_ASSERT(janus_flatten_template(t, u, &t_bytes)) | |
| 198 | - memcpy(flat_gallery, &template_id, sizeof(template_id)); | |
| 199 | - flat_gallery += sizeof(template_id); | |
| 200 | - *bytes += sizeof(template_id); | |
| 201 | - | |
| 202 | - memcpy(flat_gallery, &t_bytes, sizeof(t_bytes)); | |
| 203 | - flat_gallery += sizeof(t_bytes); | |
| 204 | - *bytes += sizeof(t_bytes); | |
| 205 | - | |
| 206 | - memcpy(flat_gallery, u, t_bytes); | |
| 207 | - flat_gallery += t_bytes; | |
| 208 | - *bytes += t_bytes; | |
| 209 | - delete[] u; | |
| 210 | - } | |
| 236 | + delete gallery; | |
| 211 | 237 | return JANUS_SUCCESS; |
| 212 | 238 | } |
| 213 | 239 | |
| ... | ... | @@ -242,23 +268,22 @@ janus_error janus_verify(const janus_flat_template a, const size_t a_bytes, cons |
| 242 | 268 | return JANUS_SUCCESS; |
| 243 | 269 | } |
| 244 | 270 | |
| 245 | -janus_error janus_search(const janus_flat_template probe, const size_t probe_bytes, const janus_flat_gallery gallery, const size_t gallery_bytes, const size_t requested_returns, janus_template_id *template_ids, float *similarities, size_t *actual_returns) | |
| 271 | +janus_error janus_search(const janus_flat_template probe, const size_t probe_bytes, const janus_gallery gallery, const size_t requested_returns, janus_template_id *template_ids, float *similarities, size_t *actual_returns) | |
| 246 | 272 | { |
| 247 | 273 | typedef QPair<float, int> Pair; |
| 248 | 274 | QList<Pair> comparisons; comparisons.reserve(requested_returns); |
| 249 | - janus_flat_gallery target_gallery = gallery; | |
| 250 | - while (target_gallery < gallery + gallery_bytes) { | |
| 251 | - janus_template_id target_id = *reinterpret_cast<janus_template_id*>(target_gallery); | |
| 252 | - target_gallery += sizeof(target_id); | |
| 275 | + foreach (const janus_template &target_template, *gallery) { | |
| 276 | + janus_template_id target_id = target_template->file.get<janus_template_id>("TEMPLATE_ID"); | |
| 277 | + | |
| 278 | + size_t target_bytes; | |
| 279 | + janus_data *buffer = new janus_data[janus_max_template_size()]; | |
| 280 | + JANUS_ASSERT(janus_flatten_template(target_template, buffer, &target_bytes)) | |
| 253 | 281 | |
| 254 | - const size_t target_template_bytes = *reinterpret_cast<size_t*>(target_gallery); | |
| 255 | - target_gallery += sizeof(target_template_bytes); | |
| 256 | - janus_flat_template target_template_flat = new janus_data[target_template_bytes]; | |
| 257 | - memcpy(target_template_flat, target_gallery, target_template_bytes); | |
| 258 | - target_gallery += target_template_bytes; | |
| 282 | + janus_flat_template target_flat = new janus_data[target_bytes]; | |
| 283 | + memcpy(target_flat, buffer, target_bytes); | |
| 259 | 284 | |
| 260 | 285 | float similarity; |
| 261 | - JANUS_ASSERT(janus_verify(probe, probe_bytes, target_template_flat, target_template_bytes, &similarity)) | |
| 286 | + JANUS_ASSERT(janus_verify(probe, probe_bytes, target_flat, target_bytes, &similarity)) | |
| 262 | 287 | if ((size_t)comparisons.size() < requested_returns) { |
| 263 | 288 | comparisons.append(Pair(similarity, target_id)); |
| 264 | 289 | std::sort(comparisons.begin(), comparisons.end()); |
| ... | ... | @@ -270,7 +295,8 @@ janus_error janus_search(const janus_flat_template probe, const size_t probe_byt |
| 270 | 295 | std::sort(comparisons.begin(), comparisons.end()); |
| 271 | 296 | } |
| 272 | 297 | } |
| 273 | - delete[] target_template_flat; | |
| 298 | + delete[] buffer; | |
| 299 | + delete[] target_flat; | |
| 274 | 300 | } |
| 275 | 301 | *actual_returns = comparisons.size(); |
| 276 | 302 | QList<Pair> temp; temp.reserve(comparisons.size()); | ... | ... |
openbr/janus_io.cpp
| ... | ... | @@ -12,41 +12,43 @@ static void _janus_add_sample(vector<double> &samples, double sample) |
| 12 | 12 | samples.push_back(sample); |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | -static void _janus_create_template(const char *data_path, TemplateData templateData, janus_gallery gallery, bool verbose) | |
| 15 | +typedef QPair<janus_template_id, FlatTemplate> TemplatePair; | |
| 16 | + | |
| 17 | +TemplatePair _janus_create_flat_template(const char *data_path, TemplateData templateData, bool verbose) | |
| 16 | 18 | { |
| 17 | 19 | janus_template template_; |
| 18 | 20 | janus_template_id templateID; |
| 19 | 21 | JANUS_ASSERT(TemplateIterator::create(data_path, templateData, &template_, &templateID, verbose)) |
| 20 | 22 | templateData.release(); |
| 21 | - | |
| 22 | - static QMutex enrollLock; | |
| 23 | - QMutexLocker enrollLocker(&enrollLock); | |
| 24 | - | |
| 25 | - JANUS_ASSERT(janus_enroll(template_, templateID, gallery)) | |
| 23 | + return TemplatePair(templateID, FlatTemplate(template_)); | |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | -janus_error janus_create_gallery(const char *data_path, janus_metadata metadata, janus_gallery gallery, int verbose) | |
| 26 | +janus_error janus_create_gallery(const char *data_path, janus_metadata metadata, janus_gallery_path gallery_path, int verbose) | |
| 29 | 27 | { |
| 30 | 28 | TemplateIterator ti(metadata, true); |
| 31 | 29 | TemplateData templateData = ti.next(); |
| 32 | - QFutureSynchronizer<void> futures; | |
| 30 | + QFutureSynchronizer<TemplatePair> futures; | |
| 33 | 31 | while (!templateData.templateIDs.empty()) { |
| 34 | - futures.addFuture(QtConcurrent::run(_janus_create_template, data_path, templateData, gallery, verbose)); | |
| 32 | + futures.addFuture(QtConcurrent::run(_janus_create_flat_template, data_path, templateData, verbose)); | |
| 35 | 33 | templateData = ti.next(); |
| 36 | 34 | } |
| 37 | 35 | futures.waitForFinished(); |
| 38 | - return JANUS_SUCCESS; | |
| 39 | -} | |
| 36 | + QList< QFuture<TemplatePair> > flat_templates = futures.futures(); | |
| 40 | 37 | |
| 41 | -typedef QPair<janus_template_id, FlatTemplate> TemplatePair; | |
| 38 | + vector<janus_flat_template> templates; | |
| 39 | + vector<size_t> template_bytes; | |
| 40 | + vector<janus_template_id> template_ids; | |
| 41 | + size_t num_templates = 0; | |
| 42 | 42 | |
| 43 | -TemplatePair _janus_create_flat_template(const char *data_path, TemplateData templateData, bool verbose) | |
| 44 | -{ | |
| 45 | - janus_template template_; | |
| 46 | - janus_template_id templateID; | |
| 47 | - JANUS_ASSERT(TemplateIterator::create(data_path, templateData, &template_, &templateID, verbose)) | |
| 48 | - templateData.release(); | |
| 49 | - return TemplatePair(templateID, FlatTemplate(template_)); | |
| 43 | + foreach (const QFuture<TemplatePair> &future, flat_templates) { | |
| 44 | + template_ids.push_back(future.result().first); | |
| 45 | + template_bytes.push_back(future.result().second.data->bytes); | |
| 46 | + templates.push_back(future.result().second.data->flat_template); | |
| 47 | + num_templates++; | |
| 48 | + } | |
| 49 | + | |
| 50 | + JANUS_ASSERT(janus_write_gallery(&templates[0], &template_bytes[0], &template_ids[0], num_templates, gallery_path)) | |
| 51 | + return JANUS_SUCCESS; | |
| 50 | 52 | } |
| 51 | 53 | |
| 52 | 54 | janus_error janus_create_templates(const char *data_path, janus_metadata metadata, const char *gallery_file, int verbose) | ... | ... |