浅谈旋转矩阵和平移向量的计算原理
1 def img_transform(img, post_rot, post_tran, 2 resize, resize_dims, crop, 3 flip, rotate): 4 # adjust image 5 img = img.resize(resize_dims) # 变形 crop 6 img = img.crop(crop) 7 if flip: 8 img = img.transpose(method=Image.FLIP_LEFT_RIGHT) 9 img = img.rotate(rotate) 10 11 # post-homography transformation 12 post_rot *= resize 13 post_tran -= torch.Tensor(crop[:2]) 14 if flip: 15 A = torch.Tensor([[-1, 0], [0, 1]]) 16 b = torch.Tensor([crop[2] - crop[0], 0]) 17 post_rot = A.matmul(post_rot) 18 post_tran = A.matmul(post_tran) + b 19 A = get_rot(rotate/180*np.pi) 20 b = torch.Tensor([crop[2] - crop[0], crop[3] - crop[1]]) / 2 21 b = A.matmul(-b) + b 22 post_rot = A.matmul(post_rot) 23 post_tran = A.matmul(post_tran) + b 24 25 return img, post_rot, post_tran 26
旋转矩阵和平移向量的计算原理:
增强的顺序是:resize,crop,flip,rotate
假设初始坐标为(x,y),
a) resize
坐标变为(rx,ry) , r为变换scale,此时旋转矩阵和平移向量为:
R1=((r, 0),(0,r)),
t1=(0,0)
b) crop
若左上角crop点坐标为(cx,cy),则坐标变为(rx-cx,ry-cy) ,旋转矩阵和平移向量为:
R2=((r, 0),(0,r)),
t2=(-cx,-cy)
至此,对应上述12到13行得到的张量。
c)水平flip
记crop出来的区块宽度为w,坐标变化: (x3,y3)=(w-x2,y2)=(-rx+w+cx,ry-cy) ,旋转矩阵和平移向量为:
R3=((-r, 0),(0,r)) = ((-1, 0),(0,1))((r, 0),(0,r))=((-1, 0),(0,1))*R2
t3=(w+cx,-cy)=((-1, 0),(0,1))(-cx,-cy)+(w,0)=((-1, 0),(0,1))*t2+(w,0)
该步对应上述15到18行。
d)rotate
一般旋转公式左乘旋转矩阵是针对相对原点旋转的情况,而图像旋转一般是围绕图像中心旋转。因此,我们需要先把坐标系平移到图像中心,即由(x3,y3)变成 (x3-w/2,y3-h/2),再左乘旋转矩阵A ,最后再把坐标系转回到原点。
因此:(x4,y4)=A( (x3-w/2,y3-h/2)) +(w/2,h/2) = A( (-rx+w/2+cx,ry-h/2-cy)) +(w/2,h/2) =A((-r, 0),(0,r))(x,y)+A(w/2+cx,-h/w-cy)+(w/2,h/2)即: (x4,y4)=AR3(x,y)+A((w+cx,-cy)+(-w/2,-h/2))+(w/2,h/2)=AR3(x,y)+At3+A(-(w/2,h/2))+(w/2,h/2) .
其中A=((cosa,sina),(-sina,cosa))因此,令b=(w/2,h/2),旋转矩阵和平移向量为:
R4=AR3
t4=At3+A(-b)+b
到此对应上述19到23行。