Commit 352b8980605c31e15d6a52e961ac073b265c5944

Authored by Scott Klum
2 parents fb193b02 8f903c52

Merge pull request #298 from biometrics/flip_rotate

Flip rotate
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"
... ...