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

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

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

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

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

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

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

Мне известно, что в 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;
}

9

Решение

Если у вас есть три угловые точки, используйте Warp Affine transform. Если у вас есть четыре угловые точки, используйте трансформацию Warp Perspective. Вот как вы должны использовать Warp Perspective transform. Выберите четыре угловые точки изображения. Затем выберите четыре соответствующие точки желаемого прямоугольника. Деформация деформации сделает все остальное.

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

Другие решения

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

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

добавьте инициализацию dst:
Mat dst = _image.clone ();

-1
По вопросам рекламы [email protected]