三角化
向量叉乘向矩陣運算轉換
a×b=a^b=⎣⎡0a3−a2−a30a1a2−a10⎦⎤⎣⎡b1b2b3⎦⎤
其中,a^表示向量a對應的反對稱矩陣。
三角化推導
已知三維空間點在世界座標系下的齊次座標:
X=⎣⎢⎢⎡xyz1⎦⎥⎥⎤
世界座標系到相機座標系的變換:
T=[RT]=⎣⎡r1r2r3⎦⎤
x爲相機歸一化平面座標:
x=⎣⎡uv1⎦⎤
λ爲深度值,已知以上條件有:
λx=TX⇒λx×TX=0⇒x^TX=0
展開上式得:
x^TX=⎣⎡01−v−10uv−u0⎦⎤⎣⎡r1r2r3⎦⎤X=⎣⎡−r2+vr3r1−ur3−vr1+ur2⎦⎤X
其中:
⎣⎡−r2+vr3r1−ur3−vr1+ur2⎦⎤
第一行 ×(−u),第二行 ×(−v) ,再相加,即可得到第三行,因此,其線性相關,保留前兩行即可,有
[−r2+vr3r1−ur3]X=0
因此,已知一個歸一化平面座標x和變換矩陣T可以構建兩個關於X的線性方程組。有兩個以上的圖像觀測即可求出X
⎣⎢⎢⎢⎢⎢⎢⎡−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
上式方程沒有非零解,使用SVD求最小二乘解,解可能不滿足齊次座標形式(第四個元素爲1),因此
X=⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡x0/x3x1/x3x2/x3x3/x3⎦⎥⎥⎤
代碼:
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);
}