Commit e11b68d680bd231b1abc4badf5fbf79fc5ed0ccb
1 parent
e0aabf8c
Add support for a simple append flag for enroll
This change consolidates the previous 'read' and 'noDuplicates' flags into a single 'append' flag. If append is specified, and an output gallery already exists, and the gallery format supports read/write or has explicit append support, then enrollment will be restricted to those files in the input list not already present in the gallery, and the results will be appended to the existing gallery. append defaults to 'false', which is a deparature from previous behavior. The .gal format has explicit append support, for other cases, if the gallery supports both read and write (less common than you might think), we support append by reading the existing gallery, and writing back out to an overwriting file. It should be possible to add explicit append support to several other gallery types.
Showing
5 changed files
with
72 additions
and
7 deletions
openbr/core/core.cpp
| @@ -121,6 +121,8 @@ struct AlgorithmCore | @@ -121,6 +121,8 @@ struct AlgorithmCore | ||
| 121 | 121 | ||
| 122 | FileList enroll(File input, File gallery = File()) | 122 | FileList enroll(File input, File gallery = File()) |
| 123 | { | 123 | { |
| 124 | + FileList files; | ||
| 125 | + | ||
| 124 | qDebug("Enrolling %s%s", qPrintable(input.flat()), | 126 | qDebug("Enrolling %s%s", qPrintable(input.flat()), |
| 125 | gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); | 127 | gallery.isNull() ? "" : qPrintable(" to " + gallery.flat())); |
| 126 | 128 | ||
| @@ -128,12 +130,29 @@ struct AlgorithmCore | @@ -128,12 +130,29 @@ struct AlgorithmCore | ||
| 128 | if (input.name.isEmpty()) return FileList(); | 130 | if (input.name.isEmpty()) return FileList(); |
| 129 | else gallery = getMemoryGallery(input); | 131 | else gallery = getMemoryGallery(input); |
| 130 | } | 132 | } |
| 133 | + TemplateList data(TemplateList::fromGallery(input)); | ||
| 134 | + | ||
| 135 | + if (gallery.contains("append")) | ||
| 136 | + { | ||
| 137 | + // Remove any templates which are already in the gallery | ||
| 138 | + QScopedPointer<Gallery> g(Gallery::make(gallery)); | ||
| 139 | + files = g->files(); | ||
| 140 | + QStringList names = files.names(); | ||
| 141 | + for (int i = data.size() - 1; i>=0; i--) { | ||
| 142 | + if (names.contains(data[i].file.name)) | ||
| 143 | + { | ||
| 144 | + data.removeAt(i); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + if (data.empty()) | ||
| 150 | + return files; | ||
| 131 | 151 | ||
| 132 | - TemplateList i(TemplateList::fromGallery(input)); | ||
| 133 | 152 | ||
| 134 | // Trust me, this makes complete sense. | 153 | // Trust me, this makes complete sense. |
| 135 | // We're just going to make a pipe with a placeholder first transform | 154 | // We're just going to make a pipe with a placeholder first transform |
| 136 | - QString pipeDesc = "Identity+ProgressCounter("+QString::number(i.length())+")+GalleryOutput("+gallery.flat()+")+Discard"; | 155 | + QString pipeDesc = "Identity+ProgressCounter("+QString::number(data.length())+")+GalleryOutput("+gallery.flat()+")+Discard"; |
| 137 | QScopedPointer<Transform> basePipe(Transform::make(pipeDesc,NULL)); | 156 | QScopedPointer<Transform> basePipe(Transform::make(pipeDesc,NULL)); |
| 138 | 157 | ||
| 139 | CompositeTransform * downcast = dynamic_cast<CompositeTransform *>(basePipe.data()); | 158 | CompositeTransform * downcast = dynamic_cast<CompositeTransform *>(basePipe.data()); |
| @@ -157,9 +176,10 @@ struct AlgorithmCore | @@ -157,9 +176,10 @@ struct AlgorithmCore | ||
| 157 | // and get the final stream's stages by reinterpreting the pipe. Perfectly straightforward. | 176 | // and get the final stream's stages by reinterpreting the pipe. Perfectly straightforward. |
| 158 | wrapper->init(); | 177 | wrapper->init(); |
| 159 | 178 | ||
| 160 | - wrapper->projectUpdate(i,i); | 179 | + wrapper->projectUpdate(data,data); |
| 161 | 180 | ||
| 162 | - return i.files(); | 181 | + files.append(data.files()); |
| 182 | + return files; | ||
| 163 | } | 183 | } |
| 164 | 184 | ||
| 165 | void enroll(TemplateList &data) | 185 | void enroll(TemplateList &data) |
openbr/openbr_plugin.cpp
| @@ -1153,6 +1153,17 @@ Gallery *Gallery::make(const File &file) | @@ -1153,6 +1153,17 @@ Gallery *Gallery::make(const File &file) | ||
| 1153 | return gallery; | 1153 | return gallery; |
| 1154 | } | 1154 | } |
| 1155 | 1155 | ||
| 1156 | +// Default init -- if the file contains "append", read the existing | ||
| 1157 | +// data and immediately write it | ||
| 1158 | +void Gallery::init() | ||
| 1159 | +{ | ||
| 1160 | + if (file.exists() && file.contains("append")) | ||
| 1161 | + { | ||
| 1162 | + TemplateList data = this->read(); | ||
| 1163 | + this->writeBlock(data); | ||
| 1164 | + } | ||
| 1165 | +} | ||
| 1166 | + | ||
| 1156 | /* Transform - public methods */ | 1167 | /* Transform - public methods */ |
| 1157 | Transform::Transform(bool _independent, bool _trainable) | 1168 | Transform::Transform(bool _independent, bool _trainable) |
| 1158 | { | 1169 | { |
openbr/openbr_plugin.h
| @@ -1060,6 +1060,7 @@ public: | @@ -1060,6 +1060,7 @@ public: | ||
| 1060 | void writeBlock(const TemplateList &templates); /*!< \brief Serialize a template list. */ | 1060 | void writeBlock(const TemplateList &templates); /*!< \brief Serialize a template list. */ |
| 1061 | virtual void write(const Template &t) = 0; /*!< \brief Serialize a template. */ | 1061 | virtual void write(const Template &t) = 0; /*!< \brief Serialize a template. */ |
| 1062 | static Gallery *make(const File &file); /*!< \brief Make a gallery to/from a file on disk. */ | 1062 | static Gallery *make(const File &file); /*!< \brief Make a gallery to/from a file on disk. */ |
| 1063 | + void init(); | ||
| 1063 | 1064 | ||
| 1064 | private: | 1065 | private: |
| 1065 | QSharedPointer<Gallery> next; | 1066 | QSharedPointer<Gallery> next; |
openbr/plugins/gallery.cpp
| @@ -73,6 +73,11 @@ class arffGallery : public Gallery | @@ -73,6 +73,11 @@ class arffGallery : public Gallery | ||
| 73 | arffFile.write(qPrintable(OpenCVUtils::matrixToStringList(t).join(','))); | 73 | arffFile.write(qPrintable(OpenCVUtils::matrixToStringList(t).join(','))); |
| 74 | arffFile.write(qPrintable(",'" + t.file.get<QString>("Label") + "'\n")); | 74 | arffFile.write(qPrintable(",'" + t.file.get<QString>("Label") + "'\n")); |
| 75 | } | 75 | } |
| 76 | + | ||
| 77 | + void init() | ||
| 78 | + { | ||
| 79 | + // | ||
| 80 | + } | ||
| 76 | }; | 81 | }; |
| 77 | 82 | ||
| 78 | BR_REGISTER(Gallery, arffGallery) | 83 | BR_REGISTER(Gallery, arffGallery) |
| @@ -94,7 +99,12 @@ class galGallery : public Gallery | @@ -94,7 +99,12 @@ class galGallery : public Gallery | ||
| 94 | if (file.get<bool>("remove", false)) | 99 | if (file.get<bool>("remove", false)) |
| 95 | gallery.remove(); | 100 | gallery.remove(); |
| 96 | QtUtils::touchDir(gallery); | 101 | QtUtils::touchDir(gallery); |
| 97 | - if (!gallery.open(QFile::ReadWrite | QFile::Append)) | 102 | + QFile::OpenMode mode = QFile::ReadWrite; |
| 103 | + | ||
| 104 | + if (file.contains("append")) | ||
| 105 | + mode |= QFile::Append; | ||
| 106 | + | ||
| 107 | + if (!gallery.open(mode)) | ||
| 98 | qFatal("Can't open gallery: %s", qPrintable(gallery.fileName())); | 108 | qFatal("Can't open gallery: %s", qPrintable(gallery.fileName())); |
| 99 | stream.setDevice(&gallery); | 109 | stream.setDevice(&gallery); |
| 100 | } | 110 | } |
| @@ -579,6 +589,11 @@ class templateGallery : public Gallery | @@ -579,6 +589,11 @@ class templateGallery : public Gallery | ||
| 579 | (void) t; | 589 | (void) t; |
| 580 | qFatal("No supported."); | 590 | qFatal("No supported."); |
| 581 | } | 591 | } |
| 592 | + | ||
| 593 | + void init() | ||
| 594 | + { | ||
| 595 | + // | ||
| 596 | + } | ||
| 582 | }; | 597 | }; |
| 583 | 598 | ||
| 584 | BR_REGISTER(Gallery, templateGallery) | 599 | BR_REGISTER(Gallery, templateGallery) |
| @@ -737,6 +752,11 @@ class dbGallery : public Gallery | @@ -737,6 +752,11 @@ class dbGallery : public Gallery | ||
| 737 | (void) t; | 752 | (void) t; |
| 738 | qFatal("Not supported."); | 753 | qFatal("Not supported."); |
| 739 | } | 754 | } |
| 755 | + | ||
| 756 | + void init() | ||
| 757 | + { | ||
| 758 | + // | ||
| 759 | + } | ||
| 740 | }; | 760 | }; |
| 741 | 761 | ||
| 742 | BR_REGISTER(Gallery, dbGallery) | 762 | BR_REGISTER(Gallery, dbGallery) |
| @@ -790,6 +810,11 @@ class googleGallery : public Gallery | @@ -790,6 +810,11 @@ class googleGallery : public Gallery | ||
| 790 | (void) t; | 810 | (void) t; |
| 791 | qFatal("Not supported."); | 811 | qFatal("Not supported."); |
| 792 | } | 812 | } |
| 813 | + | ||
| 814 | + void init() | ||
| 815 | + { | ||
| 816 | + // | ||
| 817 | + } | ||
| 793 | }; | 818 | }; |
| 794 | 819 | ||
| 795 | BR_REGISTER(Gallery, googleGallery) | 820 | BR_REGISTER(Gallery, googleGallery) |
| @@ -883,6 +908,11 @@ class FDDBGallery : public Gallery | @@ -883,6 +908,11 @@ class FDDBGallery : public Gallery | ||
| 883 | (void) t; | 908 | (void) t; |
| 884 | qFatal("Not implemented."); | 909 | qFatal("Not implemented."); |
| 885 | } | 910 | } |
| 911 | + | ||
| 912 | + void init() | ||
| 913 | + { | ||
| 914 | + // | ||
| 915 | + } | ||
| 886 | }; | 916 | }; |
| 887 | 917 | ||
| 888 | BR_REGISTER(Gallery, FDDBGallery) | 918 | BR_REGISTER(Gallery, FDDBGallery) |
| @@ -927,6 +957,11 @@ class landmarksGallery : public Gallery | @@ -927,6 +957,11 @@ class landmarksGallery : public Gallery | ||
| 927 | (void) t; | 957 | (void) t; |
| 928 | qFatal("Not implemented."); | 958 | qFatal("Not implemented."); |
| 929 | } | 959 | } |
| 960 | + | ||
| 961 | + void init() | ||
| 962 | + { | ||
| 963 | + // | ||
| 964 | + } | ||
| 930 | }; | 965 | }; |
| 931 | 966 | ||
| 932 | BR_REGISTER(Gallery, landmarksGallery) | 967 | BR_REGISTER(Gallery, landmarksGallery) |
openbr/plugins/misc.cpp
| @@ -520,8 +520,6 @@ class EventTransform : public UntrainableMetaTransform | @@ -520,8 +520,6 @@ class EventTransform : public UntrainableMetaTransform | ||
| 520 | BR_REGISTER(Transform, EventTransform) | 520 | BR_REGISTER(Transform, EventTransform) |
| 521 | 521 | ||
| 522 | 522 | ||
| 523 | -//ProgressCounter+Output | ||
| 524 | - | ||
| 525 | class GalleryOutputTransform : public TimeVaryingTransform | 523 | class GalleryOutputTransform : public TimeVaryingTransform |
| 526 | { | 524 | { |
| 527 | Q_OBJECT | 525 | Q_OBJECT |