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,6 +79,10 @@ class AlgorithmsInitializer : public Initializer | ||
| 79 | Globals->abbreviations.insert("RegisterAffine", "Open+Affine(256,256,0.37,0.45)"); | 79 | Globals->abbreviations.insert("RegisterAffine", "Open+Affine(256,256,0.37,0.45)"); |
| 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)"); | 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 | 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"); | 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 | // Transforms | 87 | // Transforms |
| 84 | Globals->abbreviations.insert("FaceDetection", "Open+Cvt(Gray)+Cascade(FrontalFace)"); | 88 | Globals->abbreviations.insert("FaceDetection", "Open+Cvt(Gray)+Cascade(FrontalFace)"); |
openbr/plugins/meta.cpp
| @@ -783,6 +783,43 @@ public: | @@ -783,6 +783,43 @@ public: | ||
| 783 | }; | 783 | }; |
| 784 | BR_REGISTER(Transform, DistributeTemplateTransform) | 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 | } // namespace br | 823 | } // namespace br |
| 787 | 824 | ||
| 788 | #include "meta.moc" | 825 | #include "meta.moc" |
openbr/plugins/regions.cpp
| @@ -242,12 +242,24 @@ class DupTransform : public UntrainableMetaTransform | @@ -242,12 +242,24 @@ class DupTransform : public UntrainableMetaTransform | ||
| 242 | { | 242 | { |
| 243 | Q_OBJECT | 243 | Q_OBJECT |
| 244 | Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false) | 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 | BR_PROPERTY(int, n, 1) | 246 | BR_PROPERTY(int, n, 1) |
| 247 | + BR_PROPERTY(bool, dupLandmarks, false) | ||
| 246 | 248 | ||
| 247 | void project(const Template &src, Template &dst) const | 249 | void project(const Template &src, Template &dst) const |
| 248 | { | 250 | { |
| 249 | for (int i=0; i<n; i++) | 251 | for (int i=0; i<n; i++) |
| 250 | dst.merge(src); | 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,11 +143,79 @@ private: | ||
| 143 | void project(const Template &src, Template &dst) const | 143 | void project(const Template &src, Template &dst) const |
| 144 | { | 144 | { |
| 145 | flip(src, dst, axis); | 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 | BR_REGISTER(Transform, FlipTransform) | 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 | } // namespace br | 219 | } // namespace br |
| 152 | 220 | ||
| 153 | #include "register.moc" | 221 | #include "register.moc" |
openbr/plugins/template.cpp
| @@ -207,6 +207,41 @@ public: | @@ -207,6 +207,41 @@ public: | ||
| 207 | 207 | ||
| 208 | BR_REGISTER(Transform, FilterDupeMetadataTransform) | 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 | } // namespace br | 245 | } // namespace br |
| 211 | 246 | ||
| 212 | #include "template.moc" | 247 | #include "template.moc" |