图像仿射变换(Affine Transformation)是图像处理中的一种基本操作,它通过对图像的几何位置进行线性变换来实现图像的缩放、旋转、平移、剪切等操作。仿射变换保持了图像中的直线性和平行性,即变换后的图像中,原来平行的线依然是平行的,原来直线的部分依然是直线。
1.仿射变换的数学基础
仿射变换可以用一个矩阵乘法和一个向量加法来表示:
( x ′ y ′ ) = ( a b c d ) ( x y ) + ( e f ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} e \\ f \end{pmatrix} (x′y′)=(acbd)(xy)+(ef)
- 其中:
( x , y ) (x, y) (x,y) 是原图像中的点。
( x ′ , y ′ ) (x', y') (x′,y′)是变换后的点。
( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd)是线性变换矩阵,决定了旋转、缩放、剪切等变换。
( e f ) \begin{pmatrix} e \\ f \end{pmatrix} (ef) 是平移向量。
2. 常见的仿射变换
- 平移(Translation): 平移操作示意图像在 x 和 y 方向上移动。
( x ′ y ′ ) = ( 1 0 0 1 ) ( x y ) + ( t x t y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} tx \\ ty \end{pmatrix} (x′y′)=(1001)(xy)+(txty)
其中 ( t x , t y ) (tx, ty) (tx,ty) 是平移的距离。
- 旋转(Rotation): 旋转操作示意图像绕某一点旋转。
( x ′ y ′ ) = ( cos θ − sin θ sin θ cos θ ) ( x y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} (x′y′)=(cosθsinθ−sinθcosθ)(xy)
其中 θ \theta θ 是旋转角度。
- 缩放(Scaling): 缩放操作示意图像按比例放大或缩小。
( x ′ y ′ ) = ( s x 0 0 s y ) ( x y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} sx & 0 \\ 0 & sy \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} (x′y′)=(sx00sy)(xy)
其中 s x sx sx 和 s y sy sy 是 x 和 y 方向的缩放因子。
- 剪切(Shearing): 剪切操作示意图像在某一方向上倾斜。
( x ′ y ′ ) = ( 1 s h x s h y 1 ) ( x y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & sh_x \\ sh_y & 1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} (x′y′)=(1shyshx1)(xy)
其中 s h x sh_x shx和 s h y sh_y shy是剪切因子。
3.在 OpenCV 中的实现
在 OpenCV 中,可以使用 cv2.getAffineTransform()
或 cv2.warpAffine()
函数来实现仿射变换。
1. 使用 cv2.getAffineTransform()
这是通过三个点来确定一个仿射变换矩阵。
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_your_image.jpg')
# 定义三个点及其变换后的位置
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
# 计算仿射变换矩阵
M = cv2.getAffineTransform(pts1, pts2)
# 应用仿射变换
transformed_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# 显示结果
cv2.imshow('Transformed Image', transformed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 使用 cv2.warpAffine()
直接应用预计算的仿射变换矩阵。
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_your_image.jpg')
# 定义仿射变换矩阵
M = np.float32([[1, 0, 100], [0, 1, 50]]) # 平移操作
# 应用仿射变换
transformed_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# 显示结果
cv2.imshow('Transformed Image', transformed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
4,总结
仿射变换是图像处理中的一种基本变换,能够实现图像的平移、旋转、缩放和剪切等操作。通过理解仿射变换的数学基础和在 OpenCV 中的实现方法,可以灵活地对图像进行各种几何变换。