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,7 +254,6 @@ class ContractTransform : public UntrainableMetaTransform | ||
| 254 | 254 | ||
| 255 | virtual void project(const TemplateList &src, TemplateList &dst) const | 255 | virtual void project(const TemplateList &src, TemplateList &dst) const |
| 256 | { | 256 | { |
| 257 | - //dst = Expanded(src); | ||
| 258 | if (src.empty()) return; | 257 | if (src.empty()) return; |
| 259 | Template out; | 258 | Template out; |
| 260 | 259 | ||
| @@ -692,8 +691,10 @@ public: | @@ -692,8 +691,10 @@ public: | ||
| 692 | 691 | ||
| 693 | void init() | 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,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 | Q_OBJECT | 31 | Q_OBJECT |
| 32 | 32 | ||
| 33 | protected: | 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 | Q_OBJECT | 42 | Q_OBJECT |
| 96 | 43 | ||
| 97 | protected: | 44 | protected: |
| 98 | - MetaTransform() : Transform(false) {} | 45 | + UntrainableMetaTransform() : UntrainableTransform(false) {} |
| 99 | }; | 46 | }; |
| 100 | 47 | ||
| 101 | - | ||
| 102 | class TransformCopier : public ResourceMaker<Transform> | 48 | class TransformCopier : public ResourceMaker<Transform> |
| 103 | { | 49 | { |
| 104 | public: | 50 | public: |
| @@ -157,6 +103,71 @@ private: | @@ -157,6 +103,71 @@ private: | ||
| 157 | Transform * baseTransform; | 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 | * \brief A MetaTransform that aggregates some sub-transforms | 173 | * \brief A MetaTransform that aggregates some sub-transforms |
| @@ -171,15 +182,17 @@ public: | @@ -171,15 +182,17 @@ public: | ||
| 171 | 182 | ||
| 172 | virtual void project(const Template &src, Template &dst) const | 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 | _project(src, dst); | 189 | _project(src, dst); |
| 176 | } | 190 | } |
| 177 | 191 | ||
| 178 | virtual void project(const TemplateList &src, TemplateList &dst) const | 192 | virtual void project(const TemplateList &src, TemplateList &dst) const |
| 179 | { | 193 | { |
| 180 | if (timeVarying()) { | 194 | if (timeVarying()) { |
| 181 | - CompositeTransform * non_const = const_cast<CompositeTransform *>(this); | ||
| 182 | - non_const->projectUpdate(src,dst); | 195 | + timeInvariantAlias->project(src,dst); |
| 183 | return; | 196 | return; |
| 184 | } | 197 | } |
| 185 | _project(src, dst); | 198 | _project(src, dst); |
| @@ -196,6 +209,10 @@ public: | @@ -196,6 +209,10 @@ public: | ||
| 196 | isTimeVarying = isTimeVarying || transform->timeVarying(); | 209 | isTimeVarying = isTimeVarying || transform->timeVarying(); |
| 197 | trainable = trainable || transform->trainable; | 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,13 +141,15 @@ class CatColsTransform : public UntrainableMetaTransform | ||
| 141 | 141 | ||
| 142 | void project(const Template &src, Template &dst) const | 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 | dst.file = src.file; | 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,8 +707,7 @@ public: | ||
| 707 | if (input == NULL) { | 707 | if (input == NULL) { |
| 708 | qFatal("null input to multi-thread stage"); | 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 | should_continue = nextStage->tryAcquireNextStage(input); | 712 | should_continue = nextStage->tryAcquireNextStage(input); |
| 714 | 713 | ||
| @@ -1368,6 +1367,12 @@ public: | @@ -1368,6 +1367,12 @@ public: | ||
| 1368 | { | 1367 | { |
| 1369 | if (!transform) | 1368 | if (!transform) |
| 1370 | return; | 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 | trainable = transform->trainable; | 1376 | trainable = transform->trainable; |
| 1372 | 1377 | ||
| 1373 | basis.setParent(this->parent()); | 1378 | basis.setParent(this->parent()); |