我正在尝试实现以下效果,此处使用GIMP中的透视工具显示。
原始图片(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;
}
答案 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();