OpenCV image transformation and perspective change

22,477

If you have three corner points use Warp Affine transform. If you have four corner points use Warp Perspective transform. Here is how you should use Warp Perspective transform. Select four corner points of image. Then select four corresponding points of the desired rectangle. Warp transform will do the rest.

cv::Mat OpenWarpPerspective(const cv::Mat& _image
  , const cv::Point2f& _lu
  , const cv::Point2f& _ru
  , const cv::Point2f& _rd
  , const cv::Point2f& _ld
  , const cv::Point2f& _lu_result
  , const cv::Point2f& _ru_result
  , const cv::Point2f& _rd_result
  , const cv::Point2f& _ld_result
  , cv::Mat& _transform_matrix)
{
  // todo do some checks on input.

  cv::Point2f source_points[4];
  cv::Point2f dest_points[4];


  source_points[0] = _lu;
  source_points[1] = _ru;
  source_points[2] = _rd;
  source_points[3] = _ld;

  dest_points[0] = _lu_result;
  dest_points[1] = _ru_result;
  dest_points[2] = _rd_result;
  dest_points[3] = _ld_result;

  cv::Mat dst;
  _transform_matrix = cv::getPerspectiveTransform(source_points, dest_points);
  cv::warpPerspective(_image, dst, _transform_matrix, cv::Size(_width, _height));

  return dst;  
}
Share:
22,477
winterDream
Author by

winterDream

Updated on July 09, 2022

Comments

  • winterDream
    winterDream almost 2 years

    I'm trying to achieve the following effect, shown here using the perspective tool in GIMP.

    original image (620x466 pixels)

    original image (620x466 pixels)

    transforming the image

    transforming the image

    What I have is a fixed webcam and would like to plugin the above transformation matrix figures, resulting in a trapezium shaped undistorted output.

    I am aware that there are other options available to undistort images in OpenCV, but I would really like to provide transformation matrix figures manually, whilst ending up with a trapezium shaped image.

    From reading around I have a feeling warpPerspective, findHomography or getPerspectiveTransform may be useful, but not sure how to go about this in C++

    Any helpful advice would be greatly appreciated.


    Tried running with the following code but I only get a window with 1 pixel showing.

    Maybe the way I have specified points in pixels, is this correct?

        #include <opencv2/core/core.hpp>
        #include <opencv2/opencv.hpp>
        #include <cv.h>
        #include <opencv2/highgui/highgui.hpp>
        #include <iostream>
    
        using namespace cv;
        using namespace std;
    
                cv::Mat OpenWarpPerspective(const cv::Mat& _image
                  , const cv::Point2f& _lu
                  , const cv::Point2f& _ru
                  , const cv::Point2f& _rd
                  , const cv::Point2f& _ld
                  , const cv::Point2f& _lu_result
                  , const cv::Point2f& _ru_result
                  , const cv::Point2f& _rd_result
                  , const cv::Point2f& _ld_result
                  , cv::Mat& _transform_matrix)
                {
                  // todo do some checks on input.
    
                  cv::Point2f source_points[4];
                  cv::Point2f dest_points[4];
    
    
                  source_points[0] = _lu;
                  source_points[1] = _ru;
                  source_points[2] = _rd;
                  source_points[3] = _ld;
    
                  dest_points[0] = _lu_result;
                  dest_points[1] = _ru_result;
                  dest_points[2] = _rd_result;
                  dest_points[3] = _ld_result;
    
                  cv::Mat dst;
                  _transform_matrix = cv::getPerspectiveTransform(source_points, dest_points);
                  cv::warpPerspective(_image, dst, _transform_matrix, dst.size());
    
                  return dst;  
                }
    
        int main( int argc, char** argv )
        {
    
            Mat image;
            Mat edited;
    
            image = imread("c:/org.png", CV_LOAD_IMAGE_COLOR);   // Read the file
    
            namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
    
                Point2f one = (0.0, 0.0);
                Point2f two = (317.0, 0.0);
                Point2f three = (317.0, 240.0);
                Point2f four = (0.0, 240.0);
    
                Point2f five = (-100.0, 0.0);
                Point2f six = (617.0, 0.0);
                Point2f seven = (317.0, 240.0);
                Point2f eight = (0.0, 240.0);
    
                OpenWarpPerspective(image,one,two,three,four,five,six,seven,eight,edited);  
    
            imshow( "Display window", edited );                   // Show our image inside it.
    
            waitKey(0);                                          // Wait for a keystroke in the window
            return 0;
    }
    
  • winterDream
    winterDream over 11 years
    Thank you very much for replying, will check this out later to see what I get