DLT算法求解单应性矩阵
DLT算法求解单应性矩阵
原理:
单应性矩阵描述了两个图像之间的投影变换关系,即从一张图到另一张图的变换。
下面是DLT算法的基本原理:
- 构建投影方程: 对于两个图像中的对应点 (x,y,1) 和 (u,v,1) ,投影关系可以用齐次坐标表示为 cuv1=Hxy1 ( c 只是一个常数,由于是齐次坐标,所以不影响 )。这里的 H( 3×3 矩阵)是我们要求解的单应性矩阵
H=h1h4h7h2h5h8h3h6h9
- 构建矩阵 A: 将上面的投影方程展开成 Ah=0 的形式,其中 A 是一个 2n×9 的矩阵, h 是包含矩阵 H 所有元素的列向量
A=−x10⋮−xn0−y10⋮−yn0−10⋮−100−x1⋮0−xn0−y1⋮0−yn0−1⋮0−1u1x1v1x1⋮unxnvnxnu1y1v1y1⋮unynvnynu1v1⋮unvn
h=[h1h2h3h4h5h6h7h8h9]
奇异值分解(SVD): 对矩阵 A 进行奇异值分解,得到 A=UΣVT。取 VT 的最后一列作为 h 的估计
方程的最小二乘解有一个既定的结论,即对 A 进行SVD分解,得到的 VT 的最后一行 即是 h 的解,对 h 做 reshape 得到 H 。
实现:
根据你提供的信息,DLT(Direct Linear Transform)算法用于通过最小二乘法来估计单应性矩阵 H,以拟合两组特征点之间的关系。下面是DLT算法的具体步骤:
构建矩阵 A: 对于每一对特征点 (x,y,1) 和 (u,v,1),构建一个对应的矩阵 Ai。将所有这些矩阵堆叠成一个大矩阵 A
def get_Ai(xi_vector, xi_prime_vector): assert (xi_vector.shape == (3,) and xi_prime_vector.shape == (3,)) Ai = np.zeros((2, 9)) Ai[0] = np.array( [-xi_vector[0], -xi_vector[1], -1, 0, 0, 0, xi_vector[0] * xi_prime_vector[0], xi_vector[1] * xi_prime_vector[0], xi_prime_vector[0]]) Ai[1] = np.array( [0, 0, 0, -xi_vector[0], -xi_vector[1], -1, xi_vector[0] * xi_prime_vector[1], xi_vector[1] * xi_prime_vector[1], xi_prime_vector[1]]) assert (Ai.shape == (2, 9)) return Ai
-x & -y & -1 & 0 & 0 & 0 & ux & vy & uv \ 0 & 0 & 0 & -x & -y & -1 & ux & vy & uv \ \end
def get_A(points_source, points_target): N = points_source.shape[0] A = np.zeros((2 * N, 9)) for i in range(len(points_target)): Ai = get_Ai(points_source[i], points_target[i]) A[2 * i:2 * i + 2] = Ai
assert (A.shape == (2 * N, 9)) return A
SVD分解: 对矩阵 A 进行奇异值分解(SVD),得到 A=UΣVT 。取 VT 矩阵的最后一行作为矩阵 h
Reshape: 将向量 h reshape 为 3×3 的单应性矩阵 H
def get_homography(points_source, points_target): A = get_A(points_source, points_target) _, _, Vt = np.linalg.svd(A) Homo = Vt[-1].reshape((3, 3)) assert (Homo.shape == (3, 3)) return Homo