Commit fce803042852ef4ce1d155b4eeba85201198f1c3
1 parent
cabb12d4
Currently debugging (pushing for backup)
Showing
1 changed file
with
71 additions
and
45 deletions
openbr/plugins/landmarks.cpp
| ... | ... | @@ -327,7 +327,7 @@ BR_REGISTER(Transform, ProcrustesAlignTransform) |
| 327 | 327 | * \brief Creates a Delaunay triangulation based on a set of points |
| 328 | 328 | * \author Scott Klum \cite sklum |
| 329 | 329 | */ |
| 330 | -class DelaunayTransform : public UntrainableTransform | |
| 330 | +class DelaunayTransform : public Transform | |
| 331 | 331 | { |
| 332 | 332 | Q_OBJECT |
| 333 | 333 | |
| ... | ... | @@ -467,18 +467,13 @@ BR_REGISTER(Transform, DelaunayTransform) |
| 467 | 467 | /*! |
| 468 | 468 | * \ingroup transforms |
| 469 | 469 | * \brief Maps texture from one set of points to another. Assumes that points are rigidly transformed |
| 470 | - * \author Scott Klum \cite sklum | |
| 471 | 470 | * \author Brendan Klare \cite bklare |
| 471 | + * \author Scott Klum \cite sklum | |
| 472 | 472 | */ |
| 473 | 473 | class TextureMapTransform : public UntrainableTransform |
| 474 | 474 | { |
| 475 | 475 | Q_OBJECT |
| 476 | 476 | |
| 477 | - Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) | |
| 478 | - Q_PROPERTY(bool warp READ get_warp WRITE set_warp RESET reset_warp STORED false) | |
| 479 | - BR_PROPERTY(float, scaleFactor, 1) | |
| 480 | - BR_PROPERTY(bool, warp, true) | |
| 481 | - | |
| 482 | 477 | static QRectF getBounds(QList<QPointF> points, int padding) { |
| 483 | 478 | float srcMinX = FLT_MAX; |
| 484 | 479 | float srcMinY = FLT_MAX; |
| ... | ... | @@ -492,8 +487,17 @@ class TextureMapTransform : public UntrainableTransform |
| 492 | 487 | } |
| 493 | 488 | return QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), qRound(srcMaxX - srcMinX + 2 * padding), qRound(srcMaxY - srcMinY + 2 * padding)); |
| 494 | 489 | } |
| 495 | - QList<QPointF> getTriangulation(const QList<QPointF> _points, const QRectF bound) const { | |
| 490 | + | |
| 491 | + static int getVertexIndex(QPointF trianglePts, QList<QPointF> pts) { | |
| 492 | + for (int i = 0; i < pts.size(); i++) | |
| 493 | + if (trianglePts.x() == pts[i].x() && trianglePts.y() == pts[i].y()) | |
| 494 | + return i; | |
| 495 | + return -1; | |
| 496 | + } | |
| 497 | + | |
| 498 | + QList<QList<int> > getTriangulation(const QList<QPointF> _points, const QRectF bound) const { | |
| 496 | 499 | QList<QPointF> points(_points); |
| 500 | + | |
| 497 | 501 | /* |
| 498 | 502 | points.append(bound.topLeft()); |
| 499 | 503 | points.append(QPointF(bound.right() - 1, bound.top())); |
| ... | ... | @@ -511,9 +515,7 @@ class TextureMapTransform : public UntrainableTransform |
| 511 | 515 | vector<Vec6f> triangleList; |
| 512 | 516 | subdiv.getTriangleList(triangleList); |
| 513 | 517 | |
| 514 | - QList<QPointF> validTriangles; | |
| 515 | -static int SCNT = 0; | |
| 516 | -MatrixXf P(triangleList.size() * 3,2); | |
| 518 | + QList<QList<int> > triangleIndices; | |
| 517 | 519 | for (size_t i = 0; i < triangleList.size(); i++) { |
| 518 | 520 | bool valid = true; |
| 519 | 521 | QList<QPointF> vertices; |
| ... | ... | @@ -523,21 +525,16 @@ MatrixXf P(triangleList.size() * 3,2); |
| 523 | 525 | for (int j = 0; j < 3; j++) |
| 524 | 526 | if (vertices[j].x() > bound.right() || vertices[j].y() > bound.bottom() || vertices[j].x() < bound.left() || vertices[j].y() < bound.top()) |
| 525 | 527 | valid = false; |
| 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 | -} | |
| 530 | - if (valid) | |
| 531 | - validTriangles.append(vertices); | |
| 528 | + | |
| 529 | + if (valid) { | |
| 530 | + QList<int> tri; | |
| 531 | + for (int j = 0; j < 3; j++) | |
| 532 | + tri.append(getVertexIndex(vertices[j], points)); | |
| 533 | + triangleIndices.append(tri); | |
| 534 | + } | |
| 532 | 535 | } |
| 533 | -//writeEigen(P, QString("Temp/p%1.bin").arg(SCNT++)); | |
| 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 | -} | |
| 540 | - return validTriangles; | |
| 536 | + | |
| 537 | + return triangleIndices; | |
| 541 | 538 | } |
| 542 | 539 | |
| 543 | 540 | void project(const Template &src, Template &dst) const |
| ... | ... | @@ -552,43 +549,72 @@ P(i*3+j,1) = vertices[j].y(); |
| 552 | 549 | return; |
| 553 | 550 | } |
| 554 | 551 | |
| 555 | - QList<QPointF> dstTri = getTriangulation(dstPoints, dstBound); | |
| 556 | - QList<QPointF> srcTri = getTriangulation(srcPoints, srcBound); | |
| 552 | + QList<QList<int> > triIndices = getTriangulation(srcPoints, srcBound); | |
| 557 | 553 | |
| 558 | - dst.m() = Mat::zeros(dstBound.height(), dstBound.width(), src.m().type()); | |
| 559 | - for (int i = 0; i < srcTri.size(); i+=3) { | |
| 560 | - Point2f srcPoints[3]; | |
| 561 | - Point2f dstPoints[3]; | |
| 554 | + //QList<QPointF> dstTri = getTriangulation(dstPoints, dstBound); | |
| 555 | + //QList<QPointF> srcTri = getTriangulation(srcPoints, srcBound); | |
| 556 | + | |
| 557 | + int dstWidth = dstBound.width() + dstBound.x(); | |
| 558 | + int dstHeight = dstBound.height() + dstBound.y(); | |
| 559 | + dst.m() = Mat::zeros(dstHeight, dstWidth, src.m().type()); | |
| 560 | +static int SCNT = 0; | |
| 561 | + for (int i = 0; i < triIndices.size(); i++) { | |
| 562 | + Point2f srcPoint1[3]; | |
| 563 | + Point2f dstPoint1[3]; | |
| 562 | 564 | for (int j = 0; j < 3; j++) { |
| 563 | - srcPoints[j] = OpenCVUtils::toPoint(srcTri[i+j]); | |
| 564 | - dstPoints[j] = OpenCVUtils::toPoint(dstTri[i+j]); | |
| 565 | + srcPoint1[j] = OpenCVUtils::toPoint(srcPoints[triIndices[i][j]]); | |
| 566 | + dstPoint1[j] = OpenCVUtils::toPoint(dstPoints[triIndices[i][j]]); | |
| 565 | 567 | } |
| 566 | 568 | |
| 567 | - Mat buffer(dstBound.height(), dstBound.width(), src.m().type()); | |
| 568 | - warpAffine(src.m(), buffer, getAffineTransform(srcPoints, dstPoints), Size(dstBound.width(), dstBound.height())); | |
| 569 | + Mat buffer(dstHeight, dstWidth, src.m().type()); | |
| 570 | + warpAffine(src.m(), buffer, getAffineTransform(srcPoint1, dstPoint1), Size(dstBound.width(), dstBound.height())); | |
| 569 | 571 | |
| 570 | - //Mat mask = Mat::zeros(dstBound.height(), dstBound.width(), CV_8UC1); | |
| 571 | - Mat mask = Mat::zeros(dstBound.height(), dstBound.width(), src.m().type()); | |
| 572 | + Mat mask = Mat::zeros(dstHeight, dstWidth, CV_8UC1); | |
| 573 | + //Mat mask = Mat::zeros(dstHeight, dstWidth, src.m().type()); | |
| 572 | 574 | Point maskPoints[1][3]; |
| 573 | - maskPoints[0][0] = dstPoints[0]; | |
| 574 | - maskPoints[0][1] = dstPoints[1]; | |
| 575 | - maskPoints[0][2] = dstPoints[2]; | |
| 575 | + maskPoints[0][0] = dstPoint1[0]; | |
| 576 | + maskPoints[0][1] = dstPoint1[1]; | |
| 577 | + maskPoints[0][2] = dstPoint1[2]; | |
| 576 | 578 | const Point* ppt = { maskPoints[0] }; |
| 577 | - fillConvexPoly(mask, ppt, 3, Scalar(255,255,255), 8); | |
| 579 | + fillConvexPoly(mask, ppt, 3, Scalar(255, 255, 255), 8); | |
| 580 | + | |
| 581 | + //dst.m().setTo(buffer, mask); | |
| 582 | + //bitwise_and(buffer, mask, dst.m(), mask); | |
| 583 | + for (int i = 0; i < dstHeight; i++) { | |
| 584 | + for (int j = 0; j < dstWidth; j++) { | |
| 585 | + if (mask.at<uchar>(i,j) == 255) { | |
| 586 | + if (dst.m().type() == CV_32FC3 || dst.m().type() == CV_8UC3) | |
| 587 | + dst.m().at<cv::Vec3b>(i,j) = buffer.at<cv::Vec3b>(i,j); | |
| 588 | + else if (dst.m().type() == CV_32F) | |
| 589 | + dst.m().at<float>(i,j) = buffer.at<float>(i,j); | |
| 590 | + else if (dst.m().type() == CV_8U) | |
| 591 | + dst.m().at<uchar>(i,j) = buffer.at<uchar>(i,j); | |
| 592 | + else | |
| 593 | + qFatal("Unsupported pixel format."); | |
| 594 | + } | |
| 595 | + //dst.m().at<src.m().type()>i,j) = 255; | |
| 596 | + } | |
| 597 | + } | |
| 578 | 598 | |
| 579 | - Mat output(dstBound.height(), dstBound.width(), src.m().type()); | |
| 599 | + //Mat output(dstBound.height(), dstBound.width(), src.m().type()); | |
| 580 | 600 | |
| 581 | 601 | /* |
| 582 | 602 | if (i > 0) { |
| 583 | 603 | Mat overlap; |
| 584 | 604 | bitwise_and(dst.m(), mask, overlap); |
| 585 | - mask.setTo(0, overlap!=0); | |
| 605 | + mask.setTo(0, overlap != 0); | |
| 586 | 606 | } |
| 587 | 607 | */ |
| 588 | 608 | |
| 589 | - bitwise_and(buffer,mask,output); | |
| 590 | - dst.m() += output; | |
| 609 | + //bitwise_and(buffer,mask,output); | |
| 610 | + //dst.m() += output; | |
| 591 | 611 | } |
| 612 | + /* | |
| 613 | +qDebug() << dst.m().rows << dst.m().cols << dstBound; | |
| 614 | +Eigen::Map<const Eigen::VectorXf> M(dst.m().ptr<float>(), dst.m().rows*dst.m().cols); | |
| 615 | +writeEigen((MatrixXf)M, QString("Temp/img%1.bin").arg(SCNT++)); | |
| 616 | +OpenCVUtils::saveImage(dst.m(), QString("Temp/img%1.jpg").arg(SCNT)); | |
| 617 | +*/ | |
| 592 | 618 | } |
| 593 | 619 | }; |
| 594 | 620 | ... | ... |