透视畸变和单应性变换
1.透视畸变
透视投影导致图像变形;主要是由于相机成像角度和成像平面有倾斜导致的图像变形。
举例:当你从地面拍摄高楼大厦时,建筑物的垂直边缘看起来会向顶部汇聚。
校正:透视畸变可以通过单应性变换(Homography Transformation)来描述。单应性变换是一个 3x3 的齐次变换矩阵,能够将一个平面上的点映射到另一个平面上的对应点。透视畸变的数学模型可以用以下公式表示:p′=H⋅p
  为了消除透视畸变,可以使用单应性变换将图像校正为正面视图。以下是校正透视畸变的步骤:
- 
选择对应点:- 
在原始图像中选择四个点,这些点定义了一个平面区域(例如,文档的四个角)。
- 
在目标图像中选择对应的四个点,这些点定义了校正后的平面区域(通常是矩形)。
 
- 
- 
计算单应性矩阵:- 
使用这四对对应点,计算单应性矩阵 H。在OpenCV中,可以使用cv::findHomography函数来计算。
 
- 
- 
应用单应性变换:- 
使用计算得到的单应性矩阵对原始图像进行变换,将图像校正为正面视图。在OpenCV中,可以使用cv::warpPerspective函数来实现。
 
- 
2.单应性变换
一种在二维平面上的几何变换,用于将一个平面的点映射到另一个平面上的对应点。它是一种3x3的齐次变换矩阵,能够描述两个平面之间的投影关系。单应性变换特别适用于处理图像之间的几何变换,例如校正图像、拼接图像、消除透视畸变等。
应用:
- 
图像校正:- 
如果图像存在透视畸变(例如,从一个角度拍摄的平面物体),可以通过单应性变换将其校正为正面视图。
- 
例如,将倾斜拍摄的文档图像校正为正面视图。
 
- 
- 
图像拼接:- 
在全景图像拼接中,单应性变换用于将多张图像对齐并拼接成一张全景图。
- 
通过找到两张图像之间的对应点,计算单应性矩阵,然后将图像映射到同一平面上。
 
- 
- 
增强现实(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()
在一张倾斜的图上,至少标记四个点,作为原图的定位点:

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

 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号