Commit 9670e296b81c60e55c01ab6a9f6074dbc713b8fa
Merge branch 'master' of https://github.com/biometrics/openbr into training_structure
Showing
4 changed files
with
99 additions
and
74 deletions
openbr/plugins/meta.cpp
| ... | ... | @@ -254,7 +254,6 @@ class ContractTransform : public UntrainableMetaTransform |
| 254 | 254 | |
| 255 | 255 | virtual void project(const TemplateList &src, TemplateList &dst) const |
| 256 | 256 | { |
| 257 | - //dst = Expanded(src); | |
| 258 | 257 | if (src.empty()) return; |
| 259 | 258 | Template out; |
| 260 | 259 | |
| ... | ... | @@ -692,8 +691,10 @@ public: |
| 692 | 691 | |
| 693 | 692 | void init() |
| 694 | 693 | { |
| 695 | - if (transform && transform->timeVarying()) | |
| 696 | - transform = new br::TimeInvariantWrapperTransform(transform); | |
| 694 | + if (!transform) | |
| 695 | + return; | |
| 696 | + | |
| 697 | + trainable = transform->trainable; | |
| 697 | 698 | } |
| 698 | 699 | |
| 699 | 700 | }; | ... | ... |
openbr/plugins/openbr_internal.h
| ... | ... | @@ -24,81 +24,27 @@ private: |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | /*! |
| 27 | - * \brief A br::MetaTransform that does not require training data. | |
| 27 | + * \brief A br::Transform expecting multiple matrices per template. | |
| 28 | 28 | */ |
| 29 | -class BR_EXPORT UntrainableMetaTransform : public UntrainableTransform | |
| 29 | +class BR_EXPORT MetaTransform : public Transform | |
| 30 | 30 | { |
| 31 | 31 | Q_OBJECT |
| 32 | 32 | |
| 33 | 33 | protected: |
| 34 | - UntrainableMetaTransform() : UntrainableTransform(false) {} | |
| 35 | -}; | |
| 36 | - | |
| 37 | -/*! | |
| 38 | - * \brief A br::Transform for which the results of project may change due to prior calls to project | |
| 39 | - */ | |
| 40 | -class BR_EXPORT TimeVaryingTransform : public Transform | |
| 41 | -{ | |
| 42 | - Q_OBJECT | |
| 43 | - | |
| 44 | -public: | |
| 45 | - virtual bool timeVarying() const { return true; } | |
| 46 | - | |
| 47 | - virtual void project(const Template &src, Template &dst) const | |
| 48 | - { | |
| 49 | - qFatal("No const project defined for time-varying transform"); | |
| 50 | - (void) dst; (void) src; | |
| 51 | - } | |
| 52 | - | |
| 53 | - virtual void project(const TemplateList &src, TemplateList &dst) const | |
| 54 | - { | |
| 55 | - qFatal("No const project defined for time-varying transform"); | |
| 56 | - (void) dst; (void) src; | |
| 57 | - } | |
| 58 | - | |
| 59 | - // Get a compile failure if this isn't here to go along with the other | |
| 60 | - // projectUpdate, no idea why | |
| 61 | - virtual void projectUpdate(const Template & src, Template & dst) | |
| 62 | - { | |
| 63 | - (void) src; (void) dst; | |
| 64 | - qFatal("do something useful"); | |
| 65 | - } | |
| 66 | - | |
| 67 | - virtual void projectUpdate(const TemplateList &src, TemplateList &dst) | |
| 68 | - { | |
| 69 | - foreach (const Template & src_part, src) { | |
| 70 | - Template out; | |
| 71 | - projectUpdate(src_part, out); | |
| 72 | - dst.append(out); | |
| 73 | - } | |
| 74 | - } | |
| 75 | - | |
| 76 | - /*! | |
| 77 | - *\brief For transforms that don't do any training, this default implementation | |
| 78 | - * which creates a new copy of the Transform from its description string is sufficient. | |
| 79 | - */ | |
| 80 | - virtual Transform * smartCopy() | |
| 81 | - { | |
| 82 | - return this->clone(); | |
| 83 | - } | |
| 84 | - | |
| 85 | - | |
| 86 | -protected: | |
| 87 | - TimeVaryingTransform(bool independent = true, bool trainable = true) : Transform(independent, trainable) {} | |
| 34 | + MetaTransform() : Transform(false) {} | |
| 88 | 35 | }; |
| 89 | 36 | |
| 90 | 37 | /*! |
| 91 | - * \brief A br::Transform expecting multiple matrices per template. | |
| 38 | + * \brief A br::MetaTransform that does not require training data. | |
| 92 | 39 | */ |
| 93 | -class BR_EXPORT MetaTransform : public Transform | |
| 40 | +class BR_EXPORT UntrainableMetaTransform : public UntrainableTransform | |
| 94 | 41 | { |
| 95 | 42 | Q_OBJECT |
| 96 | 43 | |
| 97 | 44 | protected: |
| 98 | - MetaTransform() : Transform(false) {} | |
| 45 | + UntrainableMetaTransform() : UntrainableTransform(false) {} | |
| 99 | 46 | }; |
| 100 | 47 | |
| 101 | - | |
| 102 | 48 | class TransformCopier : public ResourceMaker<Transform> |
| 103 | 49 | { |
| 104 | 50 | public: |
| ... | ... | @@ -157,6 +103,71 @@ private: |
| 157 | 103 | Transform * baseTransform; |
| 158 | 104 | }; |
| 159 | 105 | |
| 106 | +/*! | |
| 107 | + * \brief A br::Transform for which the results of project may change due to prior calls to project | |
| 108 | + */ | |
| 109 | +class BR_EXPORT TimeVaryingTransform : public Transform | |
| 110 | +{ | |
| 111 | + Q_OBJECT | |
| 112 | + | |
| 113 | +public: | |
| 114 | + | |
| 115 | + virtual bool timeVarying() const { return true; } | |
| 116 | + | |
| 117 | + virtual void project(const Template &src, Template &dst) const | |
| 118 | + { | |
| 119 | + timeInvariantAlias->project(src,dst); | |
| 120 | + } | |
| 121 | + | |
| 122 | + virtual void project(const TemplateList &src, TemplateList &dst) const | |
| 123 | + { | |
| 124 | + timeInvariantAlias->project(src,dst); | |
| 125 | + } | |
| 126 | + | |
| 127 | + // Get a compile failure if this isn't here to go along with the other | |
| 128 | + // projectUpdate, no idea why | |
| 129 | + virtual void projectUpdate(const Template & src, Template & dst) | |
| 130 | + { | |
| 131 | + (void) src; (void) dst; | |
| 132 | + qFatal("do something useful"); | |
| 133 | + } | |
| 134 | + | |
| 135 | + virtual void projectUpdate(const TemplateList &src, TemplateList &dst) | |
| 136 | + { | |
| 137 | + foreach (const Template & src_part, src) { | |
| 138 | + Template out; | |
| 139 | + projectUpdate(src_part, out); | |
| 140 | + dst.append(out); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + /*! | |
| 145 | + *\brief For transforms that don't do any training, this default implementation | |
| 146 | + * which creates a new copy of the Transform from its description string is sufficient. | |
| 147 | + */ | |
| 148 | + virtual Transform * smartCopy() | |
| 149 | + { | |
| 150 | + return this->clone(); | |
| 151 | + } | |
| 152 | + | |
| 153 | + void init() | |
| 154 | + { | |
| 155 | + delete timeInvariantAlias; | |
| 156 | + timeInvariantAlias = new TimeInvariantWrapperTransform(this); | |
| 157 | + } | |
| 158 | + | |
| 159 | +protected: | |
| 160 | + Transform * timeInvariantAlias; | |
| 161 | + TimeVaryingTransform(bool independent = true, bool trainable = true) : Transform(independent, trainable) | |
| 162 | + { | |
| 163 | + timeInvariantAlias = NULL; | |
| 164 | + } | |
| 165 | + ~TimeVaryingTransform() | |
| 166 | + { | |
| 167 | + delete timeInvariantAlias; | |
| 168 | + } | |
| 169 | +}; | |
| 170 | + | |
| 160 | 171 | |
| 161 | 172 | /*! |
| 162 | 173 | * \brief A MetaTransform that aggregates some sub-transforms |
| ... | ... | @@ -171,15 +182,17 @@ public: |
| 171 | 182 | |
| 172 | 183 | virtual void project(const Template &src, Template &dst) const |
| 173 | 184 | { |
| 174 | - if (timeVarying()) qFatal("No const project defined for time-varying transform"); | |
| 185 | + if (timeVarying()) { | |
| 186 | + timeInvariantAlias->project(src,dst); | |
| 187 | + return; | |
| 188 | + } | |
| 175 | 189 | _project(src, dst); |
| 176 | 190 | } |
| 177 | 191 | |
| 178 | 192 | virtual void project(const TemplateList &src, TemplateList &dst) const |
| 179 | 193 | { |
| 180 | 194 | if (timeVarying()) { |
| 181 | - CompositeTransform * non_const = const_cast<CompositeTransform *>(this); | |
| 182 | - non_const->projectUpdate(src,dst); | |
| 195 | + timeInvariantAlias->project(src,dst); | |
| 183 | 196 | return; |
| 184 | 197 | } |
| 185 | 198 | _project(src, dst); |
| ... | ... | @@ -196,6 +209,10 @@ public: |
| 196 | 209 | isTimeVarying = isTimeVarying || transform->timeVarying(); |
| 197 | 210 | trainable = trainable || transform->trainable; |
| 198 | 211 | } |
| 212 | + | |
| 213 | + // If we are time varying, set up timeInvariantAlias | |
| 214 | + if (this->timeVarying()) | |
| 215 | + TimeVaryingTransform::init(); | |
| 199 | 216 | } |
| 200 | 217 | |
| 201 | 218 | /*! | ... | ... |
openbr/plugins/regions.cpp
| ... | ... | @@ -141,13 +141,15 @@ class CatColsTransform : public UntrainableMetaTransform |
| 141 | 141 | |
| 142 | 142 | void project(const Template &src, Template &dst) const |
| 143 | 143 | { |
| 144 | + int half = src.size()/2; | |
| 145 | + for (int i=0; i<half; i++) { | |
| 146 | + Mat first = src[i]; | |
| 147 | + Mat second = src[half+i]; | |
| 148 | + Mat both; | |
| 149 | + hconcat(first, second, both); | |
| 150 | + dst.append(both); | |
| 151 | + } | |
| 144 | 152 | dst.file = src.file; |
| 145 | - Mat m = OpenCVUtils::toMatByRow(src); | |
| 146 | - // right now this just splits src in half and joins them horizontally | |
| 147 | - // TODO: add partitions parameter for more than a single split | |
| 148 | - Mat first = m.rowRange(Range(0, m.rows/2)); | |
| 149 | - Mat second = m.rowRange(Range(m.rows/2, m.rows)); | |
| 150 | - hconcat(first, second, dst); | |
| 151 | 153 | } |
| 152 | 154 | }; |
| 153 | 155 | ... | ... |
openbr/plugins/stream.cpp
| ... | ... | @@ -707,8 +707,7 @@ public: |
| 707 | 707 | if (input == NULL) { |
| 708 | 708 | qFatal("null input to multi-thread stage"); |
| 709 | 709 | } |
| 710 | - // Project the input we got | |
| 711 | - transform->projectUpdate(input->data); | |
| 710 | + input->data >> *transform; | |
| 712 | 711 | |
| 713 | 712 | should_continue = nextStage->tryAcquireNextStage(input); |
| 714 | 713 | |
| ... | ... | @@ -1368,6 +1367,12 @@ public: |
| 1368 | 1367 | { |
| 1369 | 1368 | if (!transform) |
| 1370 | 1369 | return; |
| 1370 | + | |
| 1371 | + // Set up timeInvariantAlias | |
| 1372 | + // this is only safe because copies are actually made in project | |
| 1373 | + // calls, not during init. | |
| 1374 | + TimeVaryingTransform::init(); | |
| 1375 | + | |
| 1371 | 1376 | trainable = transform->trainable; |
| 1372 | 1377 | |
| 1373 | 1378 | basis.setParent(this->parent()); | ... | ... |