OpenCv高阶(六)——图像的透视变换

发布于:2025-04-17 ⋅ 阅读:(26) ⋅ 点赞:(0)

目录

一、透视变换的定义与作用

二、透视变换的过程

三、OpenCV 中的透视变换函数

1. cv2.getPerspectiveTransform(src, dst)

2. cv2.warpPerspective(src, H, dsize, dst=None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0)

四、文档扫描校正(将倾斜文档转为正视图)

五、透视变换 vs 仿射变换

六、注意事项

1、点坐标的准确性

2、边界黑边处理

3、非平面场景的限制

七、总结


一、透视变换的定义与作用

透视变换是将图像从一个视平面投影到另一个视平面的几何变换,用于解决图像的透视畸变问题(如近大远小的视觉效果),或实现视角转换(如从倾斜图像恢复正视图)。

  • 核心目标:通过 4 组对应点(原图像与目标图像中的坐标对),计算单应性矩阵(Homography Matrix),将任意四边形区域映射为矩形(或其他四边形),实现视角校正或投影变换。
  • 应用场景:文档扫描校正、无人机航拍图像视角调整、增强现实(AR)中的虚拟物体叠加、目标检测中的视角归一化等。

二、透视变换的过程

        对一张我们即将做透视变换图像,首先要获取到图像中的4个坐标点,用于与目标图像中的坐标对应,这四个点还是有顺序的以坐标轴原点为参照点,距离原点最近的点为0号坐标,最远的为2号坐标,这两个点是最容易区分出来的;1号和3号位置可以通过坐标相减作为区分,距离X轴近的坐标的y值小于x值,所以按照x坐标减去y坐标得到的值1号坐标的值大于3号坐标的值。

        区分0和2号坐标点:对四个点每个点坐标的x和y的值相加求和,我们发现,针对任意图片轮廓,如果被四个点描绘,距离原点最近的点求和的值最小,在右下点的值求和的数值最大,可以区分出左上和右下两个点

         区分1和3号坐标点:对四个点每个点坐标的x和y的值相减(x-y),针对任意图片轮廓,如果被四个点描绘,位于右上角做差的值为一个很大的正数,在左下点的值做差的数值为负数,可以区分出左下和右上两个点

三、OpenCV 中的透视变换函数

OpenCV 提供两个核心函数实现透视变换:cv2.getPerspectiveTransform 和 cv2.warpPerspective

1. cv2.getPerspectiveTransform(src, dst)

  • 功能:根据 4 组对应点对计算单应性矩阵 H。

  • 参数

    • src:原图像中 4 个点的坐标(形状为 (4,2) 或 (4,1,2) 的浮点型数组)。

    • dst:目标图像中对应 4 个点的坐标(形状同上,通常取矩形的四个角点,如 (0,0), (w,0), (w,h), (0,h))。

  • 返回值:单应性矩阵 H(形状为 (3,3) 的浮点型矩阵)。

2. cv2.warpPerspective(src, H, dsize, dst=None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=0)

  • 功能:根据单应性矩阵 H 对图像进行透视变换。

  • 参数

    • src:输入图像(单通道或三通道)。

    • H:单应性矩阵(由 getPerspectiveTransform 计算得到)。

    • dsize:输出图像的大小(元组 (width, height))。

    • flags:插值方法(默认 cv2.INTER_LINEAR,常用 cv2.INTER_NEAREST 或 cv2.INTER_CUBIC)。

    • borderMode:边界填充模式(默认 cv2.BORDER_CONSTANT,可填充黑色或自定义颜色)。

    • borderValue:边界填充值(默认 0,即黑色)。

四、文档扫描校正(将倾斜文档转为正视图)

假设原图像中文档的四个角点坐标为 src_points,目标图像中希望将其映射为宽度 w、高度 h 的矩形(四个角点为 dst_points):

import cv2
import numpy as np

# 读取图像
img = cv2.imread('document.jpg')
h, w = img.shape[:2]

# 定义原图像中的4个角点(需手动选择或通过特征匹配获取)
src_points = np.float32([[92, 112], [381, 90], [390, 264], [120, 309]])  # 左上、右上、右下、左下(顺序需对应)
# 定义目标图像中的4个角点(通常为矩形的四个角,左上、右上、右下、左下)
dst_points = np.float32([[0, 0], [w, 0], [w, h], [0, h]])

# 计算单应性矩阵
H = cv2.getPerspectiveTransform(src_points, dst_points)

# 应用透视变换
warped_img = cv2.warpPerspective(img, H, (w, h))

# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('Warped Image', warped_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 可以看出我们将一张歪歪扭扭的照片扶正了,那么接下来我们就可以对图片做一些图像处理,使文本信息更加清晰。

关键点说明:

  1. 点的顺序

    • src_points 和 dst_points 中的点必须一一对应,通常按 左上→右上→右下→左下 的顺序排列,确保映射区域正确。

  2. 手动选点

    • 可通过鼠标交互函数(如 cv2.setMouseCallback)手动选择图像中的四个角点,提高灵活性。

  3. 目标图像大小

    • dsize 决定输出图像的宽度和高度,需根据实际需求设置(如原图像尺寸或自定义尺寸)。

五、透视变换 vs 仿射变换

特性

透视变换

仿射变换

变换类型

3D 投影到 2D 平面(非线性变换)

2D 平面内的线性变换 + 平移

对应点要求

至少 4 个不共线点对

至少 3 个不共线点对

保持性质

直线映射为直线,但平行线可能不平行

直线、平行线、相对距离比例保持不变

变换矩阵

3×3 矩阵(8 个自由度)

2×3 矩阵(6 个自由度)

应用场景

视角校正、文档扫描、AR 视角变换

旋转、缩放、平移、剪切等简单变换

仿射变换的知识我们将在后面通过案例来详细介绍。 

六、注意事项

1、点坐标的准确性

输入点对的微小误差会显著影响变换结果,建议通过特征匹配(如 SIFT、ORB)+ 随机抽样一致性算法(RANSAC)自动获取鲁棒的点对。

2、边界黑边处理

变换后的图像可能出现黑边(超出原图像范围),可通过调整 dsize 或裁剪去除黑边。

3、非平面场景的限制

透视变换假设场景为平面(如文档、墙面),若处理 3D 物体(如立方体),需分面处理或使用 3D 重建技术。

七、总结

透视变换是图像处理中解决视角畸变的核心技术,通过单应性矩阵实现任意四边形到矩形(或其他四边形)的映射,广泛应用于文档校正、图像拼接、AR 等领域。关键在于准确获取 4 组对应点对,并合理设置输出图像尺寸和插值方法。实际应用中,结合特征检测与匹配算法(如 SIFT+RANSAC)可实现自动化的透视变换,提高鲁棒性和效率。


网站公告

今日签到

点亮在社区的每一天
去签到