透视变换是一种图像几何变换操作,它可以将一个二维平面上的点映射到另一个二维平面上的相应位置,同时改变原始图像的形状和角度。在计算机视觉和图像处理中,透视变换通常用于校正图像的投影畸变或在不同视角或距离下重建三维场景。它可以通过定义透视变换矩阵来实现,该矩阵包含了平移、旋转、缩放和投影等变换操作。
透视变换中,透视前的图像和透视后的图像之间的变换关系可以用一个3×3的矩阵变换矩阵表示,该矩阵可以通过两张图像中四个对应点的坐标求取,因此透视变换又称作“四点变换”。与仿射变换一样,OpenCV 4中提供了根据四个对应点求取变换矩阵的getPerspectiveTransform()函数和进行透视变换的warpPerspective()函数。
1、求取变换矩阵
Mat cv::getPerspectiveTransform (const Point2f src[],
const Point2f dst[],
int solveMethod = DECOMP_LU
)
src[]:原图像中的四个像素坐标
dst[]:目标图像中的四个像素坐标
solveMethod:选择计算透视变换矩阵方法的标志,可以选择参数及含义在表1中给出
该函数两个输入量都是存放浮点坐标的数组,在生成数组的时候需要注意像素点的对应关系,函数的返回值是一个3×3的变换矩阵。
表1:计算透视变换矩阵方法的标志
2、透视变换
void cv::warpPerspective(InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
src:输入图像
dst:透视变换后输出图像,与src数据类型相同,但是尺寸与dsize相同
M:3×3的变换矩阵
dsize:输出图像的尺寸
flags:插值方法标志
borderMode:像素边界外推方法的标志
borderValue:填充边界使用的数值,默认情况下为0
3、例子
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("C:/opencv/1.bmp");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Point2f src_points[4];
Point2f dst_points[4];
//变换前图片四个角点坐标
src_points[0] = Point2f(94.0, 374.0);
src_points[1] = Point2f(507.0, 380.0);
src_points[2] = Point2f(1.0, 623.0);
src_points[3] = Point2f(627.0, 627.0);
//期望变换后图片四个角点的坐标
dst_points[0] = Point2f(0.0, 0.0);
dst_points[1] = Point2f(627.0, 0.0);
dst_points[2] = Point2f(0.0, 627.0);
dst_points[3] = Point2f(627.0, 627.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;
}