仿射变换介绍
仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。
仿射变换原理
-
仿射变换矩阵
M = [A B] =
[ a 00 a 01 b 00 a 10 a 11 b 10 ] (1) \begin{bmatrix} a00 & a01 & b00 \\ a10 & a11 & b10 \end{bmatrix} \tag{1} [a00a10a01a11b00b10](1) -
仿射变换原理
**T=A * [x,y] + B **
仿射变换相关函数
图像仿射变换
warpAffine()
void cv::warpAffine(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:2*3的变换矩阵
- dsize:输出图像大小
- flags:插值方法标志
- borderMode:像素边界外推方法标志
- borderValue:填充边界使用的数值,默认为0
旋转矩阵仿射变换
getRotationMatrix2D()
Mat cv::getRotationMatrix2D(Point2f center,
double angel,
double scale)
-
center:图像旋转的中心位置
-
angle:图像旋转的角度,正直为逆时针旋转
-
scale:两个轴的比例因子,可以实现旋转过程中的比例缩放,不缩放则为1
R o t a t i o n = [ a 00 a 01 b 00 a 10 a 11 b 10 ] (1) Rotation = \begin{bmatrix} a00 & a01 & b00 \\ a10 & a11 & b10 \end{bmatrix} \tag{1} Rotation=[a00a10a01a11b00b10](1)
其中 α = scale * cos(angle)
β = scale * cos(angle)
三点对应仿射变换
getAffineTransform()
Mat cv::getAffineTransform(const Point2f src[],
const Point2f dst[])
- src[]:原图像中三个像素坐标
- dst[]:目标图像中的三个像素坐标
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("lena.png");
Mat rotation0, rotation1, img_warp0, img_warp1;
double angle = 30; // 图像旋转角度
Size dst_size(img.rows/2, img.cols/2); // 设置输出图像尺寸
// 设置旋转中心点
Point2f center(img.rows / 2.0, img.cols / 2.0);
// 计算仿射变换矩阵
rotation0 = getRotationMatrix2D(center, angle, 1);
warpAffine(img, img_warp0, rotation0, dst_size, WARP_INVERSE_MAP);
imshow("rotation0", img_warp0);
// 根据定义的三个点进行仿射变换
Point2f src_points[3];
Point2f dst_points[3];
// 原始图像中的三个点
src_points[0] = Point2f(0, 0);
src_points[1] = Point2f(0, (float)(img.cols - 1));
src_points[2] = Point2f((float)(img.rows - 1), (float)(img.cols - 1));
// 仿射变换后的三个点
dst_points[0] = Point2f((float)(img.rows * 0.11), (float)(img.cols * 0.20));
dst_points[1] = Point2f((float)(img.rows * 0.15), (float)(img.cols * 0.70));
dst_points[2] = Point2f((float)(img.rows * 0.81), (float)(img.cols * 0.85));
rotation1 = getAffineTransform(src_points, dst_points);
warpAffine(img, img_warp1, rotation1, dst_size, WARP_FILL_OUTLIERS);
imshow("img_warp1", img_warp1);
waitKey(0);
return 0;
}