旋转(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')\)
\(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}\)
\(\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}\)