计算透视变换矩阵
getPerspectiveTransform()(四点变换)
Mat cv::getPerspectiveTransform( const Point2f src[],
const Point2f dst[],
int solveMethod = DECOMP_LU
)
·src[]:原图像中的四个像素坐标
·dst[]:目标图像中的四个像素坐标
·solveMethod:计算透视变换矩阵方法的选择标志
通过这些参数标志就可以选择对应的方法,计算出我们的透视变换矩阵,之后根据透视变换矩阵M,再利用变换关系就可以得到透视变换图像。
透视变换函数
void cv::warpPerspective( InputArray src,
OutputArray dst,
inputArray M,
Size dize,
int flags = INTER_LINEAR,
borderMode =
int BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
·src:输入图像
·dst:透视变换后输出图像,与src数据类型相同,但是尺寸与dsize相同
·M:3x3的变换矩阵
·dsize:输出图像的尺寸
·flags:插值方法标志
·borderMode:像素边界外推方法的标志
·borderValue:填充边界使用的数值,默认情况下为0
示例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv; //opencv的命名空间
using namespace std;
int main()
{
//程序目的是为了将含有图像形变的二维码复原成正方形的二维码,首先我们并不知道透视的变换矩阵是多少,因此我们需要先计算透视变换矩阵
//透视变换矩阵计算需要四个像素点,所以我们需要在原图片中找到二维码的四个顶点,之后通过透视变换,将其置为图像的四个顶点
Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/toushi.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
//Point2f是opencv中用于表示二维平面上点的数据类型
Point2f src_points[4];
Point2f dst_points[4];
//通过Image Watch查看的二维码四个角点坐标
src_points[0] = Point2f(179.0,164.0);
src_points[1] = Point2f(152.0,416.0);
src_points[2] = Point2f(391.0,464.0);
src_points[3] = Point2f(432.0,202.0);
//期望透视变换后二维码四个焦点的坐标
dst_points[0] = Point2f(0.0,0.0);
dst_points[1] = Point2f(0.0,631.0);
dst_points[2] = Point2f(612.0,631.0);
dst_points[3] = Point2f(612.0,0.0);
Mat rotation, img_warp;
rotation = getPerspectiveTransform(src_points, dst_points); //计算透视变换矩阵
warpPerspective(img, img_warp, rotation, img.size());//透视变换投影
imshow("img", img);
imshow("img_warp", img_warp);
waitKey(0);
return 0;
}
结果
可以看见原来不平行与平面的二维码,经过处理可充满整个平面(部分截取)。