← 返回首页
图像矫正
发表时间:2025-02-17 07:37:21
图像矫正

OpenCV图像矫正是一项重要的图像处理任务,通常用于纠正由于拍摄角度、镜头畸变等因素导致的图像变形。

1.透视变换

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

数学基础:

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

其中 w 是齐次坐标的一部分,最终的点坐标需要归一化为 (x′/w,y′/w)。

关键步骤: 1. 确定输入图像中的四个点(通常是矩形的四个顶点)。 2. 确定目标图像中对应的四个点。 3. 使用这四对点计算透视变换矩阵 H。 4. 应用矩阵 H 对图像进行变换。

应用场景: - 校正文档扫描图像的倾斜。 - 模拟三维场景的不同视角。 - 地图投影和地理信息系统的图像处理。

透视变换相比仿射变换更加灵活,变换后会产生一个新的四边形,但不一定是平行四边形,所以需要非共线的四个点才能唯一确定,原图中的直线变换后依然是直线。因为四边形包括了所有的平行四边形,所以透视变换包括了所有的仿射变换。

2.OpenCV实现图像矫正

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)

3. 仿射变换与透视变换的区别

透视变换和仿射变换是两种不同的几何变换类型,透视变换并不属于仿射变换,而是更复杂、更一般化的变换形式。以下是两者的关键区别和联系:

特性 仿射变换 透视变换
平行性保持 ✅ 平行线仍平行 ❌ 平行线可能相交
直线性保持 ✅ 直线仍为直线 ✅ 直线仍为直线
近大远小效果 ❌ 无法模拟 ✅ 可模拟
矩阵自由度 6 自由度(平移、旋转等) 8 自由度(含投影分量)
典型应用 图像平移、旋转、缩放 生成鸟瞰图、三维投影