Commit 352b8980605c31e15d6a52e961ac073b265c5944
Merge pull request #298 from biometrics/flip_rotate
Flip rotate
Showing
5 changed files
with
157 additions
and
1 deletions
openbr/plugins/algorithms.cpp
| ... | ... | @@ -79,6 +79,10 @@ class AlgorithmsInitializer : public Initializer |
| 79 | 79 | Globals->abbreviations.insert("RegisterAffine", "Open+Affine(256,256,0.37,0.45)"); |
| 80 | 80 | Globals->abbreviations.insert("ContrastEnhanced", "Open+Affine(256,256,0.37,0.45)+Cvt(Gray)+Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)"); |
| 81 | 81 | Globals->abbreviations.insert("ColoredLBP", "Open+Affine(128,128,0.37,0.45)+Cvt(Gray)+Blur(1.1)+Gamma(0.2)+DoG(1,2)+ContrastEq(0.1,10)+LBP(1,2)+ColoredU2"); |
| 82 | + Globals->abbreviations.insert("FlipMUCT","Flip+ReorderPoints([ 0, 1, 2, 3, 4, 5, 6, 7, 17,18,19,20,21,31,32,36,37,38,39,40,41,48,49,50,55,56,60,61,65], \ | |
| 83 | + [16,15,14,13,12,11,10, 9, 26,25,24,23,22,35,34,45,44,43,42,47,46,54,53,52,59,58,64,63,67],true)"); | |
| 84 | + Globals->abbreviations.insert("FlipMUCTNoJaw","Flip+ReorderPoints([0,1,2,3,4,14,15,19,20,21,22,23,24,31,32,33,38,39,43,44,48], \ | |
| 85 | + [9,8,7,6,5,18,17,28,27,26,25,30,29,37,36,35,42,41,47,46,50],true)"); | |
| 82 | 86 | |
| 83 | 87 | // Transforms |
| 84 | 88 | Globals->abbreviations.insert("FaceDetection", "Open+Cvt(Gray)+Cascade(FrontalFace)"); | ... | ... |
openbr/plugins/meta.cpp
| ... | ... | @@ -783,6 +783,43 @@ public: |
| 783 | 783 | }; |
| 784 | 784 | BR_REGISTER(Transform, DistributeTemplateTransform) |
| 785 | 785 | |
| 786 | +/*! | |
| 787 | + * \ingroup transforms | |
| 788 | + * \brief Generates two templates, one of which is passed through a transform and the other | |
| 789 | + * is not. No cats were harmed in the making of this transform. | |
| 790 | + * \author Scott Klum \cite sklum | |
| 791 | + */ | |
| 792 | +class SchrodingerTransform : public MetaTransform | |
| 793 | +{ | |
| 794 | + Q_OBJECT | |
| 795 | + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform) | |
| 796 | + BR_PROPERTY(br::Transform*, transform, NULL) | |
| 797 | + | |
| 798 | +public: | |
| 799 | + void train(const TemplateList &data) | |
| 800 | + { | |
| 801 | + transform->train(data); | |
| 802 | + } | |
| 803 | + | |
| 804 | + void project(const TemplateList &src, TemplateList &dst) const | |
| 805 | + { | |
| 806 | + foreach(const Template &t, src) { | |
| 807 | + dst.append(t); | |
| 808 | + Template u; | |
| 809 | + transform->project(t,u); | |
| 810 | + dst.append(u); | |
| 811 | + } | |
| 812 | + } | |
| 813 | + | |
| 814 | + void project(const Template &src, Template &dst) const { | |
| 815 | + TemplateList temp; | |
| 816 | + project(TemplateList() << src, temp); | |
| 817 | + if (!temp.isEmpty()) dst = temp.first(); | |
| 818 | + } | |
| 819 | + | |
| 820 | +}; | |
| 821 | +BR_REGISTER(Transform, SchrodingerTransform) | |
| 822 | + | |
| 786 | 823 | } // namespace br |
| 787 | 824 | |
| 788 | 825 | #include "meta.moc" | ... | ... |
openbr/plugins/regions.cpp
| ... | ... | @@ -242,12 +242,24 @@ class DupTransform : public UntrainableMetaTransform |
| 242 | 242 | { |
| 243 | 243 | Q_OBJECT |
| 244 | 244 | Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false) |
| 245 | + Q_PROPERTY(bool dupLandmarks READ get_dupLandmarks WRITE set_dupLandmarks RESET reset_dupLandmarks STORED false) | |
| 245 | 246 | BR_PROPERTY(int, n, 1) |
| 247 | + BR_PROPERTY(bool, dupLandmarks, false) | |
| 246 | 248 | |
| 247 | 249 | void project(const Template &src, Template &dst) const |
| 248 | 250 | { |
| 249 | 251 | for (int i=0; i<n; i++) |
| 250 | 252 | dst.merge(src); |
| 253 | + | |
| 254 | + if (dupLandmarks) { | |
| 255 | + QList<QPointF> points = src.file.points(); | |
| 256 | + QList<QRectF> rects = src.file.rects(); | |
| 257 | + | |
| 258 | + for (int i=1; i<n; i++) { | |
| 259 | + dst.file.appendPoints(points); | |
| 260 | + dst.file.appendRects(rects); | |
| 261 | + } | |
| 262 | + } | |
| 251 | 263 | } |
| 252 | 264 | }; |
| 253 | 265 | ... | ... |
openbr/plugins/register.cpp
| ... | ... | @@ -143,11 +143,79 @@ private: |
| 143 | 143 | void project(const Template &src, Template &dst) const |
| 144 | 144 | { |
| 145 | 145 | flip(src, dst, axis); |
| 146 | + | |
| 147 | + QList<QPointF> flippedPoints; | |
| 148 | + foreach(const QPointF &point, src.file.points()) { | |
| 149 | + if (axis == Y) { | |
| 150 | + flippedPoints.append(QPointF(src.m().cols-point.x(),point.y())); | |
| 151 | + } else if (axis == X) { | |
| 152 | + flippedPoints.append(QPointF(point.x(),src.m().rows-point.y())); | |
| 153 | + } else { | |
| 154 | + flippedPoints.append(QPointF(src.m().cols-point.x(),src.m().rows-point.y())); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + | |
| 158 | + QList<QRectF> flippedRects; | |
| 159 | + foreach(const QRectF &rect, src.file.rects()) { | |
| 160 | + if (axis == Y) { | |
| 161 | + flippedRects.append(QRectF(src.m().cols-rect.right(), | |
| 162 | + rect.y(), | |
| 163 | + rect.width(), | |
| 164 | + rect.height())); | |
| 165 | + } else if (axis == X) { | |
| 166 | + flippedRects.append(QRectF(rect.x(), | |
| 167 | + src.m().rows-rect.bottom(), | |
| 168 | + rect.width(), | |
| 169 | + rect.height())); | |
| 170 | + } else { | |
| 171 | + flippedRects.append(QRectF(src.m().cols-rect.right(), | |
| 172 | + src.m().rows-rect.bottom(), | |
| 173 | + rect.width(), | |
| 174 | + rect.height())); | |
| 175 | + } | |
| 176 | + } | |
| 177 | + | |
| 178 | + dst.file.setPoints(flippedPoints); | |
| 179 | + dst.file.setRects(flippedRects); | |
| 146 | 180 | } |
| 147 | 181 | }; |
| 148 | - | |
| 149 | 182 | BR_REGISTER(Transform, FlipTransform) |
| 150 | 183 | |
| 184 | +/*! | |
| 185 | + * \ingroup transforms | |
| 186 | + * \brief Randomly rotates an image in a specified range. | |
| 187 | + * \author Scott Klum \cite sklum | |
| 188 | + */ | |
| 189 | +class RandRotateTransform : public UntrainableTransform | |
| 190 | +{ | |
| 191 | + Q_OBJECT | |
| 192 | + | |
| 193 | + Q_PROPERTY(QList<int> range READ get_range WRITE set_range RESET reset_range STORED false) | |
| 194 | + BR_PROPERTY(QList<int>, range, QList<int>() << -15 << 15) | |
| 195 | + | |
| 196 | + void project(const Template &src, Template &dst) const { | |
| 197 | + int span = range.first() - range.last(); | |
| 198 | + int angle = (rand() % span) + range.first(); | |
| 199 | + Mat rotMatrix = getRotationMatrix2D(Point2f(src.m().rows/2,src.m().cols/2),angle,1.0); | |
| 200 | + warpAffine(src,dst,rotMatrix,Size(src.m().cols,src.m().rows)); | |
| 201 | + | |
| 202 | + QList<QPointF> points = src.file.points(); | |
| 203 | + QList<QPointF> rotatedPoints; | |
| 204 | + for (int i=0; i<points.size(); i++) { | |
| 205 | + rotatedPoints.append(QPointF(points.at(i).x()*rotMatrix.at<double>(0,0)+ | |
| 206 | + points.at(i).y()*rotMatrix.at<double>(0,1)+ | |
| 207 | + rotMatrix.at<double>(0,2), | |
| 208 | + points.at(i).x()*rotMatrix.at<double>(1,0)+ | |
| 209 | + points.at(i).y()*rotMatrix.at<double>(1,1)+ | |
| 210 | + rotMatrix.at<double>(1,2))); | |
| 211 | + } | |
| 212 | + | |
| 213 | + dst.file.setPoints(rotatedPoints); | |
| 214 | + } | |
| 215 | +}; | |
| 216 | + | |
| 217 | +BR_REGISTER(Transform, RandRotateTransform) | |
| 218 | + | |
| 151 | 219 | } // namespace br |
| 152 | 220 | |
| 153 | 221 | #include "register.moc" | ... | ... |
openbr/plugins/template.cpp
| ... | ... | @@ -207,6 +207,41 @@ public: |
| 207 | 207 | |
| 208 | 208 | BR_REGISTER(Transform, FilterDupeMetadataTransform) |
| 209 | 209 | |
| 210 | +/*! | |
| 211 | + * \ingroup transforms | |
| 212 | + * \brief Reorder the points such that points[from[i]] becomes points[to[i]] and | |
| 213 | + * vice versa | |
| 214 | + * \author Scott Klum \cite sklum | |
| 215 | + */ | |
| 216 | +class ReorderPointsTransform : public UntrainableMetadataTransform | |
| 217 | +{ | |
| 218 | + Q_OBJECT | |
| 219 | + | |
| 220 | + Q_PROPERTY(QList<int> from READ get_from WRITE set_from RESET reset_from STORED false) | |
| 221 | + Q_PROPERTY(QList<int> to READ get_to WRITE set_to RESET reset_to STORED false) | |
| 222 | + Q_PROPERTY(bool flippedOnly READ get_flippedOnly WRITE set_flippedOnly RESET reset_flippedOnly STORED false) | |
| 223 | + BR_PROPERTY(QList<int>, from, QList<int>()) | |
| 224 | + BR_PROPERTY(QList<int>, to, QList<int>()) | |
| 225 | + BR_PROPERTY(bool, flippedOnly, false) | |
| 226 | + | |
| 227 | + void projectMetadata(const File &src, File &dst) const | |
| 228 | + { | |
| 229 | + if (flippedOnly && !src.contains("Flipped")) { | |
| 230 | + dst = src; | |
| 231 | + return; | |
| 232 | + } | |
| 233 | + | |
| 234 | + if (from.size() == to.size()) { | |
| 235 | + QList<QPointF> points = src.points(); | |
| 236 | + for (int i=0; i<from.size(); i++) | |
| 237 | + std::swap(points[from[i]],points[to[i]]); | |
| 238 | + dst.setPoints(points); | |
| 239 | + } else qFatal("Inconsistent sizes for to and from index lists."); | |
| 240 | + } | |
| 241 | +}; | |
| 242 | + | |
| 243 | +BR_REGISTER(Transform, ReorderPointsTransform) | |
| 244 | + | |
| 210 | 245 | } // namespace br |
| 211 | 246 | |
| 212 | 247 | #include "template.moc" | ... | ... |