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,6 +262,9 @@ private:
262 QStringList words = QtUtils::parse(description, ':'); 262 QStringList words = QtUtils::parse(description, ':');
263 if (words.size() > 2) qFatal("Invalid algorithm format."); 263 if (words.size() > 2) qFatal("Invalid algorithm format.");
264 264
  265 + words[0].prepend("DistributeTemplate(");
  266 + words[0].append(")");
  267 +
265 transform = QSharedPointer<Transform>(Transform::make(words[0], NULL)); 268 transform = QSharedPointer<Transform>(Transform::make(words[0], NULL));
266 if (words.size() > 1) distance = QSharedPointer<Distance>(Distance::make(words[1], NULL)); 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,10 +1202,8 @@ Transform *Transform::make(QString str, QObject *parent)
1202 if (Globals->abbreviations.contains(str)) 1202 if (Globals->abbreviations.contains(str))
1203 return make(Globals->abbreviations[str], parent); 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 { // Check for use of '+' as shorthand for Pipe(...) 1209 { // Check for use of '+' as shorthand for Pipe(...)
@@ -1250,17 +1248,6 @@ Transform *Transform::clone() const @@ -1250,17 +1248,6 @@ Transform *Transform::clone() const
1250 return clone; 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 static void _backProject(const Transform *transform, const Template *dst, Template *src) 1251 static void _backProject(const Transform *transform, const Template *dst, Template *src)
1265 { 1252 {
1266 try { 1253 try {
@@ -1273,17 +1260,25 @@ static void _backProject(const Transform *transform, const Template *dst, Templa @@ -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 void Transform::project(const TemplateList &src, TemplateList &dst) const 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 void Transform::backProject(const Template &dst, Template &src) const 1284 void Transform::backProject(const Template &dst, Template &src) const
sdk/plugins/gallery.cpp
@@ -590,10 +590,10 @@ class dbGallery : public Gallery @@ -590,10 +590,10 @@ class dbGallery : public Gallery
590 } 590 }
591 591
592 QStringList labels = entries.keys(); 592 QStringList labels = entries.keys();
  593 + qSort(labels);
  594 +
593 if (hasFilter && ((labels.size() > numSubjects) || (numSubjects == std::numeric_limits<int>::max()))) 595 if (hasFilter && ((labels.size() > numSubjects) || (numSubjects == std::numeric_limits<int>::max())))
594 std::random_shuffle(labels.begin(), labels.end()); 596 std::random_shuffle(labels.begin(), labels.end());
595 - else  
596 - qSort(labels);  
597 597
598 foreach (const QString &label, labels) { 598 foreach (const QString &label, labels) {
599 QList<Entry> entryList = entries[label]; 599 QList<Entry> entryList = entries[label];
sdk/plugins/meta.cpp
@@ -86,66 +86,6 @@ static void incrementStep() @@ -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 * \brief A MetaTransform that aggregates some sub-transforms 89 * \brief A MetaTransform that aggregates some sub-transforms
150 */ 90 */
151 class BR_EXPORT CompositeTransform : public TimeVaryingTransform 91 class BR_EXPORT CompositeTransform : public TimeVaryingTransform
@@ -291,12 +231,9 @@ protected: @@ -291,12 +231,9 @@ protected:
291 // or if parallelism is disabled, handle them sequentially 231 // or if parallelism is disabled, handle them sequentially
292 void _project(const TemplateList &src, TemplateList &dst) const 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,40 +257,26 @@ BR_REGISTER(Transform, PipeTransform)
320 257
321 /*! 258 /*!
322 * \ingroup transforms 259 * \ingroup transforms
323 - * \brief Transforms in series with expansion step. 260 + * \brief Performs an expansion step on input templatelists
324 * \author Josh Klontz \cite jklontz 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 * \see PipeTransform 265 * \see PipeTransform
330 */ 266 */
331 -class ExpandTransform : public PipeTransform 267 +class ExpandTransform : public UntrainableMetaTransform
332 { 268 {
333 Q_OBJECT 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,12 +328,12 @@ class ForkTransform : public CompositeTransform
405 { 328 {
406 dst = src; 329 dst = src;
407 dst.reserve(src.size()); 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 foreach (Transform *f, transforms) { 332 foreach (Transform *f, transforms) {
410 TemplateList m; 333 TemplateList m;
411 f->projectUpdate(src, m); 334 f->projectUpdate(src, m);
412 if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size."); 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,17 +383,13 @@ protected:
460 383
461 void _project(const TemplateList &src, TemplateList &dst) const 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,6 +589,73 @@ class FTETransform : public Transform
670 589
671 BR_REGISTER(Transform, FTETransform) 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 } // namespace br 659 } // namespace br
674 660
675 #include "meta.moc" 661 #include "meta.moc"
1 -Subproject commit 3ab0a438e4d93ead1a7db346d221bbb4ae81ccf1 1 +Subproject commit 09d1852fbdf4b745e3b92fc86620694ac0c41d61