视觉实验三 全景图

视觉实验三 全景图

这次实验让我们分别使用平移变换和单应变换(仿射变换)拼接图像,生成全景图。时间过去很久了,简单说一下实验步骤和遇到的问题

一、球面坐标变换

使用平移变换需要先求得球面变换坐标,并校正径向畸变。按照公式可得代码

1
2
3
4
5
6
7
8
9
10
# 球面座标变换
xt = np.sin(xf)*np.cos(yf)
yt = np.sin(yf)
zt = np.cos(xf)*np.cos(yf)
xt = xt/zt
yt = yt/zt
# 校正畸变
r2=xt**2+yt**2
xt = xt*(1+k1*r2+k2*r2**2)
yt = yt*(1+k1*r2+k2*r2**2)

二、估计最佳变换矩阵

首先是求单应变换的方法,对于方程式 Ah = 0, 最佳解 h 是 ATA 具有最小特征值的特征向量,其中 AT是 A 的转置。根据线性代数知识,A 的右奇异向量是 ATA 的特征向量 。所以,求右奇异向量就可以了。通过调用np.linalg.svd(),实现矩阵的SVD分解。A矩阵如图所示

之后是使用RANSAC估计最佳变换矩阵。判断使用平移变换还是仿射变换,执行步骤

首先,它随机抽出一组最小的特征匹配对(对于平移变换只需要一个匹配对, 对于单应映射需要四个匹配对),估计相应的变换矩阵(对齐)(在单应映射时调用 computeHomography), 然后调用 getInliers 获取与当前运动估计一致的特征匹配索引; 在重复试验之后, 选择具有最大内点数量的运动估计,并使用 LeastSquaresFit 来对这一最大内点集合计算两幅图间的变换 M。

代码请自行查看。

三、融合图像

[TODO 8]给定图像和变换矩阵, 求出应用变换后图像的框。(imageBoundingBox)
[TODO 9]根据每幅图像的边框(使用 imageBoundingBox),计算出最终拼接图像的大小以及它们在全景图中的绝对位移。(getAccSize)

注意变换矩阵要齐次化,否则会失败

[TODO 10]然后,将每个图像重新映射到其最终位置(此处需要使用反向卷绕), 并将其与
相邻图像融合。

在这一步上纠结了将近一周,原因是没有注意到要用反向卷绕。反向卷绕是遍历生成图像的每个点,用变换矩阵的逆矩阵求出点在原图像的坐标,用这样的反向卷绕能很好的解决插值问题(直接在变换时加个参数就好)。如果是正向卷绕,生成图像上会有很多点被漏掉,再自己做插值处理就比较麻烦。

之后就是规范化和处理漂移问题。漂移这里我直接用了一个投影矩阵来实现生成图像的修正。

最终结果:
平移(translation)

单应(homography)

360度全景图

代码地址:
https://github.com/Xiayue09/VisionExp