9

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

原始图像(620x466 像素)

原始图像(620x466 像素)

转换图像

转换图像

我拥有的是一个固定的网络摄像头,并想插入上述变换矩阵图,从而产生梯形不失真的输出。

我知道在 OpenCV 中还有其他选项可用于使图像不失真,但我真的很想手动提供变换矩阵图,同时最终得到一个梯形图像。

从阅读中我有一种感觉warpPerspectivefindHomography或者getPerspectiveTransform可能有用,但不确定如何在 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;
}
4

3 回答 3

15

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

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;  
}
于 2013-01-06T06:28:40.327 回答
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;
            }
于 2017-07-14T05:28:42.440 回答
-1

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

于 2016-09-08T09:18:14.453 回答