三角測量
1. 核心公式推導
假設兩個相機的投影矩陣為 P P P 和 P ′ P' P′,對應的匹配圖像點(同名點)為 ( u , v ) (u, v) (u,v) 和 ( u ′ , v ′ ) (u', v') (u′,v′),目標是求解三維點 X = [ X x , X y , X z , 1 ] T X = [X_x, X_y, X_z, 1]^T X=[Xx?,Xy?,Xz?,1]T(齊次坐標)。
投影方程
每個相機的投影方程可以表示為:
{ u = P 00 X x + P 01 X y + P 02 X z + P 03 P 20 X x + P 21 X y + P 22 X z + P 23 v = P 10 X x + P 11 X y + P 12 X z + P 13 P 20 X x + P 21 X y + P 22 X z + P 23 u ′ = P 00 ′ X x + P 01 ′ X y + P 02 ′ X z + P 03 ′ P 20 ′ X x + P 21 ′ X y + P 22 ′ X z + P 23 ′ v ′ = P 10 ′ X x + P 11 ′ X y + P 12 ′ X z + P 13 ′ P 20 ′ X x + P 21 ′ X y + P 22 ′ X z + P 23 ′ \begin{cases} u = \frac{P_{00}X_x + P_{01}X_y + P_{02}X_z + P_{03}}{P_{20}X_x + P_{21}X_y + P_{22}X_z + P_{23}} \\ v = \frac{P_{10}X_x + P_{11}X_y + P_{12}X_z + P_{13}}{P_{20}X_x + P_{21}X_y + P_{22}X_z + P_{23}} \\ u' = \frac{P'_{00}X_x + P'_{01}X_y + P'_{02}X_z + P'_{03}}{P'_{20}X_x + P'_{21}X_y + P'_{22}X_z + P'_{23}} \\ v' = \frac{P'_{10}X_x + P'_{11}X_y + P'_{12}X_z + P'_{13}}{P'_{20}X_x + P'_{21}X_y + P'_{22}X_z + P'_{23}} \\ \end{cases} ? ? ??u=P20?Xx?+P21?Xy?+P22?Xz?+P23?P00?Xx?+P01?Xy?+P02?Xz?+P03??v=P20?Xx?+P21?Xy?+P22?Xz?+P23?P10?Xx?+P11?Xy?+P12?Xz?+P13??u′=P20′?Xx?+P21′?Xy?+P22′?Xz?+P23′?P00′?Xx?+P01′?Xy?+P02′?Xz?+P03′??v′=P20′?Xx?+P21′?Xy?+P22′?Xz?+P23′?P10′?Xx?+P11′?Xy?+P12′?Xz?+P13′???
消去分母
將分母移到等式左邊,得到四個線性方程:
{ u ( P 20 X x + P 21 X y + P 22 X z + P 23 ) = P 00 X x + P 01 X y + P 02 X z + P 03 v ( P 20 X x + P 21 X y + P 22 X z + P 23 ) = P 10 X x + P 11 X y + P 12 X z + P 13 u ′ ( P 20 ′ X x + P 21 ′ X y + P 22 ′ X z + P 23 ′ ) = P 00 ′ X x + P 01 ′ X y + P 02 ′ X z + P 03 ′ v ′ ( P 20 ′ X x + P 21 ′ X y + P 22 ′ X z + P 23 ′ ) = P 10 ′ X x + P 11 ′ X y + P 12 ′ X z + P 13 ′ \begin{cases} u (P_{20}X_x + P_{21}X_y + P_{22}X_z + P_{23}) = P_{00}X_x + P_{01}X_y + P_{02}X_z + P_{03} \\ v (P_{20}X_x + P_{21}X_y + P_{22}X_z + P_{23}) = P_{10}X_x + P_{11}X_y + P_{12}X_z + P_{13} \\ u' (P'_{20}X_x + P'_{21}X_y + P'_{22}X_z + P'_{23}) = P'_{00}X_x + P'_{01}X_y + P'_{02}X_z + P'_{03} \\ v' (P'_{20}X_x + P'_{21}X_y + P'_{22}X_z + P'_{23}) = P'_{10}X_x + P'_{11}X_y + P'_{12}X_z + P'_{13} \\ \end{cases} ? ? ??u(P20?Xx?+P21?Xy?+P22?Xz?+P23?)=P00?Xx?+P01?Xy?+P02?Xz?+P03?v(P20?Xx?+P21?Xy?+P22?Xz?+P23?)=P10?Xx?+P11?Xy?+P12?Xz?+P13?u′(P20′?Xx?+P21′?Xy?+P22′?Xz?+P23′?)=P00′?Xx?+P01′?Xy?+P02′?Xz?+P03′?v′(P20′?Xx?+P21′?Xy?+P22′?Xz?+P23′?)=P10′?Xx?+P11′?Xy?+P12′?Xz?+P13′??
矩陣形式
將上述方程整理為齊次方程組 A ? X = 0 A \cdot X = 0 A?X=0,其中系數矩陣 A A A 的每一行對應一個方程:
A = [ u P 2 ? P 0 v P 2 ? P 1 u ′ P 2 ′ ? P 0 ′ v ′ P 2 ′ ? P 1 ′ ] A = \begin{bmatrix} u P_{2} - P_{0} \\ v P_{2} - P_{1} \\ u' P'_{2} - P'_{0} \\ v' P'_{2} - P'_{1} \\ \end{bmatrix} A= ?uP2??P0?vP2??P1?u′P2′??P0′?v′P2′??P1′?? ?
這里 P i P_{i} Pi? 表示投影矩陣的第 i i i 行(如 P 0 = [ P 00 , P 01 , P 02 , P 03 ] P_{0} = [P_{00}, P_{01}, P_{02}, P_{03}] P0?=[P00?,P01?,P02?,P03?]),進而通過SVD求解 X X X的齊次坐標。
2. 代碼實現步驟
以下是基于公式的手動實現(Python + NumPy):
步驟1:構造系數矩陣 $ A $
def triangulate_point(P1, P2, pt1, pt2):"""P1, P2: 3x4 投影矩陣pt1, pt2: 匹配的二維點 (u, v)"""u1, v1 = pt1u2, v2 = pt2# 構造矩陣A的每一行row1 = u1 * P1[2, :] - P1[0, :] # u * P1[2] - P1[0]row2 = v1 * P1[2, :] - P1[1, :] # v * P1[2] - P1[1]row3 = u2 * P2[2, :] - P2[0, :] # u' * P2[2] - P2[0]row4 = v2 * P2[2, :] - P2[1, :] # v' * P2[2] - P2[1]A = np.vstack([row1, row2, row3, row4])return A
步驟2:SVD分解求解最小二乘解
def solve_svd(A):# 奇異值分解U, S, Vt = np.linalg.svd(A)# V的最后一列對應最小奇異值的解X = Vt[-1, :]# 歸一化齊次坐標X = X / X[3]return X[:3] # 返回三維坐標 (X, Y, Z)