一、函数:
a.getRotationMatrix2D
函数:
(1)函数原型:
-
CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);
(2) 函数作用:
- 计算一个2D旋转的仿射变换矩阵。这个矩阵可以用于图像处理中的旋转操作,将图像中的每个点绕指定的中心点按照给定的角度进行旋转,并且可以应用一个缩放因子。
(3)参数说明:
Point2f center
:旋转中心的坐标,以(x, y)的形式表示。double angle
:旋转角度,以度为单位。正值表示逆时针旋转。double scale
:各向同性缩放因子。
(4)旋转矩阵的计算公式:
- 旋转矩阵具体形式为:
(5) 补充说明:
-
这个变换矩阵将旋转中心映射到自身。如果目标不是这样,需要调整平移量。这个函数可以用来获取一个2D旋转变换的矩阵,该矩阵可以用于图像的仿射变换,例如在
warpAffine
或transform
函数中使用。
b.warpAffine
函数:
(1)函数原型:
CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, InputArray M,
Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
(2)函数作用:
warpAffine
根据提供的仿射变换矩阵M
对输入图像src
进行变换,生成输出图像dst
。
(3) 参数说明:
src
:输入图像,即要进行变换的原始图像。dst
:输出图像,其大小由dsize
指定,并且与src
具有相同的数据类型。M
:2x3
仿射变换矩阵,定义了图像点之间的线性变换关系。dsize
:输出图像的大小,即dst
的宽度和高度。flags
:插值方法的标志,可以是INTER_LINEAR
(双线性插值)、INTER_NEAREST
(最近邻插值)等,以及可选的WARP_INVERSE_MAP
标志,表示M
是逆变换矩阵。borderMode
:边界外推方法,用于处理图像边缘的像素。BORDER_CONSTANT
(常数边界)是默认选项,其他选项包括BORDER_REFLECT
、BORDER_WRAP
等。borderValue
:当borderMode
设置为BORDER_CONSTANT
时使用的边界值,默认为0。
(4) 变换公式:
-
如果设置了
WARP_INVERSE_MAP
标志,则直接使用M
矩阵进行变换。否则,首先使用invertAffineTransform
函数对M
进行求逆,然后将逆矩阵用于变换公式。
(5) 补充说明:
warpAffine
函数常用于图像校正、图像配准、图像变换等场景。-
该函数不能在原地(in-place)操作,即输入图像
src
和输出图像dst
不能是同一个图像。
(6) 相关函数:
-
warpPerspective
(用于透视变换)、resize
(用于改变图像大小)、remap
(用于一般映射)、getRectSubPix
(用于获取图像的子像素点)、transform
(用于对图像点应用线性变换)。
c.getAffineTransform
函数:
(1)函数原型:
CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
(2)函数作用:
- 根据源图像中的三个点和它们在目标图像中对应的三个点,计算一个仿射变换矩阵。
(3) 参数说明:
src
:源图像中三个顶点的坐标数组,每个顶点的坐标用Point2f
表示,即包含x
和y
两个浮点数。dst
:目标图像中与src
中顶点对应的三个顶点的坐标数组。
(4)变换公式:
(5) 补充说明:
-
函数返回一个
2x3
的仿射变换矩阵map_matrix
,这个矩阵可以用于warpAffine
或transform
函数来实际应用变换。 -
getAffineTransform
函数常用于图像配准、图像校正、图像变换等场景,特别是在已知源图像和目标图像之间三个对应点的情况下。
(6) 相关函数:
warpAffine
:使用仿射变换矩阵对图像进行变换。transform
:将变换应用到图像的点集或向量上。
d.getPerspectiveTransform 函数:
(1)函数原型:
CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst,
int solveMethod = DECOMP_LU);
(2)函数作用:
- 用于计算一个3x3的透视变换矩阵,它可以将图像中的一个四边形顶点集映射到另一个四边形顶点集。透视变换可以模拟相机视角的变化,用于图像校正等。
(3) 参数说明:
src
:源图像中四边形顶点的坐标数组。dst
:目标图像中与src
中顶点对应的四边形顶点的坐标数组。solveMethod
:传递给cv::solve
方法的选项,用于解决线性系统,DECOMP_LU
是默认的分解方法。
(4) 变换公式:
(5)公共点(getAffineTransform
)
- 两个函数都接受坐标数组作为输入,这些坐标定义了源图像和目标图像之间的对应关系。
- 它们都返回一个变换矩阵,可以用于
warpAffine
或warpPerspective
函数来实际应用变换。 - 它们都可以用于图像变换,但
getPerspectiveTransform
适用于更复杂的视角变换,而getAffineTransform
适用于保持平行线的变换。
(6) 注意事项
- 这些函数不能在原地(in-place)操作,即输入坐标和输出坐标不能相同。
- 透视变换和仿射变换都是线性变换,但透视变换可以模拟更复杂的视角效果。
e.warpPerspective
函数:
(1)函数原型:
CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst,
InputArray M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());
(2)函数作用:
warpPerspective
根据提供的3x3透视变换矩阵M
对输入图像src
进行变换,生成输出图像dst
。
(3) 参数说明:
src
:输入图像,即要进行变换的原始图像。dst
:输出图像,其大小由dsize
指定,并且与src
具有相同的数据类型。M
:3x3 透视变换矩阵,定义了图像点之间的变换关系。dsize
:输出图像的大小,即dst
的宽度和高度。flags
:插值方法的标志,可以是INTER_LINEAR
(双线性插值)或INTER_NEAREST
(最近邻插值),以及可选的WARP_INVERSE_MAP
标志,表示M
是逆变换矩阵。borderMode
:边界外推方法,可以是BORDER_CONSTANT
(常数边界)或BORDER_REPLICATE
(复制边界)等。borderValue
:当borderMode
设置为BORDER_CONSTANT
时使用的边界值,默认为0。
(4)变换公式:
- 当设置了
WARP_INVERSE_MAP
标志时使用上述公式。否则,首先使用invert
函数对M
进行求逆,然后将逆矩阵用于变换公式。
(5) 补充说明:
-
warpPerspective
函数常用于图像校正(如校正透视失真)、图像拼接、3D场景建模等。 -
该函数不能在原地(in-place)操作,即输入图像
src
和输出图像dst
不能是同一个图像。
(6) 相关函数:
warpAffine
(用于仿射变换)、resize
(用于改变图像大小)、remap
(用于一般映射)、getRectSubPix
(用于获取图像的子像素点)、perspectiveTransform
(用于对点集应用透视变换)。
二、示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
// 读取图片
Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Q版阿离.png");
// 判断图片是否读取成功
if (srcMat.empty()) return 0; // 如果图片未读取成功,结束程序
// 初始化旋转角度以及缩放尺度
auto angle = -10.0; // 定义旋转角度为-10度(逆时针)
float scale = 0.5; // 定义缩放因子为0.5
//设置旋转中心为图像中心(计算图像中心点坐标)
Point2f center(srcMat.cols * 0.5, srcMat.rows * 0.5);
//创建2x3的仿射变换矩阵(获得旋转缩放变换矩阵)
const Mat affine= getRotationMatrix2D(center, angle, scale);
// 定义存放旋转缩放结果的图像容器
Mat spin_Scale; // 用于存放旋转缩放后的图像
// 对原图像利用warpAffine函数进行仿射变换(旋转和缩放)
warpAffine(srcMat, spin_Scale, affine, srcMat.size());
// 定义仿射变换矩阵
Mat affine_image; // 用于存放仿射变换后的图像
// 变换前的三个点坐标
const Point2f src_pt[] = {
Point2f(200,200), // 第一个点的坐标
Point2f(250,200), // 第二个点的坐标
Point2f(200,100) // 第三个点的坐标
};
// 变换后的三个点坐标
const Point2f warp_pt[] = {
Point2f(300,100), // 第一个点变换后的坐标
Point2f(300,50), // 第二个点变换后的坐标
Point2f(200,100) // 第三个点变换后的坐标
};
//根据三个点,使用getAffineTransform计算仿射矩阵
const Mat affine_matrix = getAffineTransform(src_pt, warp_pt);
//对原图像利用warpAffine函数进行仿射变换
warpAffine(srcMat, affine_image, affine_matrix, srcMat.size());
// 定义透视变换矩阵
Mat perspective_image; // 用于存放透视变换后的图像
// 变换前的四个点坐标
Point2f pts1[] = {
Point2f(150,150), // 第一个点的坐标
Point2f(150,300), // 第二个点的坐标
Point2f(350,300), // 第三个点的坐标
Point2f(350,150) // 第四个点的坐标
};
// 变换后的四个点坐标
Point2f pts2[] = {
Point2f(200,150), // 第一个点变换后的坐标
Point2f(200,300), // 第二个点变换后的坐标
Point2f(340,270), // 第三个点变换后的坐标
Point2f(340,180) // 第四个点变换后的坐标
};
// 根据四个点, 使用getPerspectiveTransform计算透视变换矩阵
Mat perspective_matrix = cv::getPerspectiveTransform(pts1, pts2);
// 对原图像利用warpPerspective函数进行透视变换
warpPerspective(srcMat, perspective_image, perspective_matrix, srcMat.size());
// 显示所有结果
imshow("原图像", srcMat); // 显示原图像
imshow("旋转缩放", spin_Scale); // 显示旋转缩放后的图像
imshow("仿射变换", affine_image); // 显示仿射变换后的图像
imshow("透视变换", perspective_image); // 显示透视变换后的图像
waitKey(0); // 等待任意按键继续
destroyAllWindows(); // 关闭所有OpenCV创建的窗口
return 0;
}