【精选】图像(点)绕任意中心位置旋转的旋转矩阵推导

您所在的位置:网站首页 直线绕点旋转45度的解析式 【精选】图像(点)绕任意中心位置旋转的旋转矩阵推导

【精选】图像(点)绕任意中心位置旋转的旋转矩阵推导

2023-10-28 13:37| 来源: 网络整理| 查看: 265

1 以原点为中心的旋转矩阵推导

为了推导绕任意中心位置旋转的旋转矩阵,可以先从简单绕原点旋转开始推导。

假设有点 P ( x a , x b ) P(x_a,x_b) P(xa​,xb​),绕原点顺时针旋转了 θ \theta θ度后,求其旋转矩阵 T \boldsymbol{T} T(图1)。

图1

P绕原点顺时针旋转 θ \theta θ,可以看成是坐标轴逆时针旋转旋转 θ \theta θ,求P点在新坐标轴上的坐标(图2)。

图2

由上图可知, O P A → = [ x a y a ] , O P B → = [ x b y b ] \overrightarrow{OP_A}=\left[\begin{matrix}x_a \\ y_a\end{matrix} \right],\overrightarrow{OP_B}=\left[\begin{matrix}x_b \\ y_b\end{matrix} \right] OPA​ ​=[xa​ya​​],OPB​ ​=[xb​yb​​],所求的便是 O P A → = T O P B → \overrightarrow{OP_A}=\boldsymbol{T}\overrightarrow{OP_B} OPA​ ​=TOPB​ ​中的变换矩阵 T \boldsymbol{T} T。

在图中作辅助线如下图(图3),可以知道 ∠ A O B = ∠ A P D = θ O B = O A c o s θ B C = A D = A P s i n θ \angle AOB = \angle APD = \theta \\ OB=OAcos\theta\\ BC = AD = APsin\theta \\ ∠AOB=∠APD=θOB=OAcosθBC=AD=APsinθ 即 x b = O B + O C = x a c o s θ + y a s i n θ x_b = OB+OC = x_acos\theta + y_asin\theta xb​=OB+OC=xa​cosθ+ya​sinθ 同理可得 y b = − x a s i n θ + y a c o s θ y_b=-x_asin\theta + y_acos\theta yb​=−xa​sinθ+ya​cosθ

图3

转化为矩阵形式为 [ x b y b ] = [ c o s θ s i n θ − s i n θ c o s θ ] [ x a y a ] T = [ c o s θ s i n θ − s i n θ c o s θ ] \left[\begin{matrix}x_b \\ y_b\end{matrix} \right]=\left[\begin{matrix} cos\theta &sin\theta\\ -sin\theta&cos\theta \end{matrix}\right]\left[\begin{matrix}x_a \\ y_a\end{matrix} \right]\\ \boldsymbol{T}= \left[\begin{matrix} cos\theta &sin\theta\\ -sin\theta&cos\theta \end{matrix}\right] [xb​yb​​]=[cosθ−sinθ​sinθcosθ​][xa​ya​​]T=[cosθ−sinθ​sinθcosθ​]

所以对于P绕原点逆时针旋转 T = [ c o s ( − θ ) s i n ( − θ ) − s i n ( − θ ) c o s ( − θ ) ] = [ c o s θ − s i n θ s i n θ c o s θ ] = c o s θ [ 1 0 0 1 ] + s i n θ [ 0 − 1 1 0 ] = e θ [ 0 − 1 1 0 ] \boldsymbol{T}= \left[\begin{matrix} cos(-\theta) &sin(-\theta)\\ -sin(-\theta)&cos(-\theta) \end{matrix}\right]= \left[\begin{matrix} cos\theta &-sin\theta\\ sin\theta&cos\theta \end{matrix}\right]= cos\theta \left[\begin{matrix} 1 &0\\ 0&1 \end{matrix}\right]+sin\theta \left[\begin{matrix} 0&-1\\ 1&0 \end{matrix}\right]=e^{\theta \left[\begin{matrix} 0&-1\\ 1&0 \end{matrix}\right]} T=[cos(−θ)−sin(−θ)​sin(−θ)cos(−θ)​]=[cosθsinθ​−sinθcosθ​]=cosθ[10​01​]+sinθ[01​−10​]=eθ[01​−10​]

2 任意中心的旋转矩阵推导

知道了绕原点旋转的形式,其实点绕任意中心旋转的只是多了一个平移步骤(图4)。

图4

假设 O ′ ( x c , y c ) O'(x_c,y_c) O′(xc​,yc​)没旋转前 P P P对于 O ′ O' O′的坐标为 ( x a − x c , y a − y c ) (x_a-x_c,y_a-y_c) (xa​−xc​,ya​−yc​)。

以上文的方法让 P P P绕 O ′ O' O′逆时针旋转得到 x b = ( x a − x c ) c o s θ − ( y a − y c ) s i n θ y b = ( x a − x c ) s i n θ + ( y a − y c ) c o s θ x_b=(x_a-x_c)cos\theta - (y_a-y_c)sin\theta \\ y_b=(x_a-x_c)sin\theta + (y_a-y_c)cos\theta xb​=(xa​−xc​)cosθ−(ya​−yc​)sinθyb​=(xa​−xc​)sinθ+(ya​−yc​)cosθ

再将坐标系 O ′ O' O′平移回 O O O得到 x b = ( x a − x c ) c o s θ − ( y a − y c ) s i n θ + x c = x a c o s θ − y a s i n θ − x c c o s θ + y c s i n θ + x c y b = ( x a − x c ) s i n θ + ( y a − y c ) c o s θ + y c = x a s i n θ + y a c o s θ − x c s i n θ − y c c o s θ + y c (1) x_b=(x_a-x_c)cos\theta - (y_a-y_c)sin\theta + x_c \\ = x_acos\theta-y_asin\theta-x_ccos\theta+y_csin\theta+x_c\\ \\ y_b=(x_a-x_c)sin\theta + (y_a-y_c)cos\theta + y_c \\ =x_asin\theta+y_acos\theta-x_csin\theta-y_ccos\theta+y_c\tag{1} xb​=(xa​−xc​)cosθ−(ya​−yc​)sinθ+xc​=xa​cosθ−ya​sinθ−xc​cosθ+yc​sinθ+xc​yb​=(xa​−xc​)sinθ+(ya​−yc​)cosθ+yc​=xa​sinθ+ya​cosθ−xc​sinθ−yc​cosθ+yc​(1)

其齐次化矩阵形式为 [ x b y b 1 ] = [ c o s θ − s i n θ − x c c o s θ + y c s i n θ + x c s i n θ c o s θ − x c s i n θ − y c c o s θ + y c 0 0 1 ] [ x a y a 1 ] \left[\begin{matrix}x_b \\ y_b\\1\end{matrix} \right]= \begin{bmatrix}cos\theta & -sin\theta & -x_c cos\theta+y_c sin\theta + x_c \\ sin\theta&cos\theta&-x_c sin\theta - y_c cos\theta + y_c\\ 0 & 0 & 1 \\ \end{bmatrix}\begin{bmatrix}x_a\\y_a\\1\\\end{bmatrix} ⎣ ⎡​xb​yb​1​⎦ ⎤​=⎣ ⎡​cosθsinθ0​−sinθcosθ0​−xc​cosθ+yc​sinθ+xc​−xc​sinθ−yc​cosθ+yc​1​⎦ ⎤​⎣ ⎡​xa​ya​1​⎦ ⎤​ 另外,如果从公式1来看,其矩阵形式还有另外一种 [ x b y b ] = [ c o s θ − s i n θ s i n θ c o s θ ] [ x a − x c y a − x c ] + [ x c y c ] (3) \begin{bmatrix}x_b\\y_b\end{bmatrix}=\left[\begin{matrix} cos\theta &-sin\theta\\ sin\theta&cos\theta \end{matrix}\right]\left[\begin{matrix}x_a-x_c \\ y_a-x_c\end{matrix} \right]\\ +\begin{bmatrix}x_c\\y_c\end{bmatrix}\tag{3} [xb​yb​​]=[cosθsinθ​−sinθcosθ​][xa​−xc​ya​−xc​​]+[xc​yc​​](3)

齐次化(齐次化升维后可以把加法变成减法?) [ x b y b 1 ] = [ 1 0 x c 0 1 y c 0 0 1 ] [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] [ 1 0 − x c 0 1 − y c 0 0 1 ] [ x a y a 1 ] (4) \begin{bmatrix}x_b\\y_b\\1\end{bmatrix}= \begin{bmatrix} 1&0&x_c\\ 0&1&y_c\\ 0&0&1 \end{bmatrix} \left[\begin{matrix} cos\theta &-sin\theta&0\\ sin\theta&cos\theta&0\\ 0&0&1 \end{matrix}\right] \begin{bmatrix} 1&0&-x_c\\ 0&1&-y_c\\ 0&0&1 \end{bmatrix} \left[\begin{matrix}x_a \\ y_a\\1\end{matrix} \right]\\\tag{4} ⎣ ⎡​xb​yb​1​⎦ ⎤​=⎣ ⎡​100​010​xc​yc​1​⎦ ⎤​⎣ ⎡​cosθsinθ0​−sinθcosθ0​001​⎦ ⎤​⎣ ⎡​100​010​−xc​−yc​1​⎦ ⎤​⎣ ⎡​xa​ya​1​⎦ ⎤​(4) 即 Q = T ( x c , x c ) R ( θ ) T ( − x c , − y c ) P Q=T(x_c,x_c)R(\theta)T(-x_c,-y_c)P Q=T(xc​,xc​)R(θ)T(−xc​,−yc​)P,其中 T T T为平移矩阵, R R R为旋转矩阵。

从公式4的形式来看,点绕任意中心位置旋转其实就是先将坐标系从原点位置平移后旋转再平移回来。

3 代码实现

首先根据公式3计算变换矩阵

import numpy as np from skimage import io,transform,img_as_float import matplotlib.pyplot as plt def generate_matrix(theta,pos): (x0,y0)=pos c = np.cos(np.radians(theta)) s = np.sin(np.radians(theta)) matrix = np.zeros((3,3)) matrix[0,0] = c matrix[0,1] = -s matrix[1,0] = s matrix[1,1] = c matrix[0,2] = -c * x0 + s * y0 + x0 matrix[1,2] = -c * y0 - s * x0 + y0 matrix[2,2] = 1 return matrix

由于图片旋转后会超出其原本矩阵范围,所以需要重新计算旋转后图片的高宽。

def trans_and_box(matrix, shape): h = shape[0] w = shape[1] rect_original = np.array([[0,0,1],[0,h,1],[w,0,1],[w,h,1]]) #构建四个顶点齐次坐标 rect_mapped = np.dot(matrix, rect_original.T) #利用矩阵运算计算变换后的顶点位置 min_val = rect_mapped.min(axis=1) #计算两个方向的最小值 max_val = rect_mapped.max(axis=1) #计算两个方向的最大值 #计算反向平移的值 trans_pos = (-np.floor(min_val[0]) if (min_val[0]>0) else -np.ceil(min_val[0]), -np.floor(min_val[1]) if (min_val[1]>0) else -np.ceil(min_val[1])) #计算图像变换后高度和宽度,注意skimage中图像采用(h,w,c)方式来表示 output_shape = (int(np.ceil(max_val[1]-min_val[1])), \ int(np.ceil(max_val[0]-min_val[0]))) return trans_pos, output_shape

然后用自己写的函数与skimage库的旋转函数处理图像后进行对比(图5)。

org_img = img_as_float(io.imread("images/dog.jpg",as_gray=True)) ref_img = transform.rotate(org_img,30,resize=True) #skimage的旋转函数 deg = -30 pos = (600,600) mat = generate_matrix(deg,pos) trans_pos, output_shape = trans_and_box(mat,org_img.shape) tform = transform.SimilarityTransform(mat) + transform.SimilarityTransform(translation=trans_pos) out_img = transform.warp(org_img, tform.inverse, output_shape=output_shape) plt.subplot(121) plt.imshow(ref_img,cmap='gray') plt.title('Default') plt.subplot(122) plt.imshow(out_img,cmap='gray') plt.title('Around pivot')

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlFYp30C-1637246621633)(C:\Users\cheng\AppData\Roaming\Typora\typora-user-images\image-20211118224118432.png)]

图5 4 参考文献 [1]Rotational Transform Matrix Derivation:https://www.youtube.com/watch?v=8XRvpDhTJpw[2]旋转矩阵(Rotation Matrix)的推导及其应用:https://blog.csdn.net/weixin_33812433/article/details/86398663


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3