Commit 260843b51f0686b00f13653ce85320c6f39dc985
1 parent
71e41b4a
Improved functionality for texture mapping
Showing
2 changed files
with
47 additions
and
29 deletions
openbr/plugins/landmarks.cpp
| ... | ... | @@ -232,29 +232,15 @@ class ProcrustesAlignTransform : public Transform |
| 232 | 232 | |
| 233 | 233 | //Normalize rotation |
| 234 | 234 | if (!useFirst) { |
| 235 | - MatrixXf refPrev; | |
| 236 | - referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); | |
| 237 | - float diff = FLT_MAX; | |
| 238 | - float diffDelta = FLT_MAX; | |
| 239 | - while (diff > 1e-5 && diffDelta > 1e-5) {//iterate until reference shape is stable | |
| 240 | - refPrev = referenceShape; | |
| 241 | - | |
| 242 | - for (int j = 0; j < points.cols(); j++) { | |
| 243 | - MatrixXf p = vectorToMatrix(points.col(j)); | |
| 244 | - MatrixXf R = getRotation(referenceShape, p); | |
| 245 | - p = p * R; | |
| 246 | - points.col(j) = matrixToVector(p); | |
| 247 | - } | |
| 248 | - referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); | |
| 249 | - float temp = diff; | |
| 250 | - diff = (matrixToVector(referenceShape) - matrixToVector(refPrev)).norm(); | |
| 251 | - diffDelta = abs(diff - temp); | |
| 252 | - } | |
| 253 | - | |
| 254 | 235 | referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); |
| 255 | 236 | } else { |
| 256 | 237 | referenceShape = vectorToMatrix(points.col(0)); |
| 257 | - referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); | |
| 238 | + } | |
| 239 | + | |
| 240 | + for (int i = 0; i < points.cols(); i++) { | |
| 241 | + MatrixXf p = vectorToMatrix(points.col(i)); | |
| 242 | + MatrixXf R = getRotation(referenceShape, p); | |
| 243 | + points.col(i) = matrixToVector(p * R); | |
| 258 | 244 | } |
| 259 | 245 | |
| 260 | 246 | //Choose crop boundaries and adjustments that captures most data |
| ... | ... | @@ -287,10 +273,10 @@ class ProcrustesAlignTransform : public Transform |
| 287 | 273 | maxYs(j) = maxY; |
| 288 | 274 | } |
| 289 | 275 | |
| 290 | - minX = eigMean(minXs) - 1 * eigStd(minXs); | |
| 291 | - minY = eigMean(minYs) - 1 * eigStd(minYs); | |
| 292 | - maxX = eigMean(maxXs) + 1 * eigStd(maxXs); | |
| 293 | - maxY = eigMean(maxYs) + 1 * eigStd(maxYs); | |
| 276 | + minX = eigMean(minXs) - 0 * eigStd(minXs); | |
| 277 | + minY = eigMean(minYs) - 0 * eigStd(minYs); | |
| 278 | + maxX = eigMean(maxXs) + 0 * eigStd(maxXs); | |
| 279 | + maxY = eigMean(maxYs) + 0 * eigStd(maxYs); | |
| 294 | 280 | aspectRatio = (maxX - minX) / (maxY - minY); |
| 295 | 281 | } |
| 296 | 282 | |
| ... | ... | @@ -325,6 +311,7 @@ class ProcrustesAlignTransform : public Transform |
| 325 | 311 | dst = src; |
| 326 | 312 | dst.file.setList<QPointF>("ProcrustesPoints", procrustesPoints); |
| 327 | 313 | dst.file.set("ProcrustesBound", QRectF(0, 0, width + 2 * padding, (qRound(width / aspectRatio) + 2 * padding))); |
| 314 | + dst.file.set("ProcrustesPadding", padding); | |
| 328 | 315 | } |
| 329 | 316 | |
| 330 | 317 | void store(QDataStream &stream) const |
| ... | ... | @@ -502,7 +489,7 @@ class TextureMapTransform : public UntrainableTransform |
| 502 | 489 | { |
| 503 | 490 | Q_OBJECT |
| 504 | 491 | |
| 505 | - static QRectF getBounds(QList<QPointF> points) { | |
| 492 | + static QRectF getBounds(QList<QPointF> points, int dstPadding) { | |
| 506 | 493 | float srcMinX = FLT_MAX; |
| 507 | 494 | float srcMinY = FLT_MAX; |
| 508 | 495 | float srcMaxX = -FLT_MAX; |
| ... | ... | @@ -514,8 +501,7 @@ class TextureMapTransform : public UntrainableTransform |
| 514 | 501 | if (points[i].y() > srcMaxY) srcMaxY = points[i].y(); |
| 515 | 502 | } |
| 516 | 503 | |
| 517 | - float padding = (srcMaxX - srcMinX) / 80 * 16; | |
| 518 | - //padding = 8; | |
| 504 | + float padding = (srcMaxX - srcMinX) / 80 * dstPadding; | |
| 519 | 505 | return QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), qRound(srcMaxX - srcMinX + 2 * padding), qRound(srcMaxY - srcMinY + 2 * padding)); |
| 520 | 506 | } |
| 521 | 507 | |
| ... | ... | @@ -574,8 +560,8 @@ class TextureMapTransform : public UntrainableTransform |
| 574 | 560 | { |
| 575 | 561 | QList<QPointF> dstPoints = dst.file.getList<QPointF>("ProcrustesPoints"); |
| 576 | 562 | QList<QPointF> srcPoints = dst.file.points(); |
| 577 | - QRectF dstBound = dst.file.get<QRectF>("ProcrustesBound");// getBounds(dstPoints, 8); | |
| 578 | - QRectF srcBound = getBounds(srcPoints); | |
| 563 | + QRectF dstBound = dst.file.get<QRectF>("ProcrustesBound"); | |
| 564 | + QRectF srcBound = getBounds(srcPoints, dst.file.get<int>("ProcrustesPadding")); | |
| 579 | 565 | if (dstPoints.empty() || srcPoints.empty()) { |
| 580 | 566 | dst = src; |
| 581 | 567 | if (Globals->verbose) qWarning("Delauney triangulation failed because points or rects are empty."); |
| ... | ... | @@ -635,6 +621,36 @@ class TextureMapTransform : public UntrainableTransform |
| 635 | 621 | BR_REGISTER(Transform, TextureMapTransform) |
| 636 | 622 | |
| 637 | 623 | /*! |
| 624 | + * \ingroup initializers | |
| 625 | + * \brief Initialize Procrustes croppings | |
| 626 | + * \author Brendan Klare \cite bklare | |
| 627 | + */ | |
| 628 | +class ProcrustesInitializer : public Initializer | |
| 629 | +{ | |
| 630 | + Q_OBJECT | |
| 631 | + | |
| 632 | + void initialize() const | |
| 633 | + { | |
| 634 | + Globals->abbreviations.insert("ProcrustesStasmFace","ProcrustesAlign(padding=16)+TextureMap+Resize(48,48)"); | |
| 635 | + Globals->abbreviations.insert("ProcrustesStasmEyes","SelectPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47])+ProcrustesAlign(padding=8)+TextureMap+Resize(24,48)"); | |
| 636 | + Globals->abbreviations.insert("ProcrustesStasmPeriocular","SelectPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,16,17,18,19,20,21,22,23,24,25,26,27])+ProcrustesAlign(padding=8)+TextureMap+Resize(36,48)"); | |
| 637 | + Globals->abbreviations.insert("ProcrustesStasmBrow","SelectPoints([16,17,18,19,20,21,22,23,24,25,26,27])+ProcrustesAlign(padding=8)+TextureMap+Resize(24,48)"); | |
| 638 | + Globals->abbreviations.insert("ProcrustesStasmNose","SelectPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58])+ProcrustesAlign(padding=8)+TextureMap+Resize(36,48)"); | |
| 639 | + Globals->abbreviations.insert("ProcrustesStasmMouth","SelectPoints([59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76])+ProcrustesAlign(padding=10)+TextureMap+Resize(36,48)"); | |
| 640 | + Globals->abbreviations.insert("ProcrustesStasmJaw", "SelectPoints([2,3,4,5,6,7,8,9,10])+ProcrustesAlign(padding=8)+TextureMap+Resize(36,48)"); | |
| 641 | + | |
| 642 | + Globals->abbreviations.insert("ProcrustesLargeStasmFace","ProcrustesAlign(padding=16)+TextureMap+Resize(480,480)"); | |
| 643 | + Globals->abbreviations.insert("ProcrustesLargeStasmEyes","SelectPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47])+ProcrustesAlign(padding=8)+TextureMap+Resize(240,480)"); | |
| 644 | + Globals->abbreviations.insert("ProcrustesLargeStasmPeriocular","SelectPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,16,17,18,19,20,21,22,23,24,25,26,27])+ProcrustesAlign(padding=8)+TextureMap+Resize(360,480)"); | |
| 645 | + Globals->abbreviations.insert("ProcrustesLargeStasmBrow","SelectPoints([16,17,18,19,20,21,22,23,24,25,26,27])+ProcrustesAlign(padding=8)+TextureMap+Resize(240,480)"); | |
| 646 | + Globals->abbreviations.insert("ProcrustesLargeStasmNose","SelectPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58])+ProcrustesAlign(padding=8)+TextureMap+Resize(360,480)"); | |
| 647 | + Globals->abbreviations.insert("ProcrustesLargeStasmMouth","SelectPoints([59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76])+ProcrustesAlign(padding=20)+TextureMap+Resize(360,480)"); | |
| 648 | + Globals->abbreviations.insert("ProcrustesLargeStasmJaw", "SelectPoints([2,3,4,5,6,7,8,9,10])+ProcrustesAlign(padding=8)+TextureMap+Resize(360,480)"); | |
| 649 | + } | |
| 650 | +}; | |
| 651 | +BR_REGISTER(Initializer, ProcrustesInitializer) | |
| 652 | + | |
| 653 | +/*! | |
| 638 | 654 | * \ingroup transforms |
| 639 | 655 | * \brief Creates a Delaunay triangulation based on a set of points |
| 640 | 656 | * \author Scott Klum \cite sklum | ... | ... |
openbr/plugins/stasm4.cpp
| ... | ... | @@ -37,6 +37,8 @@ class StasmInitializer : public Initializer |
| 37 | 37 | { |
| 38 | 38 | Globals->abbreviations.insert("RectFromStasmEyes","RectFromPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],0.3,5.3)"); |
| 39 | 39 | Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([16,17,18,19,20,21,22,23,24,25,26,27],0.15,5)"); |
| 40 | + Globals->abbreviations.insert("RectFromStasmPeriocular","RectFromPoints([28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,16,17,18,19,20,21,22,23,24,25,26,27]],0.3,5.3)"); | |
| 41 | + Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([16,17,18,19,20,21,22,23,24,25,26,27],0.15,5)"); | |
| 40 | 42 | Globals->abbreviations.insert("RectFromStasmNose","RectFromPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58],0.15,1.15)"); |
| 41 | 43 | Globals->abbreviations.insert("RectFromStasmNoseWithBridge", "RectFromPoints([21, 22, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58],0.15,.6)"); |
| 42 | 44 | Globals->abbreviations.insert("RectFromStasmMouth","RectFromPoints([59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76],0.3,2)"); | ... | ... |