- 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)
x′=Rcos(α−θ)=Rcosαcosθ+Rsinαsinθ=xcosθ+ysinθ
y′=Rsin(α−θ)=Rsinαcosθ−Rcosαsinθ=ycosθ−xsinθ
[x′y′]=[cosθsinθ−sinθcosθ][xy]=M[xy]=[xcosθ+ysinθycosθ−xsinθ]
注意,这里的旋转矩阵 M 和上面代码中实现的旋转矩阵 M′,两者互为转置 M′=MT。这是因为在mmdet的实现中,最终的变换是通过函数cv2.warpPerspective实现的,在该函数中,当没有设置参数WARP_INVERSE_MAP即默认情况下,转换矩阵需要先进行转置操作。
另外,上面代码的实现是完整的齐次坐标形式,这是因为2x2矩阵没法描述平移操作,为了将旋转与后面的缩放、平移、剪切统一表示,引入了齐次坐标。代码中rotation_matrix如下
[cosθ−sinθ0sinθcosθ0001]
- 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
缩放变换矩阵如下
[scale_ratio000scale_ratio0001]
[x′y′1]=[scale_ratio000scale_ratio0001][xy1]=[scale_ratio×xscale_ratio×y1]
- 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
剪切变换矩阵如下
[1tanθ0tanθ10001]
[x′y′1]=[1tanθ0tanθ10001][xy1]=[x+ytanθy+xtanθ1]
- 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
平移变换矩阵如下
[10xt01yt001]
[x′y′1]=[10xt01yt001][xy1]=[x+xty+yy1]