# OpenCV实现图像的几何变换

·  阅读 1195

「这是我参与11月更文挑战的第29天，活动详情查看：2021最后一次更文挑战

## 图像的几何变换

cv2.warpAffine() 函数使用以下 2 x 3 变换矩阵来变换源图像：

$dst(x,y)=src(M_{11}x+M_{12}y+M_{13}, M_{21}x+M_{22}y+M_{23})$

cv2.warpPerspective() 函数使用以下 3 x 3 变换矩阵变换源图像：

$dst(x,y)=src(\frac {M_{11}x+M_{12}y+M_{13}} {M_{31}x+M_{32}y+M_{33}}, \frac {M_{21}x+M_{22}y+M_{23}} {M_{31}x+M_{32}y+M_{33}})$

### 缩放图像

# 指定缩放后图像尺寸
resized_image = cv2.resize(image, (width * 2, height * 2), interpolation=cv2.INTER_LINEAR)

# 使用缩放因子
dst_image = cv2.resize(image, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

cv2.INTER_NEAREST最近邻插值
cv2.INTER_LINEAR双线性插值
cv2.INTER_AREA使用像素面积关系重采样
cv2.INTER_CUBIC基于4x4像素邻域的3次插值
cv2.INTER_LANCZOS4正弦插值

def show_with_matplotlib(color_img, title, pos):
# Convert BGR image to RGB
img_RGB = color_img[:,:,::-1]
ax = plt.subplot(1, 3, pos)
plt.imshow(img_RGB)
plt.title(title,fontsize=8)
# plt.axis('off')
show_with_matplotlib(image, 'Original image', 1)
show_with_matplotlib(dst_image, 'Resized image', 2)
show_with_matplotlib(dst_image_2, 'Resized image 2', 3)
plt.show()

### 平移图像

M = np.float32([[1, 0, x], [0, 1, y]])

$\begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix}$

dst_image = cv2.warpAffine(image, M, (width, height))

cv2.warpAffine() 函数使用提供的 M 矩阵转换源图像。第三个参数 (width, height) 用于确定输出图像的大小。

height, width = image.shape[:2]
M = np.float32([[1, 0, 200], [0, 1, 30]])
dst_image_1 = cv2.warpAffine(image, M, (width, height))

M = np.float32([[1, 0, -200], [0, 1, -30]])
dst_image_2 = cv2.warpAffine(image, M, (width, height))

### 旋转图像

$\begin{bmatrix} \alpha & \beta & (1-a)\cdot center.x-\beta\cdot center.y \\ -\beta & \alpha & \beta\cdot center.x-(1-\alpha)\cdot center.y \end{bmatrix}$

$\alpha=scale\cdot cos\theta, \beta=scale\cdot sin\theta$

height, width = image.shape[:2]
M = cv2.getRotationMatrix2D((width / 2.0, height / 2.0), 180, 1)
dst_image = cv2.warpAffine(image, M, (width, height))

M = cv2.getRotationMatrix2D((width/1.5, height/1.5), 30, 1)
dst_image_2 = cv2.warpAffine(image, M, (width, height))

### 2.4 图像的仿射变换

pts_1 = np.float32([[135, 45], [385, 45], [135, 230]])
pts_2 = np.float32([[135, 45], [385, 45], [150, 230]])
M = cv2.getAffineTransform(pts_1, pts_2)
dst_image = cv2.warpAffine(image_points, M, (width, height))

### 2.5 图像的透视变换

pts_1 = np.float32([[450, 65], [517, 65], [431, 164], [552, 164]])
pts_2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
M = cv2.getPerspectiveTransform(pts_1, pts_2)
dst_image = cv2.warpPerspective(image, M, (300, 300)

### 2.6 裁剪图像

dst_image = image[80:200, 230:330]