理论

设原始图像的任意点 \(P_0(x_0, y_0)\) 经顺时针旋转 \(\beta\) 角度后到新的位置 \(P(x,y)\),为表示方便,采用极坐标形式表示,原始点的角度为 \(\alpha\)。根据极坐标与直角坐标的关系,原始图像的点 \(P_0(x_0, y_0)\) 的极坐标为

\[\left\{ \begin{matrix} x_0 = r {\rm cos} \alpha \\ y_0 = r {\rm sin} \alpha \end{matrix} \right. \]

旋转到新位置以后 \(P(x, y)\) 的极坐标为

\[\left\{ \begin{matrix} x = r {\rm cos} (\alpha - \beta) = r{\rm cos}\alpha {\rm cos} \beta + r{\rm sin}\alpha {\rm sin}\beta\\ y = r {\rm sin} (\alpha - \beta) = r{\rm sin}\alpha {\rm cos} \beta - r{\rm cos}\alpha {\rm sin}\beta \end{matrix} \right. \]

由于旋转后的点 \(P(x, y)\) 需要用 \(P_0(x_0, y_0)\) 表示,对上式进行简化,得

\[\left\{ \begin{matrix} x = x_0 {\rm cos} \beta + y_0{\rm sin}\beta\\ y = -x_0 {\rm sin} \beta + y_0 {\rm cos}\beta \end{matrix} \right. \]

用矩阵表示如下:

\[\left[\begin{matrix} x \\ y \\ 1 \end{matrix}\right] = \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] \left[\begin{matrix} x_0 \\ y_0 \\ 1 \end{matrix}\right] \]

记上式中变换矩阵为

\[R = \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] \]

为旋转矩阵。

上述变换是针对原点的,如果指定了旋转中心,可以先按上述方式进行旋转,再把旋转后的中心平移到旋转前的中心。具体地,设旋转前的中线坐标为 \(C_0(x_0, y_0)\),则旋转后的坐标为 \(C(x,y)\),根据上面的关系,两个点的坐标关系即由上面矩阵变换确定。则旋转中心平移量为 \(\vec{CC_0}=C_0 - C\),代入 \((x,y)\),可得

\[\vec{CC_0}= \left[ \begin{matrix} \Delta x\\ \Delta y \end{matrix} \right] = \left[ \begin{matrix} x_0 - x\\ y_0 - y \end{matrix} \right] =\left[ \begin{matrix} x_0(1-{\rm cos} \beta) - y_0{\rm sin}\beta\\ x_0 {\rm sin} \beta + y_0 (1 - {\rm sin}\alpha) \end{matrix} \right] \]

根据上一节,则平移对应的平移矩阵为

\[T = \left[\begin{matrix} 1 & 0 & \Delta x\\ 0 & 1 & \Delta y\\ 0 & 0 & 1 \end{matrix}\right] \]

则旋转后再平移,对应矩阵为

\[M = TR = \left[\begin{matrix} 1 & 0 & \Delta x\\ 0 & 1 & \Delta y\\ 0 & 0 & 1 \end{matrix}\right] \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & 0\\ -{\rm sin} \beta & {\rm cos} \beta & 0\\ 0 & 0 & 1 \end{matrix}\right] = \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & \Delta x\\ -{\rm sin} \beta & {\rm cos}\beta &\Delta y\\ 0 & 0 & 1 \end{matrix}\right] = \left[\begin{matrix} {\rm cos} \beta & {\rm sin} \beta & x_0(1-{\rm cos} \beta) - y_0{\rm sin}\beta \\ -{\rm sin} \beta & {\rm cos}\beta &x_0 {\rm sin} \beta + y_0 (1 - {\rm sin}\alpha)\\ 0 & 0 & 1 \end{matrix}\right] \]

对于 OPENCV 的

cv2.getRotationMatrix2D()

乘以缩放系数,并取了上述变换矩阵 \(M\) 的前两行(第三行恒为 \([0,0,1]\)

实现

代码

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def show(img):
    if img.ndim == 2:
        plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    else:
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        plt.imshow(img)
    plt.show()


img = cv.imread('pic/rabbit500x333.jpg')
# 以(80,100)为中心,顺时针旋转45度
rotateM = cv.getRotationMatrix2D((80, 100), 45, 1)
img_rotate = cv.warpAffine(img, rotateM, dsize=(500, 500))
show(img_rotate)

效果


说明:

  1. 未经许可,谢绝转载。
  2. 本教程为《数字图像处理Python OpenCV实战》的配套代码相关内容。
    免费视频教程为0-6章(标题号≤6),可在此处点击观看。
    所有课件及源代码可在此处下载:
    链接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
    提取码:11o4
    有问题可在QQ群(1079300899)指出,进群答案:数字图像处理。在本文评论指出可能导致回复很晚。