三角化

三角化

向量叉乘向矩陣運算轉換

a×b=a^b=[0a3a2a30a1a2a10][b1b2b3]a \times b=\hat ab= \begin{bmatrix} 0 & -a_3 & a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{bmatrix} \begin{bmatrix} b_1 \\ b_2 \\ b_3 \end{bmatrix}
其中,a^\hat a表示向量aa對應的反對稱矩陣。

三角化推導

已知三維空間點在世界座標系下的齊次座標:
X=[xyz1]X= \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}
世界座標系到相機座標系的變換:
T=[RT]=[r1r2r3]T=\begin{bmatrix} R & T \end{bmatrix}=\begin{bmatrix} r_1 \\ r_2 \\ r_3 \end{bmatrix}
xx爲相機歸一化平面座標:
x=[uv1]x=\begin{bmatrix} u \\ v \\ 1 \end{bmatrix}
λ\lambda爲深度值,已知以上條件有:
λx=TXλx×TX=0x^TX=0\lambda x = TX \Rightarrow \lambda x \times TX = 0 \Rightarrow \hat x TX = 0
展開上式得:
x^TX=[01v10uvu0][r1r2r3]X=[r2+vr3r1ur3vr1+ur2]X\hat x T X = \begin{bmatrix} 0 & -1 & v \\ 1 & 0 & -u \\ -v & u & 0 \end{bmatrix} \begin{bmatrix} r_1 \\ r_2 \\ r_3 \end{bmatrix} X = \begin{bmatrix} -r_2 + vr_3 \\ r_1 - ur_3 \\ -vr_1 + ur_2 \end{bmatrix} X
其中:
[r2+vr3r1ur3vr1+ur2]\begin{bmatrix} -r_2 + vr_3 \\ r_1 - ur_3 \\ -vr_1 + ur_2 \end{bmatrix}
第一行 ×(u)\times (-u),第二行 ×(v)\times(-v) ,再相加,即可得到第三行,因此,其線性相關,保留前兩行即可,有
[r2+vr3r1ur3]X=0\begin{bmatrix} -r_2 + vr_3 \\ r_1 - ur_3 \end{bmatrix}X = 0
因此,已知一個歸一化平面座標xx和變換矩陣TT可以構建兩個關於XX的線性方程組。有兩個以上的圖像觀測即可求出XX
[r2(1)+v(1)r3(1)r1(1)u(1)r3(1)r2(2)+v(2)r3(2)r1(2)u(2)r3(2)]X=0\begin{bmatrix} -r_2^{\left( 1\right)} + v^{\left(1\right)} r_3^{\left(1\right)}\\ r_1^{\left(1\right)} - u^{\left(1\right)}r_3^{\left(1\right)} \\ -r_2^{\left( 2\right)} + v^{\left(2\right)} r_3^{\left(2\right)}\\ r_1^{\left(2\right)} - u^{\left(2\right)}r_3^{\left(2\right)} \\ \vdots \end{bmatrix}X=0
上式方程沒有非零解,使用SVD求最小二乘解,解可能不滿足齊次座標形式(第四個元素爲1),因此
X=[xyz1]=[x0/x3x1/x3x2/x3x3/x3]X=\begin{bmatrix} x \\ y \\ z \\ 1\end{bmatrix} = \begin{bmatrix} x_0 / x_3 \\ x_1 / x_3 \\ x_2 / x_3 \\ x_3 / x_3 \end{bmatrix}

代碼:

void GlobalSFM::triangulatePoint(Eigen::Matrix<double, 3, 4> &Pose0, Eigen::Matrix<double, 3, 4> &Pose1,
Vector2d &point0, Vector2d &point1, Vector3d &point_3d)
{
    Matrix4d design_matrix = Matrix4d::Zero();
    design_matrix.row(0) = point0[0] * Pose0.row(2) - Pose0.row(0);
    design_matrix.row(1) = point0[1] * Pose0.row(2) - Pose0.row(1);
    design_matrix.row(2) = point1[0] * Pose1.row(2) - Pose1.row(0);
    design_matrix.row(3) = point1[1] * Pose1.row(2) - Pose1.row(1);
    Vector4d triangulated_point;
    triangulated_point =
        design_matrix.jacobiSvd(Eigen::ComputeFullV).matrixV().rightCols<1>();
    point_3d(0) = triangulated_point(0) / triangulated_point(3);
    point_3d(1) = triangulated_point(1) / triangulated_point(3);
    point_3d(2) = triangulated_point(2) / triangulated_point(3);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章