1. 透视变换
为了获得透视变换提供的更佳灵活性(透视变换又称单应性 (homography),即将点从一个平面映射到另一个平面上的对应点,保留了直线的关系),我们需要一个新的函数来表达这种更宽泛的变换。首先我们注意到, 尽管一个透视变换完全由一个单矩阵指定,但投影实际上不是线性变换。因为变换要求除最后的维数(通常是Z),因此,在处理的过程中丢失了一个维数。同仿射变换,图像运算(密度变换)不同于点运算(稀疏变换),它是由不同的函数完成的。
1.1 稠密透视变换:cv::warpPerspective()
( 1 ) 函数原型:
cpp
void cv::warpPerspective ( InputArray
OutputArray
InputArray
Size
int
int
const Scalar &
)
参数说明:
src ------ 输入图像
dst ------ 输出图像
M ------ 一个 3 × 3 变换矩阵
dsize ------ 输出图像大小
flags ------ 插值方法组合(INTER_LINEAR 或 INTER_NEAREST ) ,以及可选标识 WARP_INVERSE_MAP (这种情况集合 M 是作为逆变换矩阵)。
(3) 示例:
cpp
void Test_warpPerspective()
{
// 读取原图像
Mat img_src = imread("D:\\TestVideo\\Flower6-2.jpg");
// 读取原图像的四个角
vector<Point2f> pts_src;
//pts_src.push_back(Point2f(0, 0));
//pts_src.push_back(Point2f(480, 159));
//pts_src.push_back(Point2f(493, 630));
//pts_src.push_back(Point2f(64, 601));
pts_src.push_back(Point2f(0, 0));
pts_src.push_back(Point2f(img_src.cols-1, 0));
pts_src.push_back(Point2f(img_src.cols-1, img_src.rows-1));
pts_src.push_back(Point2f(0, img_src.rows - 1));
// 读目标图像
//Mat img_dst = Mat::zeros(img_src.rows, img_src.cols, img_src.type());
// 目标图像的四个角.
vector<Point2f> pts_dst;
pts_dst.push_back(Point2f(img_src.cols*0.05f, img_src.rows*0.33f ));
pts_dst.push_back(Point2f(img_src.cols*0.9f, img_src.rows*0.25f));
pts_dst.push_back(Point2f(img_src.cols*0.8f, img_src.rows * 0.9f));
pts_dst.push_back(Point2f(img_src.cols*0.2f, img_src.rows * 0.7f));
// 计算变换矩阵
// Calculate Homography
Mat warp_mat = findHomography(pts_src, pts_dst);
//或下列语句
//Mat warp_mat = getPerspectiveTransform(pts_src, pts_dst);
Mat img_out;
warpPerspective(img_src, img_out, warp_mat, img_src.size(),cv::INTER_LINEAR,cv::BORDER_CONSTANT,cv::Scalar());
// 显示图像
imshow("Source Image", img_src);
imshow("Warped Image", img_out);
cv::waitKey(0);
}
原图像:

变换后的图像:
