Commit 302e502136c35d51f3b355f3e35c394b6124b82f
1 parent
24229280
Explicitly surface the behavior of the end of a stream as a transform
By default, all processed templates are collected, and output at the end of the call to projectUpdate, but it is now possible to e.g. simply discard all results, if nothing more needs to be done with the processed templates.
Showing
3 changed files
with
56 additions
and
22 deletions
openbr/core/core.cpp
| ... | ... | @@ -198,12 +198,10 @@ struct AlgorithmCore |
| 198 | 198 | QScopedPointer<Transform> outputTform(Transform::make(outputDesc, NULL)); |
| 199 | 199 | stages.append(outputTform.data()); |
| 200 | 200 | stages.append(progressCounter.data()); |
| 201 | - QScopedPointer<Transform> discard(Transform::make("Discard",NULL)); | |
| 202 | - stages.append(discard.data()); | |
| 203 | 201 | |
| 204 | 202 | QScopedPointer<Transform> pipeline(br::pipeTransforms(stages)); |
| 205 | 203 | |
| 206 | - QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery)")); | |
| 204 | + QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)")); | |
| 207 | 205 | |
| 208 | 206 | TemplateList data, output; |
| 209 | 207 | data.append(input); |
| ... | ... | @@ -486,8 +484,6 @@ struct AlgorithmCore |
| 486 | 484 | |
| 487 | 485 | // The ProgressCounter transform will simply provide a display about the number of rows completed. |
| 488 | 486 | compareOutput.append(progressCounter.data()); |
| 489 | - QScopedPointer<Transform> discard(Transform::make("Discard",NULL)); | |
| 490 | - compareOutput.append(discard.data()); | |
| 491 | 487 | |
| 492 | 488 | // With this, we have set up a transform which (optionally) enrolls templates, compares them |
| 493 | 489 | // against a gallery, and outputs them. |
| ... | ... | @@ -495,7 +491,7 @@ struct AlgorithmCore |
| 495 | 491 | |
| 496 | 492 | // Now, we will give that base transform to a stream, which will incrementally read the row gallery |
| 497 | 493 | // and pass the transforms it reads through the base algorithm. |
| 498 | - QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery)")); | |
| 494 | + QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)")); | |
| 499 | 495 | |
| 500 | 496 | // We set up a template containing the rowGallery we want to compare. |
| 501 | 497 | TemplateList rowGalleryTemplate; | ... | ... |
openbr/plugins/misc.cpp
| ... | ... | @@ -278,6 +278,23 @@ class DiscardTransform : public UntrainableMetaTransform |
| 278 | 278 | |
| 279 | 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 | 299 | * \ingroup transforms |
| 283 | 300 | * \brief Removes all but the first matrix from the template. | ... | ... |
openbr/plugins/stream.cpp
| ... | ... | @@ -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 | 1114 | // This stage reads new frames from the data source. |
| 1089 | 1115 | class ReadStage : public SingleThreadStage |
| 1090 | 1116 | { |
| ... | ... | @@ -1204,11 +1230,12 @@ class DirectStreamTransform : public CompositeTransform |
| 1204 | 1230 | { |
| 1205 | 1231 | Q_OBJECT |
| 1206 | 1232 | public: |
| 1207 | - | |
| 1208 | 1233 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) |
| 1209 | 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 | 1236 | BR_PROPERTY(int, activeFrames, 100) |
| 1211 | 1237 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) |
| 1238 | + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) | |
| 1212 | 1239 | |
| 1213 | 1240 | friend class StreamTransfrom; |
| 1214 | 1241 | |
| ... | ... | @@ -1349,22 +1376,19 @@ public: |
| 1349 | 1376 | } |
| 1350 | 1377 | final_output.append(output_set); |
| 1351 | 1378 | } |
| 1379 | + endPoint->projectUpdate(final_output); | |
| 1352 | 1380 | |
| 1353 | 1381 | // Clear dst, since we set it to src so that the datasource could open it |
| 1354 | 1382 | dst.clear(); |
| 1355 | 1383 | |
| 1356 | 1384 | // dst is set to all output received by the final stage, along |
| 1357 | 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 | 1390 | foreach (ProcessingStage *stage, processingStages) |
| 1366 | 1391 | stage->reset(); |
| 1367 | - | |
| 1368 | 1392 | } |
| 1369 | 1393 | |
| 1370 | 1394 | |
| ... | ... | @@ -1387,7 +1411,7 @@ public: |
| 1387 | 1411 | QMutexLocker poolLock(&poolsAccess); |
| 1388 | 1412 | QHash<QObject *, QThreadPool *>::Iterator it; |
| 1389 | 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 | 1415 | it.value()->setMaxThreadCount(Globals->parallelism); |
| 1392 | 1416 | } |
| 1393 | 1417 | else it = pools.find(this->parent()); |
| ... | ... | @@ -1440,7 +1464,7 @@ public: |
| 1440 | 1464 | // We also have the last stage, which just puts the output of the |
| 1441 | 1465 | // previous stages on a template list. |
| 1442 | 1466 | collectionStage = new SingleThreadStage(prev_stage_variance); |
| 1443 | - collectionStage->transform = this->collector.data(); | |
| 1467 | + collectionStage->transform = this->endPoint; | |
| 1444 | 1468 | |
| 1445 | 1469 | |
| 1446 | 1470 | processingStages.append(collectionStage); |
| ... | ... | @@ -1456,11 +1480,6 @@ public: |
| 1456 | 1480 | collectionStage->nextStage = readStage; |
| 1457 | 1481 | } |
| 1458 | 1482 | |
| 1459 | - DirectStreamTransform() | |
| 1460 | - { | |
| 1461 | - this->collector = QSharedPointer<CollectSets>(new CollectSets()); | |
| 1462 | - } | |
| 1463 | - | |
| 1464 | 1483 | ~DirectStreamTransform() |
| 1465 | 1484 | { |
| 1466 | 1485 | // Delete all the stages |
| ... | ... | @@ -1476,7 +1495,6 @@ protected: |
| 1476 | 1495 | |
| 1477 | 1496 | ReadStage *readStage; |
| 1478 | 1497 | SingleThreadStage *collectionStage; |
| 1479 | - QSharedPointer<CollectSets> collector; | |
| 1480 | 1498 | |
| 1481 | 1499 | QList<ProcessingStage *> processingStages; |
| 1482 | 1500 | |
| ... | ... | @@ -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 | 1547 | Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames) |
| 1529 | 1548 | Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode) |
| 1530 | 1549 | |
| 1531 | 1550 | BR_PROPERTY(int, activeFrames, 100) |
| 1532 | 1551 | BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto) |
| 1552 | + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput")) | |
| 1533 | 1553 | |
| 1534 | 1554 | bool timeVarying() const { return true; } |
| 1535 | 1555 | |
| ... | ... | @@ -1571,6 +1591,7 @@ public: |
| 1571 | 1591 | basis->transforms.clear(); |
| 1572 | 1592 | basis->activeFrames = this->activeFrames; |
| 1573 | 1593 | basis->readMode = this->readMode; |
| 1594 | + basis->endPoint = this->endPoint; | |
| 1574 | 1595 | |
| 1575 | 1596 | // We need at least a CompositeTransform * to acess transform's children. |
| 1576 | 1597 | CompositeTransform *downcast = dynamic_cast<CompositeTransform *> (transform); | ... | ... |