OpenCV图像矫正是一项重要的图像处理任务,通常用于纠正由于拍摄角度、镜头畸变等因素导致的图像变形。
透视变换(Perspective Transformation)是将一个平面内的点映射到另一个平面内的点的过程。它通过矩阵运算实现,可以处理复杂的几何变换,例如倾斜、旋转和缩放。在现实世界中,我们观察到的物体在视觉上会受到透视效果的影响,即远处的物体看起来会比近处的物体小。透视投影是指将三维空间中的物体投影到二维平面上的过程,这个过程会导致物体在图像中出现形变和透视畸变。

数学基础:
透视变换的核心是一个3x3的变换矩阵 H,该矩阵定义了输入图像坐标系与输出图像坐标系之间的映射关系。 假设输入图像上的点为 (x,y),经过透视变换后得到输出图像上的点 (x′,y′),则有:

其中 w 是齐次坐标的一部分,最终的点坐标需要归一化为 (x′/w,y′/w)。
关键步骤: 1. 确定输入图像中的四个点(通常是矩形的四个顶点)。 2. 确定目标图像中对应的四个点。 3. 使用这四对点计算透视变换矩阵 H。 4. 应用矩阵 H 对图像进行变换。
应用场景: - 校正文档扫描图像的倾斜。 - 模拟三维场景的不同视角。 - 地图投影和地理信息系统的图像处理。
透视变换相比仿射变换更加灵活,变换后会产生一个新的四边形,但不一定是平行四边形,所以需要非共线的四个点才能唯一确定,原图中的直线变换后依然是直线。因为四边形包括了所有的平行四边形,所以透视变换包括了所有的仿射变换。
OpenCV中首先根据变换前后的四个点用cv.getPerspectiveTransform()生成3×3的变换矩阵,然后再用cv.warpPerspective()进行透视变换。
代码实例:
# 导入OpenCV和NumPy库
import cv2
import numpy as np
# 读取图片文件
img = cv2.imread('./images/png/bank_card02.png')
# 定义四个点,这些点是图片中需要被变换的区域的四个角点
points1 = np.float32([
[293, 62], # 左上角点
[599, 146], # 右上角点
[29, 494], # 左下角点
[372, 616] # 右下角点
])
# 计算包围points1的最小外接矩形的四个角点
points2 = np.float32([
[min(points1[:, 0]), min(points1[:, 1])], # 左上角点
[max(points1[:, 0]), min(points1[:, 1])], # 右上角点
[min(points1[:, 0]), max(points1[:, 1])], # 左下角点
[max(points1[:, 0]), max(points1[:, 1])] # 右下角点
])
# 使用getPerspectiveTransform函数计算透视变换矩阵M
M = cv2.getPerspectiveTransform(points1, points2)
# 使用warpPerspective函数对图片进行透视变换
dst = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))
# 计算变换后图片的最小外接矩形的坐标
min_x, min_y = points2.min(axis=0).astype(int)
max_x, max_y = points2.max(axis=0).astype(int)
# 根据最小外接矩形的坐标裁剪变换后的图片
cropped_dst = dst[min_y:max_y, min_x:max_x]
rotated = cv2.rotate(cropped_dst, cv2.ROTATE_90_CLOCKWISE)
resized = cv2.resize(rotated, None, fx=1.0, fy=0.6, interpolation=cv2.INTER_CUBIC)
# 显示原始图片
cv2.imshow('Original', img)
# 显示裁剪后的变换图片
cv2.imshow('cropped_dst', resized)
# 等待按键,0表示无限等待直到有按键按下
cv2.waitKey(0)

透视变换和仿射变换是两种不同的几何变换类型,透视变换并不属于仿射变换,而是更复杂、更一般化的变换形式。以下是两者的关键区别和联系:
| 特性 | 仿射变换 | 透视变换 |
|---|---|---|
| 平行性保持 | ✅ 平行线仍平行 | ❌ 平行线可能相交 |
| 直线性保持 | ✅ 直线仍为直线 | ✅ 直线仍为直线 |
| 近大远小效果 | ❌ 无法模拟 | ✅ 可模拟 |
| 矩阵自由度 | 6 自由度(平移、旋转等) | 8 自由度(含投影分量) |
| 典型应用 | 图像平移、旋转、缩放 | 生成鸟瞰图、三维投影 |