透视畸变和单应性变换

1.透视畸变

  透视投影导致图像变形;主要是由于相机成像角度和成像平面有倾斜导致的图像变形。

  举例:当你从地面拍摄高楼大厦时,建筑物的垂直边缘看起来会向顶部汇聚。

  校正:透视畸变可以通过单应性变换(Homography Transformation)来描述。单应性变换是一个 3x3 的齐次变换矩阵,能够将一个平面上的点映射到另一个平面上的对应点。透视畸变的数学模型可以用以下公式表示:p=Hp

  为了消除透视畸变,可以使用单应性变换将图像校正为正面视图。以下是校正透视畸变的步骤:
  1. 选择对应点:
    • 在原始图像中选择四个点,这些点定义了一个平面区域(例如,文档的四个角)。
    • 在目标图像中选择对应的四个点,这些点定义了校正后的平面区域(通常是矩形)。
  2. 计算单应性矩阵:
    • 使用这四对对应点,计算单应性矩阵 H。在OpenCV中,可以使用 cv::findHomography 函数来计算。
  3. 应用单应性变换:
    • 使用计算得到的单应性矩阵对原始图像进行变换,将图像校正为正面视图。在OpenCV中,可以使用 cv::warpPerspective 函数来实现。

 

2.单应性变换

  一种在二维平面上的几何变换,用于将一个平面的点映射到另一个平面上的对应点。它是一种3x3的齐次变换矩阵,能够描述两个平面之间的投影关系。单应性变换特别适用于处理图像之间的几何变换,例如校正图像、拼接图像、消除透视畸变等。

  应用:

  1. 图像校正:
    • 如果图像存在透视畸变(例如,从一个角度拍摄的平面物体),可以通过单应性变换将其校正为正面视图。
    • 例如,将倾斜拍摄的文档图像校正为正面视图。
  2. 图像拼接:
    • 在全景图像拼接中,单应性变换用于将多张图像对齐并拼接成一张全景图。
    • 通过找到两张图像之间的对应点,计算单应性矩阵,然后将图像映射到同一平面上。
  3. 增强现实(AR):
    • 在AR应用中,单应性变换用于将虚拟对象正确地放置在现实场景中。
    • 例如,将虚拟的3D模型投影到现实世界的平面上

 

coding:

import cv2
import numpy as np

def mouse_callback(event, x, y, flags, param):
    global points, image
    if event == cv2.EVENT_LBUTTONDOWN:
        points.append((x, y))
        cv2.circle(image, (x, y), 5, (0, 255, 0), -1)
        cv2.imshow("Image", image)

def correct_perspective(image_path, output_size=(400, 400)):
    global points, image
    points = []
    image = cv2.imread(image_path)
    if image is None:
        print("Error: Could not open or find the image!")
        return None

    cv2.namedWindow("Image")
    cv2.setMouseCallback("Image", mouse_callback)
    cv2.imshow("Image", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    if len(points) != 4:
        print("Error: You must select exactly 4 points!")
        return None

    src_points = np.array(points, dtype=np.float32)
    dst_points = np.array([
        [0, 0],
        [output_size[0] - 1, 0],
        [output_size[0] - 1, output_size[1] - 1],
        [0, output_size[1] - 1]
    ], dtype=np.float32)

    homography_matrix, _ = cv2.findHomography(src_points, dst_points)
    corrected_image = cv2.warpPerspective(image, homography_matrix, output_size)
    return corrected_image

if __name__ == "__main__":
    input_image_path = "../img/book.png"  # 替换为你的图片路径
    corrected_image = correct_perspective(input_image_path)

    if corrected_image is not None:
        cv2.imshow("Corrected Image", corrected_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

在一张倾斜的图上,至少标记四个点,作为原图的定位点:

image

 然后选四个点,作为目标图的匹配点,这里没有,就直接降校正后的图的四角作为匹配点了。得到的结果如下:

image

 

posted @ 2025-07-30 11:41  Wind_Swing_Dunn  阅读(351)  评论(0)    收藏  举报