旋转(Rotation)

def _get_rotation_matrix(rotate_degrees):
    radian = math.radians(rotate_degrees)
    rotation_matrix = np.array(
        [[np.cos(radian), -np.sin(radian), 0.],
         [np.sin(radian), np.cos(radian), 0.], [0., 0., 1.]],
        dtype=np.float32)
    return rotation_matrix

如下图所示,点 \(v(x,y)\) 逆时针旋转到 \(v'(x',y')\)

常见仿射变换矩阵-LMLPHP

\(x^{'}=Rcos(\alpha -\theta )=Rcos\alpha cos\theta +Rsin\alpha sin\theta =xcos\theta +ysin\theta\)

\(y^{'}=Rsin(\alpha -\theta )=Rsin\alpha cos\theta -Rcos\alpha sin\theta =ycos\theta -xsin\theta\)

\(\begin{bmatrix} x^{'}\\ y^{'} \end{bmatrix}=\begin{bmatrix} cos\theta &sin\theta \\ -sin\theta &cos\theta \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}=M\begin{bmatrix} x\\ y \end{bmatrix}=\begin{bmatrix}
 xcos\theta+ysin\theta\\
ycos\theta-xsin\theta
\end{bmatrix}\)

注意,这里的旋转矩阵 \(M\) 和上面代码中实现的旋转矩阵 \(M'\),两者互为转置 \(M'=M^{T}\)。这是因为在mmdet的实现中,最终的变换是通过函数cv2.warpPerspective实现的,在该函数中,当没有设置参数WARP_INVERSE_MAP即默认情况下,转换矩阵需要先进行转置操作。

另外,上面代码的实现是完整的齐次坐标形式,这是因为2x2矩阵没法描述平移操作,为了将旋转与后面的缩放、平移、剪切统一表示,引入了齐次坐标。代码中rotation_matrix如下

\(\begin{bmatrix}
  cos\theta&  -sin\theta& 0\\
  sin\theta&  cos\theta& 0\\
  0&  0& 1
\end{bmatrix}\)

缩放(Scaling)

def _get_scaling_matrix(scale_ratio):
    scaling_matrix = np.array(
        [[scale_ratio, 0., 0.], [0., scale_ratio, 0.], [0., 0., 1.]],
        dtype=np.float32)
    return scaling_matrix

缩放变换矩阵如下

\(\begin{bmatrix}
  scale\_ratio&  0& 0\\
  0&  scale\_ratio& 0\\
  0&  0& 1
\end{bmatrix}\)

\(\begin{bmatrix}
 x'\\
 y'\\
1
\end{bmatrix}=\begin{bmatrix}
  scale\_ratio&  0& 0\\
  0&  scale\_ratio& 0\\
  0&  0& 1
\end{bmatrix}\begin{bmatrix}
 x\\
 y\\
1
\end{bmatrix}=\begin{bmatrix}
 scale\_ratio\times x\\
 scale\_ratio\times y\\
1
\end{bmatrix}\)

剪切(Shear)

def _get_shear_matrix(x_shear_degrees, y_shear_degrees):
    x_radian = math.radians(x_shear_degrees)
    y_radian = math.radians(y_shear_degrees)
    shear_matrix = np.array([[1, np.tan(x_radian), 0.],
                             [np.tan(y_radian), 1, 0.], [0., 0., 1.]],
                            dtype=np.float32)
    return shear_matrix

剪切变换矩阵如下

\(\begin{bmatrix}
  1& tan\theta & 0\\
  tan\theta&  1& 0\\
  0&  0& 1
\end{bmatrix}\)

常见仿射变换矩阵-LMLPHP

\(\begin{bmatrix}
 x'\\
 y'\\
1
\end{bmatrix}=\begin{bmatrix}
  1& tan\theta & 0\\
  tan\theta&  1& 0\\
  0&  0& 1
\end{bmatrix}\begin{bmatrix}
x \\
y \\
1
\end{bmatrix}=\begin{bmatrix}
x+ytan\theta \\
y+xtan\theta \\
1
\end{bmatrix}\)

平移(Translation)

def _get_translation_matrix(x, y):
    translation_matrix = np.array([[1, 0., x], [0., 1, y], [0., 0., 1.]],
                                  dtype=np.float32)
    return translation_matrix

平移变换矩阵如下

\(\begin{bmatrix}
  1& 0 & x_t\\
  0&  1& y_t\\
  0&  0& 1
\end{bmatrix}\)

\(\begin{bmatrix}
 x'\\
 y'\\
1
\end{bmatrix}=\begin{bmatrix}
  1& 0 & x_t\\
  0&  1& y_t\\
  0&  0& 1
\end{bmatrix}\begin{bmatrix}
x \\
y \\
1
\end{bmatrix}=\begin{bmatrix}
x+x_t \\
y+y_y \\
1
\end{bmatrix}\)

参考

https://blog.csdn.net/qw8704149/article/details/118856088

11-22 10:33