opencvimage-processingwarp

Image Warping using opencv


I want to perform image warping using opencv. I have detected 4 corners of the image ((ex) 4000x4000) and got the transform matrix using getPerspectiveTransform in opencv. Now, I want to warp the image at the image center. So I used warpPerspective. Size of Source image that I input is 450x450 and I use the transform matrix that I calculated for whole image.

But nothing is displayed on the screen. Any help is appreciated.

Here is sample code and sample image.

This is source image. This is source image.

This image is detected This image is detected

This is the warping area that I want from the image.(src_crop in code)

enter image description here

This is result.

enter image description here

        source[0] = Point2f(lt.x, lt.y);
        source[1] = Point2f(rt.x, rt.y);
        source[2] = Point2f(rb.x, rb.y);
        source[3] = Point2f(lb.x, lb.y);

        dst[0] = Point2f(6, 10);
        dst[1] = Point2f(3899, 7);
        dst[2] = Point2f(3901, 3899);
        dst[3] = Point2f(9, 3902);

        Mat transformMatrix ;
        transformMatrix = getPerspectiveTransform(source, dst);



        Mat dstFrame ;
        warpPerspective(src_crop, dstFrame, transformMatrix, Size(450, 450));

Solution

  • Your transformation fails since you use the wrong values for your getPerspectiveTransform method. You seem to mix up how you create the output image and how you populate the destination corners from the data of this image.

    Also, it is important that you link the right corners in the arrays (left top, right top, left bottom, right bottom), you seem to mix this up.

    This example will show you how to connect the right points and output it in an empty output image:

    // Assuming your source image is called 'sourceImage' and you have the corner points you need:
    
    // Create vectors to store the corners
    vector<Point2f> originalCorners;
    vector<Point2f> destinationCorners;
    
    // Put the Sudoku corners in your originalCorners
    originalCorners.clear();
    originalCorners.push_back(Point2f(lt.x, lt.y);
    originalCorners.push_back(Point2f(rt.x, rt.y);
    originalCorners.push_back(Point2f(lb.x, lb.y);
    originalCorners.push_back(Point2f(rb.x, rb.y);
    
    // Output image size of 450x450
    int ouputImageWidth = 450;
    int outputImageHeight = 450;
    
    // Create an empty image (450x450) to output your transformation result in
    Mat transformedOutputImage(ouputImageWidth, outputImageHeight, sourceImage.type());
    
    // Now put the corners of the output image so the warp knows where to warp to
    destinationCorners.clear();
    destinationCorners.push_back(Point2f(0, 0));
    destinationCorners.push_back(Point2f(ouputImageWidth, 0));
    destinationCorners.push_back(Point2f(0, outputImageHeight));
    destinationCorners.push_back(Point2f(ouputImageWidth, outputImageHeight));
    
    // Now we have all corners sorted, so we can create the warp matrix
    Mat warpMatrix = getPerspectiveTransform(originalCorners, destinationCorners);
    
    // And now we can warp the Sudoku in the new image
    warpPerspective(sourceImage, transformedOutputImage, warpMatrix, Size(ouputImageWidth, ouputImageHeight));
    

    Now, this assumes you know the corner points of the part of the image you want to warp. If you don't know how to get the points of the middle square, I recommend you to take a look at these excellent answers.

    However, as long as you have the four corner points this method will work. You can even try it by manually looking up the middle square corner points and inserting those.