图像的几何变换又称为图像空间变换, 它将一幅图像中的坐标位置映射到另一幅图像中的 新坐标位置。常见的几何变换包括旋转、平移、缩放、镜像、转置、错切等,以及几种组合变换,如刚体变换、仿射变换、单应变换
旋转
( x , y , ) = ( c o s ( θ ) − s i n ( θ ) s i n ( θ ) c o s ( θ ) ) ( x y ) \left(\begin{matrix} x^,\\y^, \end{matrix}\right) = \left(\begin{matrix} cos(θ) & -sin(θ)\\ sin(θ) & cos(θ) \end{matrix}\right) \left(\begin{matrix} x\\y \end{matrix}\right) (x,y,)=(cos(θ)sin(θ)−sin(θ)cos(θ))(xy)
式中,θ表示旋转角(PS:如果是单坐标系,表示将点逆时针旋转;如果是两个坐标系转换,表示坐标系逆时针旋转,点顺时针旋转)。
M = cv2.getRotationMatrix2D((img.shape[1]*0.5, img.shape[0]*0.5), 30, 1)
img_dst = cv2.warpAffine(img, M, (width, height))
平移
M = np.float32([[1, 0, 100], [0, 1, 200]])
img_dst1 = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
缩放
M = cv2.getRotationMatrix2D((img.shape[1]*0.5, img.shape[0]*0.5), 0, 0.5)
img_dst = cv2.warpAffine(img, M, (width, height))
镜像
-
图像的镜像变换,包括水平镜像、垂直镜像和对角镜像。
-
水平镜像:
M = np.float32([[-1, 0, width], [0, 1, 0]])
img_dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
- 垂直镜像:
M = np.float32([[1, 0, 0], [0, -1, height]])
img_dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
- 对角镜像:
M = np.float32([[-1, 0, width], [0, -1, height]])
img_dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
转置
M = np.float32([[0, 1, 0], [1, 0, 0]])
img_dst = cv2.warpAffine(img, M, (img.shape[0], img.shape[1]))
错切(倾斜)
-
d x = t a n ( θ ) d~x~ =tan(θ) d x =tan(θ), d y = 0 d~y~ =0 d y =0 沿着X方向错切
-
d x = 0 d~x~ =0 d x =0, d y = t a n ( θ ) d~y~ =tan(θ) d y =tan(θ) 沿着Y方向错切
M = np.float32([[1, np.tan(0.1), 0], [0, 1, 0]])
img_dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
刚体变换
- 2D 的旋转和平移变换/rotation,translation, 3个自由度
- 点与点之间的距离不变,保角性
x , = ( R ⃗ T ⃗ ) x x^,= \left(\begin{matrix} \vec{R} & \vec{T} \end{matrix}\right)x x,=(RT)x
相似变换
- 相似变换包括旋转、平移变换,增加了均匀的缩放,4个自由度
- 点之间的距离变化,但是比例保持不变,保角性。
x , = ( s R T 0 ⃗ 1 ) x x^,=\left(\begin{matrix} sR & T \\ \vec{0} & 1 \end{matrix}\right)x x,=(sR0T1)x
仿射变换
- 仿射变换包括旋转(两个方向)、平移变换、缩放变换(两个尺度)、倾斜(错切)变换、翻转变换,6个自由度,没有保持保角性和点距比值,但是具有保持平行性。
- 保持平直性和平行性,但是角度会变
- 二维坐标到二维坐标之间的线性变换
src_point = np.float32([[526, 233],[1010, 411],[499, 1217]])
dst_point = np.float32([[92, 408],[628, 252],[972, 1058]])
warp_mat = cv2.getAffineTransform(src_point, dst_point)
img1_warp = cv2.warpAffine(img1, warp_mat, (img1.shape[1], img1.shape[0]))
投影变换
- 透视变换,单应变换
- 8个自由度,四组对应点求解
- 保持直线性,但是不保持平行性
- 二维到三维的映射
src_point = np.array([[526, 233],[1010, 411],[499, 1217],[53, 861]])
dst_point = np.array([[92, 408],[628, 252],[972, 1058],[303, 1300]])
H, _ = cv2.findHomography(src_point, dst_point)
img1_warp = cv2.warpPerspective(img1, H, (img2.shape[1], img2.shape[0]))