Commit 9bf09e4ddc83dd4c6b023b28d0374f2e38dfa042
1 parent
59acf294
In the middle of debugging, saving progress...
Showing
1 changed file
with
52 additions
and
30 deletions
openbr/plugins/landmarks.cpp
| ... | ... | @@ -268,19 +268,11 @@ class ProcrustesAlignTransform : public Transform |
| 268 | 268 | |
| 269 | 269 | void project(const Template &src, Template &dst) const |
| 270 | 270 | { |
| 271 | - float srcMinX = FLT_MAX; | |
| 272 | - float srcMinY = FLT_MAX; | |
| 273 | - float srcMaxX = -FLT_MAX; | |
| 274 | - float srcMaxY = -FLT_MAX; | |
| 275 | 271 | QList<QPointF> imagePoints = src.file.points(); |
| 276 | 272 | MatrixXf p(imagePoints.size() * 2, 1); |
| 277 | 273 | for (int i = 0; i < imagePoints.size(); i++) { |
| 278 | 274 | p(i * 2) = imagePoints[i].x(); |
| 279 | 275 | p(i * 2 + 1) = imagePoints[i].y(); |
| 280 | - if (imagePoints[i].x() < srcMinX) srcMinX = imagePoints[i].x(); | |
| 281 | - if (imagePoints[i].y() < srcMinY) srcMinY = imagePoints[i].y(); | |
| 282 | - if (imagePoints[i].x() < srcMaxX) srcMaxX = imagePoints[i].x(); | |
| 283 | - if (imagePoints[i].y() < srcMaxY) srcMaxY = imagePoints[i].y(); | |
| 284 | 276 | } |
| 285 | 277 | p = vectorToMatrix(p); |
| 286 | 278 | |
| ... | ... | @@ -305,9 +297,6 @@ class ProcrustesAlignTransform : public Transform |
| 305 | 297 | dst = src; |
| 306 | 298 | dst.file.setList<QPointF>("ProcrustesPoints", procrustesPoints); |
| 307 | 299 | dst.file.set("ProcrustesBound", QRectF(0, 0, width + 2 * padding, (qRound(width / aspectRatio) + 2 * padding))); |
| 308 | - dst.file.set("ProcrustesSrcBound", QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), | |
| 309 | - qRound(srcMaxX - srcMinX + 2 * padding), | |
| 310 | - qRound(srcMaxY - srcMinY + 2 * padding))); | |
| 311 | 300 | } |
| 312 | 301 | |
| 313 | 302 | void store(QDataStream &stream) const |
| ... | ... | @@ -347,7 +336,7 @@ class DelaunayTransform : public UntrainableTransform |
| 347 | 336 | BR_PROPERTY(float, scaleFactor, 1) |
| 348 | 337 | BR_PROPERTY(bool, warp, true) |
| 349 | 338 | |
| 350 | - void project(const Template &src, Template &dst, ) const | |
| 339 | + void project(const Template &src, Template &dst) const | |
| 351 | 340 | { |
| 352 | 341 | QList<QPointF> points = src.file.points(); |
| 353 | 342 | QList<QRectF> rects = src.file.rects(); |
| ... | ... | @@ -490,13 +479,32 @@ class TextureMapTransform : public UntrainableTransform |
| 490 | 479 | BR_PROPERTY(float, scaleFactor, 1) |
| 491 | 480 | BR_PROPERTY(bool, warp, true) |
| 492 | 481 | |
| 493 | - QList<QPointF> getTriangulation(QList<QPointF> points, QRect bound) { | |
| 482 | + static QRectF getBounds(QList<QPointF> points, int padding) { | |
| 483 | + float srcMinX = FLT_MAX; | |
| 484 | + float srcMinY = FLT_MAX; | |
| 485 | + float srcMaxX = -FLT_MAX; | |
| 486 | + float srcMaxY = -FLT_MAX; | |
| 487 | + for (int i = 0; i < points.size(); i++) { | |
| 488 | + if (points[i].x() < srcMinX) srcMinX = points[i].x(); | |
| 489 | + if (points[i].y() < srcMinY) srcMinY = points[i].y(); | |
| 490 | + if (points[i].x() > srcMaxX) srcMaxX = points[i].x(); | |
| 491 | + if (points[i].y() > srcMaxY) srcMaxY = points[i].y(); | |
| 492 | + } | |
| 493 | + return QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), qRound(srcMaxX - srcMinX + 2 * padding), qRound(srcMaxY - srcMinY + 2 * padding)); | |
| 494 | + } | |
| 495 | + QList<QPointF> getTriangulation(const QList<QPointF> _points, const QRectF bound) const { | |
| 496 | + QList<QPointF> points(_points); | |
| 497 | + /* | |
| 494 | 498 | points.append(bound.topLeft()); |
| 495 | - points.append(bound.topRight()); | |
| 496 | - points.append(bound.bottomLeft()); | |
| 497 | - points.append(bound.bottomRight()); | |
| 498 | - | |
| 499 | - Subdiv2D subdiv(); | |
| 499 | + points.append(QPointF(bound.right() - 1, bound.top())); | |
| 500 | + points.append(QPointF(bound.left(), bound.bottom() - 1)); | |
| 501 | + points.append(QPointF(bound.right() - 1, bound.bottom() - 1)); | |
| 502 | + points.append(QPointF(bound.left() + bound.width() / 2, bound.top())); | |
| 503 | + points.append(QPointF(bound.left() + bound.width() / 2, bound.bottom() - 1)); | |
| 504 | + points.append(QPointF(bound.left(), bound.top() + bound.height() / 2)); | |
| 505 | + points.append(QPointF(bound.right() - 1, bound.top() + bound.height() / 2)); | |
| 506 | + */ | |
| 507 | + Subdiv2D subdiv(OpenCVUtils::toRect(bound)); | |
| 500 | 508 | for (int i = 0; i < points.size(); i++) |
| 501 | 509 | subdiv.insert(OpenCVUtils::toPoint(points[i])); |
| 502 | 510 | |
| ... | ... | @@ -504,6 +512,8 @@ class TextureMapTransform : public UntrainableTransform |
| 504 | 512 | subdiv.getTriangleList(triangleList); |
| 505 | 513 | |
| 506 | 514 | QList<QPointF> validTriangles; |
| 515 | +static int SCNT = 0; | |
| 516 | +MatrixXf P(triangleList.size() * 3,2); | |
| 507 | 517 | for (size_t i = 0; i < triangleList.size(); i++) { |
| 508 | 518 | bool valid = true; |
| 509 | 519 | QList<QPointF> vertices; |
| ... | ... | @@ -511,23 +521,31 @@ class TextureMapTransform : public UntrainableTransform |
| 511 | 521 | vertices.append(QPointF(triangleList[i][2],triangleList[i][3])); |
| 512 | 522 | vertices.append(QPointF(triangleList[i][4],triangleList[i][5])); |
| 513 | 523 | for (int j = 0; j < 3; j++) |
| 514 | - if (vertices[j].x() > cols || vertices[j].y() > rows || vertices[j].x() < 0 || vertices[j].y() < 0) | |
| 524 | + if (vertices[j].x() > bound.right() || vertices[j].y() > bound.bottom() || vertices[j].x() < bound.left() || vertices[j].y() < bound.top()) | |
| 515 | 525 | valid = false; |
| 516 | - | |
| 526 | +for (int j = 0; j < 3;j++) { | |
| 527 | +P(i*3+j,0) = vertices[j].x(); | |
| 528 | +P(i*3+j,1) = vertices[j].y(); | |
| 529 | +} | |
| 517 | 530 | if (valid) |
| 518 | 531 | validTriangles.append(vertices); |
| 519 | 532 | } |
| 533 | +//writeEigen(P, QString("Temp/p%1.bin").arg(SCNT++)); | |
| 520 | 534 | |
| 535 | +MatrixXf P(validTriangles.size(),2); | |
| 536 | +for (int j = 0; j < validTriangles.size() ;j++) { | |
| 537 | +P(i*3+j,0) = vertices[j].x(); | |
| 538 | +P(i*3+j,1) = vertices[j].y(); | |
| 539 | +} | |
| 521 | 540 | return validTriangles; |
| 522 | 541 | } |
| 523 | 542 | |
| 524 | 543 | void project(const Template &src, Template &dst) const |
| 525 | 544 | { |
| 526 | - QList<QPointF> dstPoints = dst.file.setList<QPointF>("ProcrustesPoints", procrustesPoints); | |
| 527 | - QRectF dstBound = dst.file.setList<QPointF>("ProcrustesBound", procrustesPoints); | |
| 545 | + QList<QPointF> dstPoints = dst.file.getList<QPointF>("ProcrustesPoints"); | |
| 528 | 546 | QList<QPointF> srcPoints = dst.file.points(); |
| 529 | - QRectF srcBound = dst.file.setList<QPointF>("ProcrustesSrcBound", procrustesPoints); | |
| 530 | - | |
| 547 | + QRectF dstBound = getBounds(dstPoints, 8); | |
| 548 | + QRectF srcBound = getBounds(srcPoints, 8); | |
| 531 | 549 | if (dstPoints.empty() || srcPoints.empty()) { |
| 532 | 550 | dst = src; |
| 533 | 551 | if (Globals->verbose) qWarning("Delauney triangulation failed because points or rects are empty."); |
| ... | ... | @@ -538,18 +556,19 @@ class TextureMapTransform : public UntrainableTransform |
| 538 | 556 | QList<QPointF> srcTri = getTriangulation(srcPoints, srcBound); |
| 539 | 557 | |
| 540 | 558 | dst.m() = Mat::zeros(dstBound.height(), dstBound.width(), src.m().type()); |
| 541 | - for (int i = 0; i < srcTriangles.size(); i+=3) { | |
| 559 | + for (int i = 0; i < srcTri.size(); i+=3) { | |
| 542 | 560 | Point2f srcPoints[3]; |
| 543 | 561 | Point2f dstPoints[3]; |
| 544 | 562 | for (int j = 0; j < 3; j++) { |
| 545 | 563 | srcPoints[j] = OpenCVUtils::toPoint(srcTri[i+j]); |
| 546 | - srcPoints[j] = OpenCVUtils::toPoint(dstTri[i+j]); | |
| 564 | + dstPoints[j] = OpenCVUtils::toPoint(dstTri[i+j]); | |
| 547 | 565 | } |
| 548 | 566 | |
| 549 | 567 | Mat buffer(dstBound.height(), dstBound.width(), src.m().type()); |
| 550 | - warpAffine(src.m(), buffer, getAffineTransform(srcPoints, dstPoints), Size(cols,rows)); | |
| 568 | + warpAffine(src.m(), buffer, getAffineTransform(srcPoints, dstPoints), Size(dstBound.width(), dstBound.height())); | |
| 551 | 569 | |
| 552 | - Mat mask = Mat::zeros(rows, cols, CV_8UC1); | |
| 570 | + //Mat mask = Mat::zeros(dstBound.height(), dstBound.width(), CV_8UC1); | |
| 571 | + Mat mask = Mat::zeros(dstBound.height(), dstBound.width(), src.m().type()); | |
| 553 | 572 | Point maskPoints[1][3]; |
| 554 | 573 | maskPoints[0][0] = dstPoints[0]; |
| 555 | 574 | maskPoints[0][1] = dstPoints[1]; |
| ... | ... | @@ -559,19 +578,22 @@ class TextureMapTransform : public UntrainableTransform |
| 559 | 578 | |
| 560 | 579 | Mat output(dstBound.height(), dstBound.width(), src.m().type()); |
| 561 | 580 | |
| 581 | + /* | |
| 562 | 582 | if (i > 0) { |
| 563 | 583 | Mat overlap; |
| 564 | - bitwise_and(dst.m(),mask,overlap); | |
| 584 | + bitwise_and(dst.m(), mask, overlap); | |
| 565 | 585 | mask.setTo(0, overlap!=0); |
| 566 | 586 | } |
| 587 | + */ | |
| 567 | 588 | |
| 568 | 589 | bitwise_and(buffer,mask,output); |
| 569 | - | |
| 570 | 590 | dst.m() += output; |
| 571 | 591 | } |
| 572 | 592 | } |
| 573 | 593 | }; |
| 574 | 594 | |
| 595 | +BR_REGISTER(Transform, TextureMapTransform) | |
| 596 | + | |
| 575 | 597 | /*! |
| 576 | 598 | * \ingroup transforms |
| 577 | 599 | * \brief Creates a Delaunay triangulation based on a set of points | ... | ... |