OpenCV图像的旋转是通过图像的仿射变换来实现的,实现图像的旋转,分为三个步骤:
第一步:确定旋转角度和旋转中心。
第二步:确定旋转矩阵。通过getRotationMatrix2D函数计算出。
第三步:通过仿射变换实现旋转。通过warpAffine函数实现。
一、getRotationMatrix2D函数 原型CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);
功能:计算一个二维旋转的仿射矩阵。
函数计算下面的矩阵:
[
[
α
β
(
1
−
α
)
⋅
center.x
−
β
⋅
center.y
−
β
α
β
⋅
center.x
+
(
1
−
α
)
⋅
center.y
]
]
[begin{bmatrix} alpha & beta & (1- alpha ) cdot texttt{center.x} - beta cdot texttt{center.y} \ - beta & alpha & beta cdot texttt{center.x} + (1- alpha ) cdot texttt{center.y} end{bmatrix}]
[[α−ββα(1−α)⋅center.x−β⋅center.yβ⋅center.x+(1−α)⋅center.y]]
此处:
[
α
=
scale
⋅
cos
angle
,
β
=
scale
⋅
sin
angle
]
[begin{array}{l} alpha = texttt{scale} cdot cos texttt{angle} , \ beta = texttt{scale} cdot sin texttt{angle} end{array}]
[α=scale⋅cosangle,β=scale⋅sinangle]
变换映射旋转中心是到中心自己本身,如果这个不是目标,调整偏移量。
- 参数 center 源图像中的旋转中心
- 参数 angle 读书表示的旋转角度.正值表示逆时针旋转 (坐标原点假定在左上角).
- 参数 scale 两个轴的各向同性比例因子。1表示不缩放。
参考 getAffineTransform, warpAffine, transform
二、warpAffine函数 原型: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());
功能:对一个图像实现一个仿射变换
当设置标志WARP_INVERSE_MAP 的时候,函数warpAffine变换使用以下的矩阵来实现一个仿射变换:
[
dst
(
x
,
y
)
=
src
(
M
11
x
+
M
12
y
+
M
13
,
M
21
x
+
M
22
y
+
M
23
)
]
[texttt{dst} (x,y) = texttt{src} ( texttt{M} _{11} x + texttt{M} _{12} y + texttt{M} _{13}, texttt{M} _{21} x + texttt{M} _{22} y + texttt{M} _{23})]
[dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)]
否则,转换首先使用invertAffineTransform进行倒置,然后在上面的公式中代替M,函数不能就地转换。
- 参数 src 输入图像.
- 参数 dst 输出图像,大小是dszie,类型和src相同 。
- 参数 M 2*3的变换矩阵。
- 参数 dsize 输出图像大小。
- 参数 flags 插值方法的组合 (参见InterpolationFlags) 和可选的标志 WARP_INVERSE_MAP 意味着M是逆变换.
- 参数 borderMode 像素外推法 (参见 BorderTypes); 当
borderMode=#BORDER_TRANSPARENT, 意味着目标图像的像素对应于原图像中的“异常值”,并且不能被函数修改。 - 参数 borderValue 固定边缘情况下的值,默认是0。
参见warpPerspective, resize, remap, getRectSubPix, transform
三、源码示例 1.旋转#include#include using namespace cv; using namespace std; int main() { Mat src = imread("D:\OpenCVtest\images\juice.png", 1); if (src.empty()) { cout << "could not load image..." << endl; return -1; } double rotate_angle = 15; //设置旋转的角度 Point2f rotate_center(src.rows / 2, src.cols / 2); // 设置旋转中心 Mat rotate_matrix = getRotationMatrix2D(rotate_center, rotate_angle, 1); //计算旋转矩阵 Size dstSize(src.cols, src.rows); Mat image_dst; warpAffine(src, image_dst, rotate_matrix, dstSize ); // 仿射变换 imshow("源图像", src); imshow("仿射变换0", image_dst); waitKey(); return 0; }
运行结果:
2.三点映射#include#include using namespace cv; using namespace std; int main() { Mat src = imread("D:\OpenCVtest\images\juice.png", 1); if (src.empty()) { cout << "could not load image..." << endl; return -1; } Size dstSize(src.cols, src.rows); // 定义三个点 Point2f srcPoints[3]; Point2f dstPoints[3]; srcPoints[0] = Point2f(0, 0); srcPoints[1] = Point2f(0, (float)(src.cols-1)); srcPoints[2] = Point2f(float(src.rows-1), (float)(src.cols - 1)); // 变换后的三个点 dstPoints[0] = Point2f((float)(src.rows)*0.15, (float)(src.cols)*0.25); dstPoints[1] = Point2f((float)(src.rows) * 0.25, (float)(src.cols) * 0.65); dstPoints[2] = Point2f((float)(src.rows) * 0.70, (float)(src.cols) * 0.70); // 根据对应点求仿射矩阵 Mat rotate_matrx_1 = getAffineTransform(srcPoints, dstPoints); Mat image_warp; warpAffine(src, image_warp, rotate_matrx_1, dstSize); imshow("源图像", src); imshow("三点映射仿射变换", image_warp); waitKey(); return 0; }
运行结果:



