Commit 9f6444f8e9892c46693bce439251b1a12585549f

Authored by Ben Klein
2 parents 75ce1053 be7b6a07

Merge pull request #386 from biometrics/janus

Janus gallery updates
1   -Subproject commit 23a5abb16a20efb551cd8dd21f245e2d1603e657
  1 +Subproject commit daf6e66f6c5de45bb0dc15658a4fc581daf88f37
... ...
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&lt;double&gt; &amp;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)
... ...