Commit 819671f53303e492aef3f1ccbc4fd80bce65321d
Merge pull request #223 from biometrics/enroll_update
Drop filelist return from enroll, don't accumulate metadata during enroll
Showing
6 changed files
with
72 additions
and
37 deletions
openbr/core/core.cpp
| @@ -161,15 +161,13 @@ struct AlgorithmCore | @@ -161,15 +161,13 @@ struct AlgorithmCore | ||
| 161 | return name + file.baseName() + file.hash() + ".mem"; | 161 | return name + file.baseName() + file.hash() + ".mem"; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | - FileList enroll(File input, File gallery = File()) | 164 | + void enroll(File input, File gallery = File()) |
| 165 | { | 165 | { |
| 166 | - FileList files; | ||
| 167 | - | ||
| 168 | qDebug("Enrolling %s%s", qPrintable(input.flat()), | 166 | qDebug("Enrolling %s%s", qPrintable(input.flat()), |
| 169 | gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); | 167 | gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); |
| 170 | 168 | ||
| 171 | if (gallery.name.isEmpty()) { | 169 | if (gallery.name.isEmpty()) { |
| 172 | - if (input.name.isEmpty()) return FileList(); | 170 | + if (input.name.isEmpty()) return; |
| 173 | else gallery = getMemoryGallery(input); | 171 | else gallery = getMemoryGallery(input); |
| 174 | } | 172 | } |
| 175 | 173 | ||
| @@ -200,24 +198,18 @@ struct AlgorithmCore | @@ -200,24 +198,18 @@ struct AlgorithmCore | ||
| 200 | QScopedPointer<Transform> outputTform(Transform::make(outputDesc, NULL)); | 198 | QScopedPointer<Transform> outputTform(Transform::make(outputDesc, NULL)); |
| 201 | stages.append(outputTform.data()); | 199 | stages.append(outputTform.data()); |
| 202 | stages.append(progressCounter.data()); | 200 | stages.append(progressCounter.data()); |
| 203 | - QScopedPointer<Transform> discard(Transform::make("Discard",NULL)); | ||
| 204 | - stages.append(discard.data()); | ||
| 205 | 201 | ||
| 206 | QScopedPointer<Transform> pipeline(br::pipeTransforms(stages)); | 202 | QScopedPointer<Transform> pipeline(br::pipeTransforms(stages)); |
| 207 | 203 | ||
| 208 | - QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery)")); | 204 | + QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)")); |
| 209 | 205 | ||
| 210 | TemplateList data, output; | 206 | TemplateList data, output; |
| 211 | data.append(input); | 207 | data.append(input); |
| 212 | progressCounter->setPropertyRecursive("totalProgress", QString::number(total)); | 208 | progressCounter->setPropertyRecursive("totalProgress", QString::number(total)); |
| 213 | stream->projectUpdate(data, output); | 209 | stream->projectUpdate(data, output); |
| 214 | 210 | ||
| 215 | - files.append(output.files()); | ||
| 216 | - | ||
| 217 | if (multiProcess) | 211 | if (multiProcess) |
| 218 | delete enroll; | 212 | delete enroll; |
| 219 | - | ||
| 220 | - return files; | ||
| 221 | } | 213 | } |
| 222 | 214 | ||
| 223 | void project(File input, File output) | 215 | void project(File input, File output) |
| @@ -492,8 +484,6 @@ struct AlgorithmCore | @@ -492,8 +484,6 @@ struct AlgorithmCore | ||
| 492 | 484 | ||
| 493 | // The ProgressCounter transform will simply provide a display about the number of rows completed. | 485 | // The ProgressCounter transform will simply provide a display about the number of rows completed. |
| 494 | compareOutput.append(progressCounter.data()); | 486 | compareOutput.append(progressCounter.data()); |
| 495 | - QScopedPointer<Transform> discard(Transform::make("Discard",NULL)); | ||
| 496 | - compareOutput.append(discard.data()); | ||
| 497 | 487 | ||
| 498 | // With this, we have set up a transform which (optionally) enrolls templates, compares them | 488 | // With this, we have set up a transform which (optionally) enrolls templates, compares them |
| 499 | // against a gallery, and outputs them. | 489 | // against a gallery, and outputs them. |
| @@ -501,7 +491,7 @@ struct AlgorithmCore | @@ -501,7 +491,7 @@ struct AlgorithmCore | ||
| 501 | 491 | ||
| 502 | // Now, we will give that base transform to a stream, which will incrementally read the row gallery | 492 | // Now, we will give that base transform to a stream, which will incrementally read the row gallery |
| 503 | // and pass the transforms it reads through the base algorithm. | 493 | // and pass the transforms it reads through the base algorithm. |
| 504 | - QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery)")); | 494 | + QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)")); |
| 505 | 495 | ||
| 506 | // We set up a template containing the rowGallery we want to compare. | 496 | // We set up a template containing the rowGallery we want to compare. |
| 507 | TemplateList rowGalleryTemplate; | 497 | TemplateList rowGalleryTemplate; |
| @@ -632,9 +622,9 @@ void br::Train(const File &input, const File &model) | @@ -632,9 +622,9 @@ void br::Train(const File &input, const File &model) | ||
| 632 | AlgorithmManager::getAlgorithm(model.get<QString>("algorithm"))->train(input, model); | 622 | AlgorithmManager::getAlgorithm(model.get<QString>("algorithm"))->train(input, model); |
| 633 | } | 623 | } |
| 634 | 624 | ||
| 635 | -FileList br::Enroll(const File &input, const File &gallery) | 625 | +void br::Enroll(const File &input, const File &gallery) |
| 636 | { | 626 | { |
| 637 | - return AlgorithmManager::getAlgorithm(gallery.get<QString>("algorithm"))->enroll(input, gallery); | 627 | + AlgorithmManager::getAlgorithm(gallery.get<QString>("algorithm"))->enroll(input, gallery); |
| 638 | } | 628 | } |
| 639 | 629 | ||
| 640 | void br::Project(const File &input, const File &output) | 630 | void br::Project(const File &input, const File &output) |
openbr/gui/classifier.cpp
| @@ -37,7 +37,13 @@ void Classifier::setClassification(const QString &key, const QString &value) | @@ -37,7 +37,13 @@ void Classifier::setClassification(const QString &key, const QString &value) | ||
| 37 | void Classifier::_classify(File file) | 37 | void Classifier::_classify(File file) |
| 38 | { | 38 | { |
| 39 | QString key, value; | 39 | QString key, value; |
| 40 | - foreach (const File &f, Enroll(file.flat(), File("[algorithm=" + algorithm + "]"))) { | 40 | + QSharedPointer<Transform> transform = Transform::fromAlgorithm(algorithm); |
| 41 | + | ||
| 42 | + TemplateList input, output; | ||
| 43 | + input.append(file); | ||
| 44 | + transform->projectUpdate(input, output); | ||
| 45 | + | ||
| 46 | + foreach (const File &f, output.files() ) { | ||
| 41 | if (algorithm == "GenderClassification") key = "Gender"; | 47 | if (algorithm == "GenderClassification") key = "Gender"; |
| 42 | else if (algorithm == "AgeRegression") key = "Age"; | 48 | else if (algorithm == "AgeRegression") key = "Age"; |
| 43 | else key = algorithm; | 49 | else key = algorithm; |
openbr/gui/gallerytoolbar.cpp
| @@ -83,9 +83,10 @@ void br::GalleryToolBar::_enroll(const br::File &input) | @@ -83,9 +83,10 @@ void br::GalleryToolBar::_enroll(const br::File &input) | ||
| 83 | { | 83 | { |
| 84 | galleryLock.lock(); | 84 | galleryLock.lock(); |
| 85 | this->input = input; | 85 | this->input = input; |
| 86 | - if (input.suffix() == "gal") gallery = input.name + ".mem"; | ||
| 87 | - else gallery = QString("%1/galleries/%2.gal[cache]").arg(br::Globals->scratchPath(), qPrintable(input.baseName()+input.hash())); | ||
| 88 | - files = br::Enroll(input.flat(), gallery.flat()); | 86 | + gallery = input.name + ".mem"; |
| 87 | + br::Enroll(input.flat(), gallery.flat()); | ||
| 88 | + files = FileList::fromGallery(gallery); | ||
| 89 | + | ||
| 89 | galleryLock.unlock(); | 90 | galleryLock.unlock(); |
| 90 | } | 91 | } |
| 91 | 92 |
openbr/openbr_plugin.h
| @@ -1393,7 +1393,7 @@ BR_EXPORT void Train(const File &input, const File &model); | @@ -1393,7 +1393,7 @@ BR_EXPORT void Train(const File &input, const File &model); | ||
| 1393 | * \brief High-level function for creating galleries. | 1393 | * \brief High-level function for creating galleries. |
| 1394 | * \see br_enroll | 1394 | * \see br_enroll |
| 1395 | */ | 1395 | */ |
| 1396 | -BR_EXPORT FileList Enroll(const File &input, const File &gallery = File()); | 1396 | +BR_EXPORT void Enroll(const File &input, const File &gallery = File()); |
| 1397 | 1397 | ||
| 1398 | /*! | 1398 | /*! |
| 1399 | * \brief High-level function for enrolling templates. | 1399 | * \brief High-level function for enrolling templates. |
openbr/plugins/misc.cpp
| @@ -278,6 +278,23 @@ class DiscardTransform : public UntrainableMetaTransform | @@ -278,6 +278,23 @@ class DiscardTransform : public UntrainableMetaTransform | ||
| 278 | 278 | ||
| 279 | BR_REGISTER(Transform, DiscardTransform) | 279 | BR_REGISTER(Transform, DiscardTransform) |
| 280 | 280 | ||
| 281 | +class DiscardTemplatesTransform : public UntrainableMetaTransform | ||
| 282 | +{ | ||
| 283 | + Q_OBJECT | ||
| 284 | + | ||
| 285 | + void project(const Template &src, Template &dst) const | ||
| 286 | + { | ||
| 287 | + (void) src; (void) dst; | ||
| 288 | + qFatal("Incorrect project called on DiscardTemplatesTransform"); | ||
| 289 | + } | ||
| 290 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 291 | + { | ||
| 292 | + (void) src; | ||
| 293 | + dst.clear(); | ||
| 294 | + } | ||
| 295 | +}; | ||
| 296 | +BR_REGISTER(Transform, DiscardTemplatesTransform) | ||
| 297 | + | ||
| 281 | /*! | 298 | /*! |
| 282 | * \ingroup transforms | 299 | * \ingroup transforms |
| 283 | * \brief Removes all but the first matrix from the template. | 300 | * \brief Removes all but the first matrix from the template. |
openbr/plugins/stream.cpp
| @@ -1085,6 +1085,32 @@ public: | @@ -1085,6 +1085,32 @@ public: | ||
| 1085 | 1085 | ||
| 1086 | }; | 1086 | }; |
| 1087 | 1087 | ||
| 1088 | +class CollectOutputTransform : public TimeVaryingTransform | ||
| 1089 | +{ | ||
| 1090 | + Q_OBJECT | ||
| 1091 | +public: | ||
| 1092 | + CollectOutputTransform() : TimeVaryingTransform(false, false) {} | ||
| 1093 | + | ||
| 1094 | + TemplateList data; | ||
| 1095 | + | ||
| 1096 | + void projectUpdate(const TemplateList &src, TemplateList &dst) | ||
| 1097 | + { | ||
| 1098 | + (void) dst; | ||
| 1099 | + data.append(src); | ||
| 1100 | + } | ||
| 1101 | + | ||
| 1102 | + void finalize(TemplateList & output) | ||
| 1103 | + { | ||
| 1104 | + output = data; | ||
| 1105 | + data.clear(); | ||
| 1106 | + } | ||
| 1107 | + void train(const TemplateList &data) | ||
| 1108 | + { | ||
| 1109 | + (void) data; | ||
| 1110 | + } | ||
| 1111 | +}; | ||
| 1112 | +BR_REGISTER(Transform, CollectOutputTransform) | ||
| 1113 | + | ||
| 1088 | // This stage reads new frames from the data source. | 1114 | // This stage reads new frames from the data source. |
| 1089 | class ReadStage : public SingleThreadStage | 1115 | class ReadStage : public SingleThreadStage |
| 1090 | { | 1116 | { |
| @@ -1204,11 +1230,12 @@ class DirectStreamTransform : public CompositeTransform | @@ -1204,11 +1230,12 @@ class DirectStreamTransform : public CompositeTransform | ||
| 1204 | { | 1230 | { |
| 1205 | Q_OBJECT | 1231 | Q_OBJECT |
| 1206 | public: | 1232 | public: |
| 1207 | - | ||
| 1208 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) | 1233 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) |
| 1209 | Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) | 1234 | Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) |
| 1235 | + Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true) | ||
| 1210 | BR_PROPERTY(int, activeFrames, 100) | 1236 | BR_PROPERTY(int, activeFrames, 100) |
| 1211 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) | 1237 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) |
| 1238 | + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) | ||
| 1212 | 1239 | ||
| 1213 | friend class StreamTransfrom; | 1240 | friend class StreamTransfrom; |
| 1214 | 1241 | ||
| @@ -1349,22 +1376,19 @@ public: | @@ -1349,22 +1376,19 @@ public: | ||
| 1349 | } | 1376 | } |
| 1350 | final_output.append(output_set); | 1377 | final_output.append(output_set); |
| 1351 | } | 1378 | } |
| 1379 | + endPoint->projectUpdate(final_output); | ||
| 1352 | 1380 | ||
| 1353 | // Clear dst, since we set it to src so that the datasource could open it | 1381 | // Clear dst, since we set it to src so that the datasource could open it |
| 1354 | dst.clear(); | 1382 | dst.clear(); |
| 1355 | 1383 | ||
| 1356 | // dst is set to all output received by the final stage, along | 1384 | // dst is set to all output received by the final stage, along |
| 1357 | // with anything output via the calls to finalize. | 1385 | // with anything output via the calls to finalize. |
| 1358 | - foreach (const TemplateList &list, collector->sets) | ||
| 1359 | - dst.append(list); | ||
| 1360 | - | ||
| 1361 | - collector->sets.clear(); | ||
| 1362 | - | ||
| 1363 | - dst.append(final_output); | 1386 | + TemplateList output; |
| 1387 | + endPoint->finalize(output); | ||
| 1388 | + dst.append(output); | ||
| 1364 | 1389 | ||
| 1365 | foreach (ProcessingStage *stage, processingStages) | 1390 | foreach (ProcessingStage *stage, processingStages) |
| 1366 | stage->reset(); | 1391 | stage->reset(); |
| 1367 | - | ||
| 1368 | } | 1392 | } |
| 1369 | 1393 | ||
| 1370 | 1394 | ||
| @@ -1387,7 +1411,7 @@ public: | @@ -1387,7 +1411,7 @@ public: | ||
| 1387 | QMutexLocker poolLock(&poolsAccess); | 1411 | QMutexLocker poolLock(&poolsAccess); |
| 1388 | QHash<QObject *, QThreadPool *>::Iterator it; | 1412 | QHash<QObject *, QThreadPool *>::Iterator it; |
| 1389 | if (!pools.contains(this->parent())) { | 1413 | if (!pools.contains(this->parent())) { |
| 1390 | - it = pools.insert(this->parent(), new QThreadPool(this->parent())); | 1414 | + it = pools.insert(this->parent(), new QThreadPool()); |
| 1391 | it.value()->setMaxThreadCount(Globals->parallelism); | 1415 | it.value()->setMaxThreadCount(Globals->parallelism); |
| 1392 | } | 1416 | } |
| 1393 | else it = pools.find(this->parent()); | 1417 | else it = pools.find(this->parent()); |
| @@ -1440,7 +1464,7 @@ public: | @@ -1440,7 +1464,7 @@ public: | ||
| 1440 | // We also have the last stage, which just puts the output of the | 1464 | // We also have the last stage, which just puts the output of the |
| 1441 | // previous stages on a template list. | 1465 | // previous stages on a template list. |
| 1442 | collectionStage = new SingleThreadStage(prev_stage_variance); | 1466 | collectionStage = new SingleThreadStage(prev_stage_variance); |
| 1443 | - collectionStage->transform = this->collector.data(); | 1467 | + collectionStage->transform = this->endPoint; |
| 1444 | 1468 | ||
| 1445 | 1469 | ||
| 1446 | processingStages.append(collectionStage); | 1470 | processingStages.append(collectionStage); |
| @@ -1456,11 +1480,6 @@ public: | @@ -1456,11 +1480,6 @@ public: | ||
| 1456 | collectionStage->nextStage = readStage; | 1480 | collectionStage->nextStage = readStage; |
| 1457 | } | 1481 | } |
| 1458 | 1482 | ||
| 1459 | - DirectStreamTransform() | ||
| 1460 | - { | ||
| 1461 | - this->collector = QSharedPointer<CollectSets>(new CollectSets()); | ||
| 1462 | - } | ||
| 1463 | - | ||
| 1464 | ~DirectStreamTransform() | 1483 | ~DirectStreamTransform() |
| 1465 | { | 1484 | { |
| 1466 | // Delete all the stages | 1485 | // Delete all the stages |
| @@ -1476,7 +1495,6 @@ protected: | @@ -1476,7 +1495,6 @@ protected: | ||
| 1476 | 1495 | ||
| 1477 | ReadStage *readStage; | 1496 | ReadStage *readStage; |
| 1478 | SingleThreadStage *collectionStage; | 1497 | SingleThreadStage *collectionStage; |
| 1479 | - QSharedPointer<CollectSets> collector; | ||
| 1480 | 1498 | ||
| 1481 | QList<ProcessingStage *> processingStages; | 1499 | QList<ProcessingStage *> processingStages; |
| 1482 | 1500 | ||
| @@ -1525,11 +1543,13 @@ public: | @@ -1525,11 +1543,13 @@ public: | ||
| 1525 | { | 1543 | { |
| 1526 | } | 1544 | } |
| 1527 | 1545 | ||
| 1546 | + Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true) | ||
| 1528 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) | 1547 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) |
| 1529 | Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) | 1548 | Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) |
| 1530 | 1549 | ||
| 1531 | BR_PROPERTY(int, activeFrames, 100) | 1550 | BR_PROPERTY(int, activeFrames, 100) |
| 1532 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) | 1551 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) |
| 1552 | + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) | ||
| 1533 | 1553 | ||
| 1534 | bool timeVarying() const { return true; } | 1554 | bool timeVarying() const { return true; } |
| 1535 | 1555 | ||
| @@ -1571,6 +1591,7 @@ public: | @@ -1571,6 +1591,7 @@ public: | ||
| 1571 | basis->transforms.clear(); | 1591 | basis->transforms.clear(); |
| 1572 | basis->activeFrames = this->activeFrames; | 1592 | basis->activeFrames = this->activeFrames; |
| 1573 | basis->readMode = this->readMode; | 1593 | basis->readMode = this->readMode; |
| 1594 | + basis->endPoint = this->endPoint; | ||
| 1574 | 1595 | ||
| 1575 | // We need at least a CompositeTransform * to acess transform's children. | 1596 | // We need at least a CompositeTransform * to acess transform's children. |
| 1576 | CompositeTransform *downcast = dynamic_cast<CompositeTransform *> (transform); | 1597 | CompositeTransform *downcast = dynamic_cast<CompositeTransform *> (transform); |