C++ OpenCV 图像变换和视角变化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14179164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV image transformation and perspective change
提问by winterDream
I'm trying to achieve the following effect, shown here using the perspective tool in GIMP.
我正在尝试实现以下效果,此处使用 GIMP 中的透视工具显示。
original image (620x466 pixels)
原始图像(620x466 像素)
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.
我知道还有其他选项可用于在 OpenCV 中消除图像失真,但我真的很想手动提供变换矩阵图形,同时以梯形图像结束。
From reading around I have a feeling warpPerspective
, findHomography
or getPerspectiveTransform
may be useful, but not sure how to go about this in C++
从阅读中我有一种感觉warpPerspective
,findHomography
或者getPerspectiveTransform
可能有用,但不知道如何在 C++ 中解决这个问题
Any helpful advice would be greatly appreciated.
任何有用的建议将不胜感激。
Tried running with the following code but I only get a window with 1 pixel showing.
尝试使用以下代码运行,但我只得到一个显示 1 个像素的窗口。
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;
}
回答by wiggily
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.
如果您有三个角点,请使用 Warp Affine 变换。如果您有四个角点,请使用 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;
}
回答by IRFAN Muhammad
Following Works: Please correct the coordinates on input image, I did'nt get clue.
以下作品:请更正输入图像上的坐标,我没有得到线索。
#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;
}
回答by Pavel Nurminsky
add the initialization of dst: Mat dst = _image.clone();
添加dst的初始化:Mat dst = _image.clone();