OpenCV图像转换和透视变化

时间:2013-01-06 04:05:20

标签: c++ opencv matrix transformation perspective

我正在尝试实现以下效果,此处使用GIMP中的透视工具显示。

原始图片(620x466像素)

original image (620x466 pixels)

转换图片

transforming the image

我所拥有的是固定网络摄像头,并希望插入上述变换矩阵图形,从而产生梯形无畸变输出。

我知道在OpenCV中还有其他选项可用于未失真图像,但我真的想手动提供变换矩阵图形,最后得到梯形图像。

从阅读中我感觉warpPerspectivefindHomographygetPerspectiveTransform可能有用,但不确定如何在C ++中进行此操作

非常感谢任何有用的建议。


尝试使用以下代码运行但我只得到一个显示1个像素的窗口。

也许我指定像素点的方式,这是正确的吗?

    #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;
}

3 个答案:

答案 0 :(得分:15)

如果你有三个角点,请使用Warp仿射变换。如果您有四个角点,请使用Warp Perspective变换。以下是使用Warp Perspective变换的方法。选择图像的四个角点。然后选择所需矩形的四个对应点。 Warp变换将完成其余的工作。

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;  
}

答案 1 :(得分:0)

以下作品: 请更正输入图像上的坐标,我确实得到了线索。

            #include <opencv2/core/core.hpp>
            #include <opencv2/opencv.hpp>
            //#include "cv.hpp"
            #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
                )
            {
                // todo do some checks on input.

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

                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 = _image.clone();
                _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("img.png", CV_LOAD_IMAGE_COLOR);   // Read the file   // original image(620x466 pixels)
                imshow("InputImage", image);
                waitKey(0);


                Point2f one = (0.0, 0.0);
                Point2f two = (500.0, 0.0);
                Point2f three = (500.0, 100.0);
                Point2f four = (250.0, 100.0);

                Point2f five = (250.0, 0.0);
                Point2f six = (500.0, 0.0);
                Point2f seven = (500.0, 1000.0);
                Point2f eight = (250.0, 100.0);



                edited= OpenWarpPerspective(image, one, two, three, four, five, six, seven, eight);

                namedWindow("Display window", CV_WINDOW_AUTOSIZE);// Create a window for display.
                imshow("Display window", edited);                   // Show our image inside it.

                waitKey(0);                                          // Wait for a keystroke in the window
                return 0;
            }

答案 2 :(得分:-1)

添加dst的初始化: Mat dst = _image.clone();