Преобразование изображений OpenCV и изменение перспективы

Я пытаюсь достичь следующего эффекта, показанного здесь, используя инструмент перспективы в GIMP.

исходное изображение (620x466 пикселей)

original image (620x466 pixels)

преобразование изображения

transforming the image

у меня есть фиксированная веб-камера и я хотел бы подключить вышеуказанные матричные фигуры преобразования, что приводит к трапециевидной форме неискаженного вывода.

Я знаю, что есть и другие опции, доступные для undistort изображений в OpenCV, но я бы очень хотел предоставить фигуры матрицы преобразования вручную, в то время как в конечном итоге трапециевидное изображение.

от чтения вокруг у меня есть чувство warpPerspective, findHomography или 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;
}

3 ответов


Если у вас есть три угловые точки, используйте Warp Affine transform. Если у вас есть четыре угловые точки, используйте преобразование перспективы деформации. Вот как вы должны использовать преобразование перспективы 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;  
}

Следующие Работы: Пожалуйста, исправьте координаты на входном изображении, я не понял.

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

добавить инициализацию dst: Мат ДСТ = в верхней части страницы.clone();