DLT算法求解单应性矩阵

DLT算法求解单应性矩阵

原理:

单应性矩阵描述了两个图像之间的投影变换关系,即从一张图到另一张图的变换。

下面是DLT算法的基本原理:

  1. 构建投影方程: 对于两个图像中的对应点 ( x , y , 1 ) (x, y, 1) (x,y,1) ( u , v , 1 ) (u, v, 1) (u,v,1) ,投影关系可以用齐次坐标表示为 c [ u v 1 ] = H [ x y 1 ] c \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = H \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} c uv1 =H xy1 c c c 只是一个常数,由于是齐次坐标,所以不影响 )。这里的 H H H 3 × 3 3 \times 3 3×3 矩阵)是我们要求解的单应性矩阵

H = [ h 1 h 2 h 3 h 4 h 5 h 6 h 7 h 8 h 9 ] H =\begin{bmatrix} h1 & h2 & h3 \\ h4 & h5 & h6 \\ h7 & h8 & h9 \end{bmatrix} H= h1h4h7h2h5h8h3h6h9

  1. 构建矩阵 A A A 将上面的投影方程展开成 A h = 0 Ah = 0 Ah=0 的形式,其中 A A A 是一个 2 n × 9 2n \times 9 2n×9 的矩阵, h h h 是包含矩阵 H H H 所有元素的列向量

A = [ − x 1 − y 1 − 1 0 0 0 u 1 x 1 u 1 y 1 u 1 0 0 0 − x 1 − y 1 − 1 v 1 x 1 v 1 y 1 v 1 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ − x n − y n − 1 0 0 0 u n x n u n y n u n 0 0 0 − x n − y n − 1 v n x n v n y n v n ] A = \begin{bmatrix} -x_1 & -y_1 & -1 & 0 & 0 & 0 & u_1x_1 & u_1y_1 & u_1 \\ 0 & 0 & 0 & -x_1 & -y_1 & -1 & v_1x_1 & v_1y_1 & v_1 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ -x_n & -y_n & -1 & 0 & 0 & 0 & u_nx_n & u_ny_n & u_n \\ 0 & 0 & 0 & -x_n & -y_n & -1 & v_nx_n & v_ny_n & v_n \\ \end{bmatrix} A= x10xn0y10yn010100x10xn0y10yn0101u1x1v1x1unxnvnxnu1y1v1y1unynvnynu1v1unvn

h = [ h 1 h 2 h 3 h 4 h 5 h 6 h 7 h 8 h 9 ] h=\begin{bmatrix}h1&h2&h3&h4&h5&h6&h7&h8&h9\end{bmatrix} h=[h1h2h3h4h5h6h7h8h9]

  1. 奇异值分解(SVD): 对矩阵 A A A 进行奇异值分解,得到 A = U Σ V T A = U \Sigma V^T A=UΣVT。取 V T V^T VT 的最后一列作为 h h h​ 的估计

    方程的最小二乘解有一个既定的结论,即对 A A A 进行SVD分解,得到的 V T V^T VT 的最后一行 即是 h h h 的解,对 h h h 做 reshape 得到 H H H

实现:

根据你提供的信息,DLT(Direct Linear Transform)算法用于通过最小二乘法来估计单应性矩阵 H H H,以拟合两组特征点之间的关系。下面是DLT算法的具体步骤:

  1. 构建矩阵 A A A 对于每一对特征点 ( x , y , 1 ) (x, y, 1) (x,y,1) ( u , v , 1 ) (u, v, 1) (u,v,1),构建一个对应的矩阵 A i A_i Ai。将所有这些矩阵堆叠成一个大矩阵 A A 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
    

    A i = [ − x − y − 1 0 0 0 u x v y u v 0 0 0 − x − y − 1 u x v y u v ] A_i = \begin{bmatrix} -x & -y & -1 & 0 & 0 & 0 & ux & vy & uv \\ 0 & 0 & 0 & -x & -y & -1 & ux & vy & uv \\ \end{bmatrix} Ai=[x0y0100x0y01uxuxvyvyuvuv]

    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
    
  2. SVD分解: 对矩阵 A A A 进行奇异值分解(SVD),得到 A = U Σ V T A = U \Sigma V^T A=UΣVT 。取 V T V^T VT 矩阵的最后一行作为矩阵 h h h

  3. Reshape: 将向量 h h h reshape 为 3 × 3 3 \times 3 3×3 的单应性矩阵 H H 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
    
  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值