Commit 63596a8c07e442170ff00bbe05eeed4b53a4faf2

Authored by jklontz
2 parents b45acc40 93b7a3cd

Merge pull request #26 from biometrics/variable_output

Structural changes to the basic multi-template enrollment operation
sdk/core/core.cpp
... ... @@ -262,6 +262,9 @@ private:
262 262 QStringList words = QtUtils::parse(description, ':');
263 263 if (words.size() > 2) qFatal("Invalid algorithm format.");
264 264  
  265 + words[0].prepend("DistributeTemplate(");
  266 + words[0].append(")");
  267 +
265 268 transform = QSharedPointer<Transform>(Transform::make(words[0], NULL));
266 269 if (words.size() > 1) distance = QSharedPointer<Distance>(Distance::make(words[1], NULL));
267 270 }
... ...
sdk/openbr_plugin.cpp
... ... @@ -1202,10 +1202,8 @@ Transform *Transform::make(QString str, QObject *parent)
1202 1202 if (Globals->abbreviations.contains(str))
1203 1203 return make(Globals->abbreviations[str], parent);
1204 1204  
1205   - { // Check for use of '!' as shorthand for Expand(...)
1206   - QStringList words = parse(str, '!');
1207   - if (words.size() > 1)
1208   - return make("Expand([" + words.join(",") + "])", parent);
  1205 + { // Check for use of '!' as shorthand for Expand
  1206 + str.replace("!","+Expand+");
1209 1207 }
1210 1208  
1211 1209 { // Check for use of '+' as shorthand for Pipe(...)
... ... @@ -1250,17 +1248,6 @@ Transform *Transform::clone() const
1250 1248 return clone;
1251 1249 }
1252 1250  
1253   -static void _project(const Transform *transform, const Template *src, Template *dst)
1254   -{
1255   - try {
1256   - transform->project(*src, *dst);
1257   - } catch (...) {
1258   - qWarning("Exception triggered when processing %s with transform %s", qPrintable(src->file.flat()), qPrintable(transform->objectName()));
1259   - *dst = Template(src->file);
1260   - dst->file.set("FTE", true);
1261   - }
1262   -}
1263   -
1264 1251 static void _backProject(const Transform *transform, const Template *dst, Template *src)
1265 1252 {
1266 1253 try {
... ... @@ -1273,17 +1260,25 @@ static void _backProject(const Transform *transform, const Template *dst, Templa
1273 1260 }
1274 1261  
1275 1262  
  1263 +
  1264 +// Default project(TemplateList) -- call project(template) separately for each input
  1265 +// template
1276 1266 void Transform::project(const TemplateList &src, TemplateList &dst) const
1277 1267 {
1278   - dst.reserve(src.size());
1279   - for (int i=0; i<src.size(); i++) dst.append(Template());
1280   -
1281   - QList< QFuture<void> > futures;
1282   - if (Globals->parallelism) futures.reserve(src.size());
1283   - for (int i=0; i<src.size(); i++)
1284   - if (Globals->parallelism) futures.append(QtConcurrent::run(_project, this, &src[i], &dst[i]));
1285   - else _project (this, &src[i], &dst[i]);
1286   - if (Globals->parallelism) Globals->trackFutures(futures);
  1268 + dst.clear();
  1269 +
  1270 + // Project templates derived from a single image, default implementation: project each
  1271 + // input template to an ouptut template individually.
  1272 + foreach(const Template & src_template, src) {
  1273 + dst.append(Template(src_template.file));
  1274 + try {
  1275 + project(src_template, dst.back());
  1276 + } catch (...) {
  1277 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src_template.file.flat()), qPrintable(objectName()));
  1278 + dst.back() = Template(src_template.file);
  1279 + dst.back().file.set("FTE", true);
  1280 + }
  1281 + }
1287 1282 }
1288 1283  
1289 1284 void Transform::backProject(const Template &dst, Template &src) const
... ...
sdk/plugins/gallery.cpp
... ... @@ -590,10 +590,10 @@ class dbGallery : public Gallery
590 590 }
591 591  
592 592 QStringList labels = entries.keys();
  593 + qSort(labels);
  594 +
593 595 if (hasFilter && ((labels.size() > numSubjects) || (numSubjects == std::numeric_limits<int>::max())))
594 596 std::random_shuffle(labels.begin(), labels.end());
595   - else
596   - qSort(labels);
597 597  
598 598 foreach (const QString &label, labels) {
599 599 QList<Entry> entryList = entries[label];
... ...
sdk/plugins/meta.cpp
... ... @@ -86,66 +86,6 @@ static void incrementStep()
86 86 }
87 87  
88 88 /*!
89   - * \brief Use Expanded after basic calls that take a template list, used to implement ExpandTransform
90   - */
91   -class ExpandDecorator : public Transform
92   -{
93   - Q_OBJECT
94   -
95   - Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
96   - BR_PROPERTY(br::Transform*, transform, NULL)
97   -
98   -public:
99   - ExpandDecorator(Transform * input)
100   - {
101   - transform = input;
102   - transform->setParent(this);
103   - file = transform->file;
104   - setObjectName(transform->objectName());
105   - }
106   -
107   - void train(const TemplateList &data)
108   - {
109   - transform->train(data);
110   - }
111   -
112   - void project(const Template &src, Template &dst) const
113   - {
114   - transform->project(src, dst);
115   - }
116   -
117   - void project(const TemplateList &src, TemplateList &dst) const
118   - {
119   - transform->project(src, dst);
120   - dst = Expanded(dst);
121   - }
122   -
123   -
124   - void projectUpdate(const Template &src, Template &dst)
125   - {
126   - transform->projectUpdate(src, dst);
127   - }
128   -
129   - void projectUpdate(const TemplateList & src, TemplateList & dst)
130   - {
131   - transform->projectUpdate(src, dst);
132   - dst = Expanded(dst);
133   - }
134   -
135   - bool timeVarying() const
136   - {
137   - return transform->timeVarying();
138   - }
139   -
140   - void finalize(TemplateList & output)
141   - {
142   - transform->finalize(output);
143   - output = Expanded(output);
144   - }
145   -
146   -};
147   -
148   -/*!
149 89 * \brief A MetaTransform that aggregates some sub-transforms
150 90 */
151 91 class BR_EXPORT CompositeTransform : public TimeVaryingTransform
... ... @@ -291,12 +231,9 @@ protected:
291 231 // or if parallelism is disabled, handle them sequentially
292 232 void _project(const TemplateList &src, TemplateList &dst) const
293 233 {
294   - if (Globals->parallelism < 0) {
295   - dst = src;
296   - foreach (const Transform *f, transforms)
297   - dst >> *f;
298   - } else {
299   - Transform::project(src, dst);
  234 + dst = src;
  235 + foreach (const Transform *f, transforms) {
  236 + dst >> *f;
300 237 }
301 238 }
302 239  
... ... @@ -320,40 +257,26 @@ BR_REGISTER(Transform, PipeTransform)
320 257  
321 258 /*!
322 259 * \ingroup transforms
323   - * \brief Transforms in series with expansion step.
  260 + * \brief Performs an expansion step on input templatelists
324 261 * \author Josh Klontz \cite jklontz
325 262 *
326   - * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
327   - * Each matrix is expanded into its own template between steps.
  263 + * Each matrix in an input Template is expanded into its own template.
328 264 *
329 265 * \see PipeTransform
330 266 */
331   -class ExpandTransform : public PipeTransform
  267 +class ExpandTransform : public UntrainableMetaTransform
332 268 {
333 269 Q_OBJECT
334 270  
335   - void init()
  271 + virtual void project(const TemplateList &src, TemplateList &dst) const
336 272 {
337   - for (int i = 0; i < transforms.size(); i++)
338   - {
339   - transforms[i] = new ExpandDecorator(transforms[i]);
340   - }
341   - // Need to call this to set up timevariance correctly, and it won't
342   - // be called automatically
343   - CompositeTransform::init();
  273 + dst = Expanded(src);
344 274 }
345 275  
346   -protected:
347   -
348   - // Template list project -- project through transforms sequentially,
349   - // then expand the results, can't use Transform::Project(templateList) since
350   - // we need to expand between tranforms, so actually do need to overload this method
351   - void _project(const TemplateList &src, TemplateList &dst) const
  276 + virtual void project(const Template & src, Template & dst) const
352 277 {
353   - dst = src;
354   - for (int i=0; i<transforms.size(); i++) {
355   - dst >> *transforms[i];
356   - }
  278 + qFatal("this has gone bad");
  279 + (void) src; (void) dst;
357 280 }
358 281 };
359 282  
... ... @@ -405,12 +328,12 @@ class ForkTransform : public CompositeTransform
405 328 {
406 329 dst = src;
407 330 dst.reserve(src.size());
408   - for (int i=0; i<src.size(); i++) dst.append(Template());
  331 + for (int i=0; i<src.size(); i++) dst.append(Template(src[i].file));
409 332 foreach (Transform *f, transforms) {
410 333 TemplateList m;
411 334 f->projectUpdate(src, m);
412 335 if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
413   - for (int i=0; i<src.size(); i++) dst[i].append(m[i]);
  336 + for (int i=0; i<src.size(); i++) dst[i].merge(m[i]);
414 337 }
415 338 }
416 339  
... ... @@ -460,17 +383,13 @@ protected:
460 383  
461 384 void _project(const TemplateList &src, TemplateList &dst) const
462 385 {
463   - if (Globals->parallelism < 0) {
464   - dst.reserve(src.size());
465   - for (int i=0; i<src.size(); i++) dst.append(Template());
466   - foreach (const Transform *f, transforms) {
467   - TemplateList m;
468   - f->project(src, m);
469   - if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
470   - for (int i=0; i<src.size(); i++) dst[i].append(m[i]);
471   - }
472   - } else {
473   - Transform::project(src, dst);
  386 + dst.reserve(src.size());
  387 + for (int i=0; i<src.size(); i++) dst.append(Template(src[i].file));
  388 + foreach (const Transform *f, transforms) {
  389 + TemplateList m;
  390 + f->project(src, m);
  391 + if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
  392 + for (int i=0; i<src.size(); i++) dst[i].merge(m[i]);
474 393 }
475 394 }
476 395  
... ... @@ -670,6 +589,73 @@ class FTETransform : public Transform
670 589  
671 590 BR_REGISTER(Transform, FTETransform)
672 591  
  592 +
  593 +static void _projectList(const Transform *transform, const TemplateList *src, TemplateList *dst)
  594 +{
  595 + transform->project(*src, *dst);
  596 +}
  597 +
  598 +
  599 +class DistributeTemplateTransform : public UntrainableMetaTransform
  600 +{
  601 + Q_OBJECT
  602 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  603 + BR_PROPERTY(br::Transform*, transform, NULL)
  604 +
  605 +public:
  606 +
  607 + void project(const Template &src, Template &dst) const
  608 + {
  609 + TemplateList input;
  610 + input.append(src);
  611 + TemplateList output;
  612 + project(input, output);
  613 +
  614 + if (output.size() != 1) qFatal("output contains more than 1 template");
  615 + else dst = output[0];
  616 + }
  617 +
  618 +
  619 + // For each input template, form a single element TemplateList, push all those
  620 + // lists through transform, and form dst by concatenating the results.
  621 + // Process the single elemnt templates in parallel if parallelism is enabled.
  622 + void project(const TemplateList &src, TemplateList &dst) const
  623 + {
  624 + // Pre-allocate output for each template
  625 + QList<TemplateList> output_buffer;
  626 + output_buffer.reserve(src.size());
  627 +
  628 + // Can't declare this local to the loop because it would go out of scope
  629 + QList<TemplateList> input_buffer;
  630 + input_buffer.reserve(src.size());
  631 +
  632 + for (int i =0; i < src.size();i++) {
  633 + input_buffer.append(TemplateList());
  634 + output_buffer.append(TemplateList());
  635 + }
  636 +
  637 + QList< QFuture<void> > futures;
  638 + futures.reserve(src.size());
  639 + for (int i=0; i<src.size(); i++) {
  640 + input_buffer[i].append(src[i]);
  641 + if (Globals->parallelism)
  642 + futures.append(QtConcurrent::run(_projectList, transform, &input_buffer[i], &output_buffer[i]));
  643 + else
  644 + _projectList(transform, &input_buffer[i], &output_buffer[i]);
  645 + }
  646 +
  647 + if (Globals->parallelism)
  648 + Globals->trackFutures(futures);
  649 +
  650 + for (int i=0; i<src.size(); i++) dst.append(output_buffer[i]);
  651 + }
  652 +
  653 +
  654 + private:
  655 +
  656 +};
  657 +BR_REGISTER(Transform, DistributeTemplateTransform)
  658 +
673 659 } // namespace br
674 660  
675 661 #include "meta.moc"
... ...
1   -Subproject commit 3ab0a438e4d93ead1a7db346d221bbb4ae81ccf1
  1 +Subproject commit 09d1852fbdf4b745e3b92fc86620694ac0c41d61
... ...