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,7 +327,7 @@ BR_REGISTER(Transform, ProcrustesAlignTransform) | ||
| 327 | * \brief Creates a Delaunay triangulation based on a set of points | 327 | * \brief Creates a Delaunay triangulation based on a set of points |
| 328 | * \author Scott Klum \cite sklum | 328 | * \author Scott Klum \cite sklum |
| 329 | */ | 329 | */ |
| 330 | -class DelaunayTransform : public UntrainableTransform | 330 | +class DelaunayTransform : public Transform |
| 331 | { | 331 | { |
| 332 | Q_OBJECT | 332 | Q_OBJECT |
| 333 | 333 | ||
| @@ -467,18 +467,13 @@ BR_REGISTER(Transform, DelaunayTransform) | @@ -467,18 +467,13 @@ BR_REGISTER(Transform, DelaunayTransform) | ||
| 467 | /*! | 467 | /*! |
| 468 | * \ingroup transforms | 468 | * \ingroup transforms |
| 469 | * \brief Maps texture from one set of points to another. Assumes that points are rigidly transformed | 469 | * \brief Maps texture from one set of points to another. Assumes that points are rigidly transformed |
| 470 | - * \author Scott Klum \cite sklum | ||
| 471 | * \author Brendan Klare \cite bklare | 470 | * \author Brendan Klare \cite bklare |
| 471 | + * \author Scott Klum \cite sklum | ||
| 472 | */ | 472 | */ |
| 473 | class TextureMapTransform : public UntrainableTransform | 473 | class TextureMapTransform : public UntrainableTransform |
| 474 | { | 474 | { |
| 475 | Q_OBJECT | 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 | static QRectF getBounds(QList<QPointF> points, int padding) { | 477 | static QRectF getBounds(QList<QPointF> points, int padding) { |
| 483 | float srcMinX = FLT_MAX; | 478 | float srcMinX = FLT_MAX; |
| 484 | float srcMinY = FLT_MAX; | 479 | float srcMinY = FLT_MAX; |
| @@ -492,8 +487,17 @@ class TextureMapTransform : public UntrainableTransform | @@ -492,8 +487,17 @@ class TextureMapTransform : public UntrainableTransform | ||
| 492 | } | 487 | } |
| 493 | return QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), qRound(srcMaxX - srcMinX + 2 * padding), qRound(srcMaxY - srcMinY + 2 * padding)); | 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 | QList<QPointF> points(_points); | 499 | QList<QPointF> points(_points); |
| 500 | + | ||
| 497 | /* | 501 | /* |
| 498 | points.append(bound.topLeft()); | 502 | points.append(bound.topLeft()); |
| 499 | points.append(QPointF(bound.right() - 1, bound.top())); | 503 | points.append(QPointF(bound.right() - 1, bound.top())); |
| @@ -511,9 +515,7 @@ class TextureMapTransform : public UntrainableTransform | @@ -511,9 +515,7 @@ class TextureMapTransform : public UntrainableTransform | ||
| 511 | vector<Vec6f> triangleList; | 515 | vector<Vec6f> triangleList; |
| 512 | subdiv.getTriangleList(triangleList); | 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 | for (size_t i = 0; i < triangleList.size(); i++) { | 519 | for (size_t i = 0; i < triangleList.size(); i++) { |
| 518 | bool valid = true; | 520 | bool valid = true; |
| 519 | QList<QPointF> vertices; | 521 | QList<QPointF> vertices; |
| @@ -523,21 +525,16 @@ MatrixXf P(triangleList.size() * 3,2); | @@ -523,21 +525,16 @@ MatrixXf P(triangleList.size() * 3,2); | ||
| 523 | for (int j = 0; j < 3; j++) | 525 | for (int j = 0; j < 3; j++) |
| 524 | if (vertices[j].x() > bound.right() || vertices[j].y() > bound.bottom() || vertices[j].x() < bound.left() || vertices[j].y() < bound.top()) | 526 | if (vertices[j].x() > bound.right() || vertices[j].y() > bound.bottom() || vertices[j].x() < bound.left() || vertices[j].y() < bound.top()) |
| 525 | valid = false; | 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 | void project(const Template &src, Template &dst) const | 540 | void project(const Template &src, Template &dst) const |
| @@ -552,43 +549,72 @@ P(i*3+j,1) = vertices[j].y(); | @@ -552,43 +549,72 @@ P(i*3+j,1) = vertices[j].y(); | ||
| 552 | return; | 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 | for (int j = 0; j < 3; j++) { | 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 | Point maskPoints[1][3]; | 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 | const Point* ppt = { maskPoints[0] }; | 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 | if (i > 0) { | 602 | if (i > 0) { |
| 583 | Mat overlap; | 603 | Mat overlap; |
| 584 | bitwise_and(dst.m(), mask, overlap); | 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 |