2012-04-11 14 views
0

Ich würde gerne ein Dreieck innerhalb einer OpenCV Matte zu einem anderen mappen, so ziemlich wie WarpAffine (siehe here), aber für Dreiecke anstelle von Quads, um es in a zu verwenden Delaunay-Triangulation.OpenCV Warping von einem Dreieck zum anderen

Ich weiß, man kann eine Maske verwenden, aber ich würde gerne wissen, ob es eine bessere Lösung gibt.

Mit freundlichen Grüßen, Daniel

Antwort

0

Sie sollten die getAffineTransform verwenden die Transformation zu finden, und warpAffine verwenden, um es anzuwenden

+0

Hallo vasile, ich würde getAffineTransform() und dann WarpAffine() verwenden, aber WarpAffine wird das gesamte Bild transformieren. Ich möchte nur ein Dreieck transformieren. Es wäre in Ordnung, wenn ich den ROI als ein Dreieck festlegen könnte, aber ich denke nicht, dass diese Option existiert. – dannyxyz22

+0

Sie müssen ein neues Bild einrücken und dann mit einer Maske kopieren. Oder modifizieren Sie warpAffine, um Ihre Bedürfnisse zu erfüllen – Sam

+0

Oder versuchen Sie es besser mit BorderTransparent. Es kann funktionieren ... – Sam

4

enter image description here ich das obige Bild kopiert haben und den folgenden C++ Code aus meinem Beitrag Warp one triangle to another using OpenCV (C++/Python) . Die Kommentare im folgenden Code sollten eine gute Idee geben, was vor sich geht. Für weitere Details und für Python-Code können Sie den obigen Link besuchen. Alle Pixel im Dreieck tri1 in img1 werden in img2 in tri2 transformiert. Hoffe das hilft.

void warpTriangle(Mat &img1, Mat &img2, vector<Point2f> tri1, vector<Point2f> tri2) 
{ 
    // Find bounding rectangle for each triangle 
    Rect r1 = boundingRect(tri1); 
    Rect r2 = boundingRect(tri2); 

    // Offset points by left top corner of the respective rectangles 
    vector<Point2f> tri1Cropped, tri2Cropped; 
    vector<Point> tri2CroppedInt; 
    for(int i = 0; i < 3; i++) 
    { 
     tri1Cropped.push_back(Point2f(tri1[i].x - r1.x, tri1[i].y - r1.y)); 
     tri2Cropped.push_back(Point2f(tri2[i].x - r2.x, tri2[i].y - r2.y)); 

     // fillConvexPoly needs a vector of Point and not Point2f 
     tri2CroppedInt.push_back(Point((int)(tri2[i].x - r2.x), (int)(tri2[i].y - r2.y))); 

    } 

    // Apply warpImage to small rectangular patches 
    Mat img1Cropped; 
    img1(r1).copyTo(img1Cropped); 

    // Given a pair of triangles, find the affine transform. 
    Mat warpMat = getAffineTransform(tri1Cropped, tri2Cropped); 

    // Apply the Affine Transform just found to the src image 
    Mat img2Cropped = Mat::zeros(r2.height, r2.width, img1Cropped.type()); 
    warpAffine(img1Cropped, img2Cropped, warpMat, img2Cropped.size(), INTER_LINEAR, BORDER_REFLECT_101); 

    // Get mask by filling triangle 
    Mat mask = Mat::zeros(r2.height, r2.width, CV_32FC3); 
    fillConvexPoly(mask, tri2CroppedInt, Scalar(1.0, 1.0, 1.0), 16, 0); 

    // Copy triangular region of the rectangular patch to the output image 
    multiply(img2Cropped,mask, img2Cropped); 
    multiply(img2(r2), Scalar(1.0,1.0,1.0) - mask, img2(r2)); 
    img2(r2) = img2(r2) + img2Cropped; 

} 
+0

Schön. Ich mag deine Arbeit an LearnOpenCV.com, es rockt :) Danke. – dannyxyz22

+0

Danke für die freundlichen Worte! Ein +1 auf diese Antwort wäre sehr nett: P –