Advertisement
jack06215

[OpenCV] warp triangle

Jul 9th, 2020
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.23 KB | None | 0 0
  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3.  
  4. using namespace cv;
  5. using namespace std;
  6.  
  7. // Warps and alpha blends triangular regions from img1 and img2 to img
  8. void warpTriangle(Mat &img1, Mat &img2, vector<Point2f> tri1, vector<Point2f> tri2)
  9. {
  10.     // Find bounding rectangle for each triangle
  11.     Rect r1 = boundingRect(tri1);
  12.     Rect r2 = boundingRect(tri2);
  13.  
  14.     // Offset points by left top corner of the respective rectangles
  15.     vector<Point2f> tri1Cropped, tri2Cropped;
  16.     vector<Point> tri2CroppedInt;
  17.     for (int i = 0; i < 3; i++)
  18.     {
  19.         tri1Cropped.push_back(Point2f(tri1[i].x - r1.x, tri1[i].y - r1.y));
  20.         tri2Cropped.push_back(Point2f(tri2[i].x - r2.x, tri2[i].y - r2.y));
  21.  
  22.         // fillConvexPoly needs a vector of Point and not Point2f
  23.         tri2CroppedInt.push_back(Point((int)(tri2[i].x - r2.x), (int)(tri2[i].y - r2.y)));
  24.  
  25.     }
  26.  
  27.     // Apply warpImage to small rectangular patches
  28.     Mat img1Cropped;
  29.     img1(r1).copyTo(img1Cropped);
  30.  
  31.     // Given a pair of triangles, find the affine transform.
  32.     Mat warpMat = getAffineTransform(tri1Cropped, tri2Cropped);
  33.  
  34.  
  35.     // Apply the Affine Transform just found to the src image
  36.     Mat img2Cropped = Mat::zeros(r2.height, r2.width, img1Cropped.type());
  37.     //warpMat = cv::Mat::eye(warpMat.rows, warpMat.cols, warpMat.type());
  38.     warpAffine(img1Cropped, img2Cropped, warpMat, img2Cropped.size(), cv::INTER_LINEAR, cv::BORDER_REFLECT_101);
  39.  
  40.     // Get mask by filling triangle
  41.     Mat mask = Mat::zeros(r2.height, r2.width, CV_32FC3);
  42.     fillConvexPoly(mask, tri2CroppedInt, Scalar(1.0, 1.0, 1.0), 16, 0);
  43.  
  44.     // Copy triangular region of the rectangular patch to the output image
  45.     multiply(img2Cropped, mask, img2Cropped);
  46.     multiply(img2(r2), Scalar(1.0, 1.0, 1.0) - mask, img2(r2));
  47.     img2(r2) = img2(r2) + img2Cropped;
  48.  
  49. }
  50.  
  51. int main(int argc, char** argv)
  52. {
  53.     // Read input image and convert to float
  54.     Mat imgIn = imread("robot.jpg");
  55.     imgIn.convertTo(imgIn, CV_32FC3, 1 / 255.0);
  56.  
  57.     // Output image is set to white
  58.     Mat imgOut = Mat::ones(imgIn.size(), imgIn.type());
  59.     imgOut = Scalar(1.0, 1.0, 1.0);
  60.  
  61.     // Input triangle
  62.     vector <Point2f> triIn;
  63.     triIn.push_back(Point2f(360, 200));
  64.     triIn.push_back(Point2d(60, 250));
  65.     triIn.push_back(Point2f(450, 400));
  66.  
  67.     // Output triangle
  68.     vector <Point2f> triOut;
  69.     triOut.push_back(Point2f(400, 200));
  70.     triOut.push_back(Point2f(160, 270));
  71.     triOut.push_back(Point2f(400, 400));
  72.  
  73.  
  74.     // Warp all pixels inside input triangle to output triangle
  75.     warpTriangle(imgIn, imgOut, triIn, triOut);
  76.  
  77.     // Draw triangle on the input and output image.
  78.  
  79.     // Convert back to uint because OpenCV antialiasing
  80.     // does not work on image of type CV_32FC3
  81.  
  82.     imgIn.convertTo(imgIn, CV_8UC3, 255.0);
  83.     imgOut.convertTo(imgOut, CV_8UC3, 255.0);
  84.  
  85.     // Draw triangle using this color
  86.     Scalar color = Scalar(255, 150, 0);
  87.  
  88.     // cv::polylines needs vector of type Point and not Point2f
  89.     vector <Point> triInInt, triOutInt;
  90.     for (int i = 0; i < 3; i++)
  91.     {
  92.         triInInt.push_back(Point(triIn[i].x, triIn[i].y));
  93.         triOutInt.push_back(Point(triOut[i].x, triOut[i].y));
  94.     }
  95.  
  96.     // Draw triangles in input and output images
  97.     polylines(imgIn, triInInt, true, color, 2, 16);
  98.     polylines(imgOut, triOutInt, true, color, 2, 16);
  99.  
  100.     imshow("Input", imgIn);
  101.     imshow("Output", imgOut);
  102.     waitKey(0);
  103.  
  104.     return 0;
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement