基础矩阵用于描述两个视图之间的几何关系
基础矩阵:基础矩阵 F 是描述两个视图之间相机投影关系的矩阵。对于两个对应的图像坐标点 (x,y,1) 和 (u,v,1) 在两个视图上,基础矩阵满足以下方程:
这个方程即对极约束,描述了图像中对应点的投影关系
uv1T⋅F⋅xy1=0
线性系统:对于多对对应点,可以构建一个线性方程系统 Af=0 ,其中 A 是由对应点生成的矩阵, f 是基础矩阵的扁平形式
上述方程即:
[uv1]⋅f11f21f31f12f22f32f13f23f33⋅xy1=0
展开得到:
[uxvxxuyvyyuv1]⋅f11f12f13f21f22f23f31f32f33=0
这个矩阵方程可以表示为 Aif=0
为了解出这个9个未知数的 f ,我们至少需要8对点,所以叠加 Ai 得到 A 矩阵
A=x1u1x2u2⋮x8u8x1v1x2v2⋮x8v8x1x2⋮x8y1u1y2u2⋮y8u8y1v1y2v2⋮y8v8y1y2⋮y8u1u2⋮u8v1v2⋮v811⋮1
最小二乘法:通过奇异值分解(SVD),取 VT 的最后一列作为估计矩阵 A 的最小二乘解,即 f
方程的最小二乘解有一个既定的结论,即对 A 进行SVD分解,得到的 VT 的最后一行 即是 f 的解
基础矩阵还原:将 f reshape 为 3×3 的矩阵,然后通过奇异值分解(SVD)对矩阵进行调整,以确保基础矩阵的秩为2
SVD分解: 对矩阵 F 进行奇异值分解:F=UΣVT ,其中 U 和 V 是正交矩阵,Σ 是对角矩阵
秩-2约束: 将奇异值矩阵 Σ 调整为仅保留前两个奇异值(将第三个奇异值设为0),以确保基础矩阵的秩为2
重构基础矩阵: F=UΣ′VT
F = f.reshape((3, 3))
# 对F进行SVD分解
U, S, Vt = np.linalg.svd(F)
# 将奇异值矩阵Sigma调整为仅保留前两个奇异值(第三个设为0)
S[2] = 0
# 重构基础矩阵F
F = np.dot(U, np.dot(np.diag(S), Vt))
归一化:对基础矩阵进行归一化,以确保尺度的一致性
对普通的八点算法进行了改进,通过标准化输入数据,提高了算法的稳健性和准确性
我们首先将对应点标准化为零均值和单位方差,以消除尺度的影响
mean1 = np.mean(keypoints1, axis=0)
mean2 = np.mean(keypoints2, axis=0)
std1 = np.std(keypoints1, axis=0)
std2 = np.std(keypoints2, axis=0)
# 防止除0,由于齐次坐标,标准差std算得最后一项为0
std1[2] = 1
std2[2] = 1
nomalized_points1 = (keypoints1 - mean1) / std1
nomalized_points2 = (keypoints2 - mean2) / std2
xˉ=σxx−μxˉ
也等于左乘一个转换矩阵 T :
T=σx1000σy10−σxμx−σyμy1
在这些标准化点上运行八点算法
最后对得到的基本矩阵进行反变换,在计算基础矩阵后,需要将其进行撤销标准化处理,以获得最终的基础矩阵
F=T2−1⋅Fnormalized⋅T1
我们有两个相机,它们的c分别为 P1 和 P2 ( 3×4 矩阵)。
P=K[R∣t]
对于一个在相机1和相机2中分别观察到的同一物体的对应点 x~1 和 x~2 (齐次坐标 3×1 向量) ,我们可以得到以下方程:其中,X~ (齐次坐标 4×1 向量)是物体在三维空间中的坐标
P1X~=x~1P2X~=x~2
将 P 分解为三个向量:
PiPi1Pi2Pi3=Pi1Pi2Pi3=[p11,p12,p13,p14]=[p21,p22,p23,p24]=[p31,p32,p33,p34]
这样,原等式就变为:
Pi1X~Pi2X~Pi3X~=xiyi1
将左边向量齐次化除以第三个元素,与右边向量元素一一对应:
PiX~xiyi=Pi3X~Pi1X~Pi3X~Pi2X~1=xiyi1=x~i=Pi3X~Pi1X~⇒xiPi3X~−Pi1X~=0=Pi3X~Pi2X~⇒yiPi3X~−Pi2X~=0
由于我们知道 x1 、 x2 和 P1 、 P2 ,我们可以将其转化为一个齐次线性方程组:
A1A2AAX~=[x1P13−P11y1P13−P12]=[x2P23−P21y2P23−P22]=[A1A2]=0
A = np.array(
[keypoint1[0] * P1[2] - P1[0],
keypoint1[1] * P1[2] - P1[1],
keypoint2[0] * P2[2] - P2[0],
keypoint2[1] * P2[2] - P2[1]]
)
这样我们就可以使用最小二乘法或其他方法来解决这个线性方程组,从而找到物体的三维位置 X
# DLT算法解决最小二乘法
_, _, Vt = np.linalg.svd(A)
x_w = Vt[-1]
x_w = x_w / x_w[3] # 齐次坐标