h11h21h31h12h22h32h13h23h33x′y′w′=Hxy1
变换后需要通过归一化操作x′=w′x′,y′=w′y′得到实际坐标。
齐次坐标表示二维点
二维欧几里得空间中,一个点表示为[X,Y]T,在齐次坐标中表示为[x,y,w]T,w为比例因子,实际坐标为
{X=wxY=wy
w=1时即为常规的二维坐标,透视变换前一般默认w=1,变换后需归一化保持一致性。
为什么要引入齐次坐标?
齐次坐标就是用 N+1 维向量表示 N 维坐标,即用齐次坐标系表示笛卡尔坐标系。引入齐次坐标旨在将各种几何变换都统一成矩阵相乘的形式,比如在二维坐标系中,平移变换只能用矩阵相加的形式表示,而在齐次坐标系中可用矩阵相乘的形式表示。
单应性矩阵求解
由于齐次坐标的比例不变性,即kH~H,k=0,故矩阵只有 8 个自由度,仅需四对变换前后的坐标即可求解单应性矩阵。往往令h33=1,求得唯一解。
代码实现
选点
需要得到四对或以上点的变换前后坐标
求解单应性矩阵
通过 OpenCV 提供的函数进行求解,cv2.getPerspectiveTransform 由精确的四对点返回单应性矩阵,cv2.findHomography 从四对以上的点中多次取样,通过优化算法筛得最优解,有一定的误差容忍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import cv2 import numpy as np
src_points = np.array([[100, 100], [200, 100], [200, 200], [100, 200]], dtype=np.float32)
dst_points = np.array([[50, 50], [300, 50], [300, 300], [50, 300]], dtype=np.float32)
H, status = cv2.findHomography(src_points, dst_points)
print("单应性矩阵 H:") print(H)
|
进行透视变换
1 2 3 4 5 6 7 8 9 10
| output_size = (300, 200)
warped_image = cv2.warpPerspective(image, M, output_size)
cv2.imshow('Warped Image', warped_image) cv2.waitKey(0) cv2.destroyAllWindows()
|
逆透视变换
如果想通过俯视图的坐标得到原图像对应坐标,对单应性矩阵求逆,进行变换即可。
透视变换中的具体应用思路可借鉴(https://hibanaw.com/archives/171/)
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Forrest's Blog🍭!