仿射变换(affine transform)与透视变换(perspective transform)在图像还原、图像局部变化处理方面有重要意义。通常,在2D平面中,仿射变换的应用较多,而在3D平面中,透视变换又有了自己的一席之地。两种变换原理相似,结果也类似,可针对不同的场合使用适当的变换。
仿射变换和透视变换的数学原理不需深究,在应用层面,仿射变换是图像基于3个固定顶点的变换,如下图所示:
仿射变换是图像基于3个固定顶点的变换,接下来学习的透视变换是4个固定顶点的变换
透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式为:
(u,v)为原始图像像素坐标,(x=x’/w’,y=y’/w’)为变换之后的图像像素坐标。透视变换矩阵图解如下:
仿射变换(Affine Transformation)可以理解为透视变换的特殊形式。透视变换的数学表达式为:
所以,给定透视变换对应的四对像素点坐标,即可求得透视变换矩阵;反之,给定透视变换矩阵,即可对图像或像素点坐标完成透视变换,如下图所示:
确定变换前后的四个对应点:选择变换前图像中的四个关键点,分别对应变换后图像中的四个点。这四个点应该能够构成一个矩形或者四边形,以便进行透视变换。
计算透视变换矩阵:通过选定的对应点,利用线性代数的方法计算出透视变换矩阵。这个矩阵可以将原始图像中的点映射到目标图像中对应的位置。
应用透视变换矩阵:利用计算得到的透视变换矩阵,对原始图像进行变换操作。通过在原始图像上的每个像素点应用透视变换矩阵,计算出对应的目标图像中的位置。
可选的后处理:根据需要,可以对变换后的图像进行一些额外的后处理操作,比如插值、边缘平滑等,以获得更好的视觉效果。
汽车的360度全景影像,从拍照视角变成鸟瞰图
常见的有文档矫正和汽车摄像头转成鸟瞰图,因为视角的原因,近处宽远处窄,呈不规则的四边形
仿射变换是单纯对图片进行平移,缩放,错切(倾斜)和旋转,而这几个操作都不会改变图片线之间的平行关系
仿射变换是在二维空间中,而透视变换则是在三维空间中视角的变化
T1为线性变换完成旋转,错切和放缩,T2完成平移操作,T3就是设了两个变量来表示映射关系
需要选取原图上的四个点以上的点集,并计算出该点集变换后的位置
from cv2 import cv2
import numpy as np
# 定义鼠标点击事件的回调函数
def get_mouse_position(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
print(f"Clicked at position ({x}, {y})")
# 读取图片文件
demo_file_path = 'paper.jpg'
img = cv2.imdecode(np.fromfile(demo_file_path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
#获取高宽,调整大小
h ,w = img.shape[:2]
print(h,w) #4624 3472
img2 = cv2.resize(img,(434,578)) #这里新的大小,h,w和上面展示的h,w顺序相反
cv2.imshow('img2',img2)
#创建窗口并绑定鼠标事件回调函数
cv2.namedWindow('img2')
cv2.setMouseCallback('img2',get_mouse_position)
# 定义对应的点 原始1(书本的4个角落坐标)、变换2
pts1 = np.float32([[109, 148], [307, 135], [99, 456], [326, 452]])
pts2 = np.float32([[0, 0], [434, 0], [0, 578], [434, 578]])
# 计算得到转换矩阵 3*3
M = cv2.getPerspectiveTransform(pts1, pts2)
# 透视变换
new_img = cv2.warpPerspective(img2, M, (280, 350))
cv2.imshow('perspective img', new_img)
cv2.waitKey(0)
需要注意的是,在进行透视变换时,选择合适的对应点非常重要。对应点的选择应该能够准确地反映出透视畸变,并且能够保持图像内容的一致性。此外,透视变换一般需要借助计算机图形学或图像处理库来实现,例如OpenCV等。
透视变换在许多应用中都有广泛的应用,比如摄影中的图像校正、增强现实中的虚拟物体渲染、计算机视觉中的物体检测与跟踪等。通过透视变换,可以改善图像的观感,提高图像处理和分析的准确性。