Triangulation: Triangulation: Why Optimize?

Reference:

  1. GitHub:openMVG
  2. Triangulation: Why Optimize?

1. Preliminary knowledge

insert image description here

  • vector v \mathbf{v}Euclidean norm of v : ∥ v ∥ \| \mathbf{v}\|v
  • 单音島地:v ^ = v / ∥ v ∥ \hat{\mathbf{v}} =\mathbf{v}/ \| \mathbf{v}\|v^=v/∥v
  • Two lines L 0 \mathbf{L_0}L0 L 1 \mathbf{L_1} L1Angle: ∠ ( L 0 , L 1 ) ∈ [ 0 , π / 2 ] \angle(\mathbf{L}_0,\mathbf{L}_1)\in[0,\pi/2](L0,L1)[0,π /2 ]
  • 定义 x 0 = [ x 0 , y 0 , z 0 ] T \mathbf{x_0}=[x_0, y_0, z_0]^T x0=[x0,y0,z0]T x 1 = [ x 1 , y 1 , z 1 ] T \mathbf{x_1}=[x_1, y_1, z_1]^T x1=[x1,y1,z1]T is the camera reference frameC 0 C_0C0and C 1 C_1C1three-dimensional coordinates;
  • R\mathbf{R}R t \mathbf{t} t is the rotation and displacement between the two cameras, thenx 1 = R x 0 + t \mathbf{x}_1=\mathbf{R}\mathbf{x}_0+\mathbf{t}x1=Rx0+t
  • Camera calibration matrix: K \mathbf{K}K
  • The second pixel coordinates observed at each frame point: u 0 = ( u 0 , v 0 , 1 ) ⊺ \mathbf{u}_{0}=(u_{0},v_{0},1)^{\intercal }u0=(u0,v0,1) u 1 = ( u 1 , v 1 , 1 ) ⊺ \mathbf{u}_{1}=(u_{1},v_{1},1)^{\intercal} u1=(u1,v1,1)
  • Normalized image coordinates: f 0 = [ x 0 / z 0 , y 0 / z 0 , 1 ] T \mathbf{f_{0}}=\left[x_{0}/z_{0},y_{0 }/z_{0},1\right]^{T}f0=[x0/z0,y0/z0,1]T f 1 = [ x 1 / z 1 , y 1 / z 1 , 1 ] T \mathbf{f_{1}}=\left[x_{1}/z_{1},y_{1}/z_{1},1\right]^{T} f1=[x1/z1,y1/z1,1]T , respectivelyf 0 = K − 1 u 0 \mathbf{f}_0=\mathbf{K}^{-1}\mathbf{u}_0f0=K1 u0f 1 = K − 1 u 1 \mathbf{f}_1=\mathbf{K}^{-1}\mathbf{u}_1f1=K1 u1get;
  • In the ideal case of Fig.1a, two back-projected rays intersect, satisfying the epipolar constraint: f 1 ⋅ ( t × R f 0 ) = 0 \mathbf{f}_1\cdot(\mathbf{t}\ times\mathbf{Rf}_0)=0f1(t×Rf0)=0 (Exercise P167, x 2 T t ∧ R x 1 = 0 \mathbf{x_2}^Tt^{\wedge}\mathbf{R}\mathbf{x_1}=0x2TtRx1=0);
  • Given the depth scalar λ 0 \lambda_0 of the above figurel0and λ 1 \lambda_1l1, intersection point x 1 \mathbf{x_1}x1Default: x 1 = λ 0 R f 0 ^ + t \begin{aligned}\mathbf{x}_{1}& =\lambda_0\mathbf{R}\mathbf{\hat{f_0}}+\mathbf {t} \end{aligned}x1=l0Rf0^+tx 1 = λ 1 f 1 ^ \begin{aligned}\mathbf{x}_{1}& =\lambda_1\mathbf{\hat{f_1}}\end{aligned}x1=l1f1^。( f 0 ^ \mathbf{\hat{f_0}}f0^f 1 ^ \mathbf{\hat{f_1}}f1^Ideally, this rarely happens due to inaccuracies in image measurements and camera models. To infer a 3D point from two oblique rays leads to the following method );

1.1 Evaluating 3D point accuracy

Once the 3D point x 1 ′ \mathbf{x}_{1}' is obtained using some triangulation methodx1, its accuracy can be assessed in a number of ways:

  1. Calculate the 3D error, that is: e 3 D = ∥ x 1 ′ − xtrue ∥ e_{3D}=\|\mathbf{x}_1^\prime-\mathbf{x}_{\mathrm{true}}\|e3D _=x1xtrue (see Fig.1b);
  2. 计算 2D 误差,也就是重投影误差:
    d i = ∥ K ( f i − f i ′ ) ∥ = ∥ K ( f i − ( [ 0   0   1 ] x i ′ ) − 1 x i ′ ) ∥ for i = 0 , 1 ( 1 ) d_i=\|\mathbf{K}\left(\mathbf{f}_i-\mathbf{f}_i'\right)\|=\left\|\mathbf{K}\left(\mathbf{f}_i-\left(\left[\mathbf{0}\text{ }\mathbf{0}\text{ }\mathbf{1}\right]\mathbf{x}_i'\right)^{-1}\mathbf{x}_i'\right)\right\|\quad\text{for}\quad i=0,1 \quad(1) di=K(fifi)= K(fi([0 0 1]xi)1xi) fori=0,1( 1 ) Ifx 0 ′ = R ⊺ ( x 1 ′ − t ) \mathbf{x}'_0=\mathbf{R}^\intercal(\mathbf{x}'_1-\mathbf{t})x0=R(x1t)。这里 ( [ 0   0   1 ] x i ′ ) − 1 \left(\left[\mathbf{0}\text{ }\mathbf{0}\text{ }\mathbf{1}\right]\mathbf{x}_i'\right)^{-1} ([0 0 1]xi)1 seekszzThe inverse of the z- axis coordinates, multiplied byx 1 ′ \mathbf{x}'_1x1Normalized plane coordinates are available ( see Fig.1b );
    2D errors represent deviations from measurements, while 3D errors represent deviations from true values. Unlike 3D errors, 2D errors for 3D points can be evaluated under different norms, such as:
    • L1 L_1L1Norm: d 0 + d 1 d_0+d_1d0+d1
    • L 2 L_2L2Norm: d 0 2 + d 1 2 \sqrt{d_0^2+d_1^2}d02+d12
    • L ∞ L_\inftyLNorm: max ⁡ ( d 0 , d 1 ) \max(d_0,d_1)max(d0,d1)
  3. In addition to 2D and 3D accuracy, the obtained parallax angle accuracy can also be evaluated ( see Fig.1c ), and the parallax error is defined as follows ( the expression here feels a bit confused, xtrue \mathbf{x}_{\mathrm{true}}xtrueIt should be C 1 C_1C1xtrue \mathbf{x}_{\mathrm{true}}xtrueThe straight line of xtrue − t \mathbf{x}_{\mathrm{true}}-\mathbf{t}xtruet isC 0 C_0C0xtrue \mathbf{x}_{\mathrm{true}}xtrueDefinition :
    e β = ∣ β true − β ′ ∣ = ∣ ∠ ( xtrue , xtrue − t ) − ∠ ( x 1 ′ , x 1 ′ − t ) ∣ ( 2 ) e_{\beta}=|\beta_ {\mathrm{true}}-\beta'|=|\angle\left(\mathbf{x}_{\mathrm{true}},\mathbf{x}_{\mathrm{true}}-\mathbf{ t}\right)-\angle\left(\mathbf{x}'_1,\mathbf{x}'_1-\mathbf{t}\right)| \quad(2)eb=βtrueb=∣∠(xtrue,xtruet)(x1,x1t)( 2 ) Define "raw parallax" as the angle between raw backprojected rays:
    β raw = ∠ ( R f 0 , f 1 ) . ( 3 ) \beta_{\mathrm{raw}}=\angle\left( \mathbf{Rf}_0,\mathbf{f}_1\right). \quad(3)braw=(Rf0,f1).( 3 ) This gives a rough estimate of the disparity angle independent of translation and triangulation methods.

2. Proposed method

2.1 Generalized weighted midpoint method

The generalized weighted midpoint method Generalized Weighted Midpoint (GWM)consists the following three steps:

  1. Given two backprojected rays corresponding to the same point, use some method to estimate the two rays (λ 0 , λ 1 ) (\lambda_0, \lambda_1)( l0,l1) depth;
  2. Calculate the depth of these two lines as λ 0 \lambda_0l0and λ 1 \lambda_1l1The 3D point of the ray, that is, at C 1 C_1C1frame t + λ 0 R f 0 ^ \mathbf{t} + \lambda_0\mathbf{R}\mathbf{\hat{f_0}}t+l0Rf0^λ 1 f 1 ^ \lambda_1\mathbf{\hat{f_1}}l1f1^
  3. The final estimate of the 3D points is obtained by computing their weighted average.

In the previous classic midpoint method, the two points of each ray are the closest pair of points with the same weight. Yet another possible example of a generalized weighted midpoint is shown in the figure below:
insert image description here

2.2 Optional Midpoint Method

An optional midpoint method belonging to GWM is proposed here. Consider first the case where two backprojections happen to intersect, as in Fig.1a. In this case, the most reasonable solution is the intersection, and the corresponding depth along the ray can be obtained using the sine rule:
λ 0 = sin ⁡ ( ∠ ( f 1 , t ) ) sin ⁡ ( ∠ ( R f 0 , f 1 , ) ) ∥ t ∥ = ∥ f ^ 1 × t ∥ ∥ R f ^ 0 × f ^ 1 ∥ , λ 1 = sin ⁡ ( ∠ ( R f 0 , t ) ) sin ⁡ ( ∠ ( R f 0 , f 1 , ) ) ∥ t ∥ = ∥ R f ^ 0 × t ∥ ∥ R f ^ 0 × f ^ 1 ∥ . ( 4 ) \lambda_0=\frac{\sin\left(\angle\left(\mathbf{f}_1,\mathbf{t}\right)\right)}{\sin\left(\angle\left(\mathbf{R}\mathbf{f}_0,\mathbf{f}_1,\right)\right)}\|\mathbf{t}\|=\frac{\|\hat{\mathbf{f}}_1\times\mathbf{t}\|}{\|\mathbf{R}\hat{\mathbf{f}}_0\times\hat{\mathbf{f}}_1\|},\quad\lambda_1=\frac{\sin\left(\angle\left(\mathbf{R}\mathbf{f}_0,\mathbf{t}\right)\right)}{\sin\left(\angle\left(\mathbf{R}\mathbf{f}_0,\mathbf{f}_1,\right)\right)}\|\mathbf{t}\|=\frac{\|\mathbf{R}\hat{\mathbf{f}}_0\times\mathbf{t}\|}{\|\mathbf{R}\hat{\mathbf{f}}_0\times\hat{\mathbf{f}}_1\|}. \quad(4) l0=sin((Rf0,f1,))sin((f1,t))t=Rf^0×f^1f^1×t,l1=sin((Rf0,f1,))sin((Rf0,t))t=Rf^0×f^1Rf^0×t.( 4 ) When the two rays are oblique, the formula is also used to estimate the depth. Calculate the depth λ 0 \lambda_0of the 3D point on each ray separatelyl0and λ 1 \lambda_1l1,得:
t + λ 0 R f ^ 0 = t + ∥ f 1 × t ∥ ∥ R f 0 × f 1 ∥ R f 0 and λ 1 f 1 ^ = ∥ R f 0 × t ∥ ∥ R f 0 × f 1 ∥ f 1 ( 5 ) \mathbf{t}+\lambda_0\mathbf{R}\hat{\mathbf{f}}_0=\mathbf{t}+\frac{\|\mathbf{f}_1\ times\mathbf{t}\|}{\|\mathbf{Rf}_0\times\mathbf{f}_1\|}\mathbf{Rf}_0\quad\text{and}\quad\lambda_1\hat{\ mathbf{f_1}}=\frac{\|\mathbf{Rf}_0\times\mathbf{t}\|}{\|\mathbf{Rf}_0\times\mathbf{f}_1\|}\mathbf{ f}_1 \quad(5)t+l0Rf^0=t+Rf0×f1f1×tRf0andl1f1^=Rf0×f1Rf0×tf1( 5 ) Take the two points of the 中点有:
x 1 ′ = 1 2 ( t + ∥ f 1 × t ∥ ∥ R f 0 × f 1 ∥ R f 0 + ∥ R f 0 × t ∥ ∥ R f 0 × f 1 ∥ f 1 ). ( 6 ) \mathbf{x}_1'=\frac{1}{2}\left(\mathbf{t}+\frac{\|\mathbf{f}_1\times\mathbf{t}\|}{ \|\mathbf{R}\mathbf{f}_0\times\mathbf{f}_1\|}\mathbf{R}\mathbf{f}_0+\frac{\|\mathbf{R}\mathbf{f} _0\times\mathbf{t}\|}{\|\mathbf{R}\mathbf{f}_0\times\mathbf{f}_1\|}\mathbf{f}_1\right). (6)x1=21(t+Rf0×f1f1×tRf0+Rf0×f1Rf0×tf1).( 6 )p = R f ^ 0 × f ^ 1 \mathbf p=\mathbf R\hat{\mathbf f}_0\times\hat{\mathbf f}_1p=Rf^0×f^1, q = R f ^ 0 × t \mathbf q=\mathbf R\hat{\mathbf f}_0\times\mathbf tq=Rf^0×t er= f ^ 1 × t \mathbf r=\hat{\mathbf f}_1\times\mathbf tr=f^1×t , the depth formula can be replaced by:
λ 0 = ∣ ∣ r ∣ ∣ ∣ ∣ p ∣ ∣ , λ 1 = ∣ ∣ q ∣ ∣ ∣ ∣ p ∣ ∣ ( 7 ) \lambda_{0}={\frac{|| \mathbf{r}||}{||\mathbf{p}||}},\quad\lambda_{1}={\frac{||\mathbf{q}||}{||\mathbf{p }||}} \quad(7)l0=∣∣p∣∣∣∣r∣∣,l1=∣∣p∣∣∣∣q∣∣( 7 ) These forms are similar to the depths given by the classic midpoint method before:
λ mid 0 = p ^ ⋅ r ∥ p ∥ , λ mid 1 = p ^ ⋅ q ∥ p ∥ . ( 8 ) \lambda_{\text {mid}0}=\frac{\hat{\mathbf{p}}\cdot\mathbf{r}}{\|\mathbf{p}\|},\quad\lambda_{\text{mid}1} =\frac{\hat{\mathbf{p}}\cdot\mathbf{q}}{\|\mathbf{p}\|}. \quad(8)lmid0=pp^r,lmid1=pp^q.( 8 ) The difference between these two formulas is the molecule,equ.7has sizer \mathbf{r}rq\mathbf{q}q , andequ.8projects them ontop \mathbf{p}on p . Therefore, we always getλ 0 ≥ λ mid 0 \lambda_0\geq \lambda_{\text{mid}0}l0lmid0λ 1 ≥ λ mid 1 \lambda_1\geq \lambda _ {\text{mid}1}l1lmid1. In most cases, this means that the midpoint obtained by this method will be further away than the classical midpoint. In the example depicted in Fig.2, when we estimate a point far from the camera, it usually (traditional triangulation method) results in a smaller estimated disparity angle.

2.3 Cheirality (positive field depth constraints representing 3D points in multi-view geometry)

insert image description hereThe positive depth constraint of a 3D point is violated when the triangulated point has a negative depth. This can happen for a number of reasons, such as wrong correlation of point pairs or noisy image points near poles. Usually it doesn't cause serious problems, since it's easy to check the positive depth of field at each point and discard bad ones. For the classical midpoint method, this can be confirmed by checking the sign of depth given by equ.8 . But this cannot be confirmed for the method given in this paper, because the given depth is always positive. The figure above illustrates the difference between the two methods. Therefore, in this method, the depth alone cannot tell whether the triangulation result is reliable or not.

At this time, you need to use other methods to test whether the point is a bad point (it is a bad point if the following inequality is satisfied ): If changing the sign of at least one depth to negative will cause the distance between two points on the light to become smaller, discard the corresponding point Relation:
∥ t + λ 0 R f 0 ^ − λ 1 f ^ 1 ∥ 2 ≥ min ⁡ ( ∥ t + λ 0 R f 0 ^ + λ 1 f 1 ^ ∥ 2 , ∥ t − λ 0 R f 0 ^ − λ 1 f ^ 1 ∥ 2 , ∥ t − λ 0 R f 0 ^ + λ 1 f 1 ^ ∥ 2 ) ( 9 ) \|\mathbf{t}+\lambda_0\mathbf{R}\hat{\mathbf {f_0}}-\lambda_1\hat{\mathbf{f}}_1\|^2\geq\min\left(\|\mathbf{t}+\lambda_0\mathbf{R}\hat{\mathbf{f_0 }}+\lambda_1\hat{\mathbf{f_1}}\|^2,\|\mathbf{t}-\lambda_0\mathbf{R}\hat{\mathbf{f_0}}-\lambda_1\hat{\ mathbf{f}}_1\|^2,\|\mathbf{t}-\lambda_0\mathbf{R}\hat{\mathbf{f_0}}+\lambda_1\hat{\mathbf{f_1}}\|^ 2\right)\quad(9)t+l0Rf0^l1f^12min(t+l0Rf0^+l1f1^2,tl0Rf0^l1f^12,tl0Rf0^+l1f1^2)( 9 ) For the classic midpoint method, letλ 0 = ∣ λ mid 0 ∣ \lambda_0=|\lambda_{mid0}|l0=λmid0λ 1 = ∣ λ mid 1 ∣ \lambda_1=|\lambda_{mid1}|l1=λmid1 can effectively get the same result as testing the positive depth of field constraint (obviously, it is to verify whether this number is greater than zero). And the current method is established inequ.9and Fig.3a, because whenλ 0 = − ∣ λ mid 0 ∣ \lambda_0=-|\lambda_{mid0}|l0=λmid0λ 1 = − ∣ λ mid 1 ∣ \lambda_1=-|\lambda_{mid1}|l1=λmid1 when the two points are closest.

2.4 Inverse Depth Weighted (IDW) Midpoint

The weighted midpoint given by equ . 6 usually results in a disproportionate reprojection error of the two images, and Fig. 3c gives an example. Note that rays with smaller depths tend to have larger reprojection errors. To compensate for this imbalance, the paper proposes to use the inverse depth as the weight:
x 1 ′ = λ 0 − 1 ( t + λ 0 R f 0 ^ ) + λ 1 − 1 ( λ 1 k 1 ^ ) λ 0 − 1 + λ 1 − 1 = ∥ q ∥ ∥ q ∥ + ∥ r ∥ ( t + ∥ r ∥ ∥ p ∥ ( kf 0 ^ + f 1 ^ ) ) ( 10 ) \mathbf{x}_1'=\frac{\lambda_0 ^{-1}\left(\mathbf{t}+\lambda_0\mathbf{R}\hat{\mathbf{f_0}}\right)+\lambda_1^{-1}\left(\lambda_1\hat{\ mathbf{k_1}}\right)}{\lambda_0^{-1}+\lambda_1^{-1}}=\frac{\|\mathbf{q}\|}{\|\mathbf{q}\| +\|\mathbf{r}\|}\left(\mathbf{t}+\frac{\|\mathbf{r}\|}{\|\mathbf{p}\|}\left(\mathbf{ k}\hat{\mathbf{f_0}}+\hat{\mathbf{f_1}}\right)\right)\quad(10)x1=l01+l11l01(t+l0Rf0^)+l11( l1k1^)=q+rq(t+pr(kf0^+f1^))(10)

3. Implement the code

// Helper function
// Compute Relative motion between two absolute poses parameterized by Rt
// Rotate one bearing vector according to the relative motion
inline void AbsoluteToRelative(const Mat3 &R0, const Vec3 &t0, const Mat3 &R1, const Vec3 &t1, const Vec3 &x0, Mat3 &R, Vec3 &t, Vec3 &Rx0)
{
    
    
  R = R1 * R0.transpose();
  t = t1 - R * t0;
  Rx0 = R * x0;
}

bool TriangulateIDWMidpoint(const Mat3 & R0, const Vec3 & t0, const Vec3 & x0, const Mat3 & R1, const Vec3 & t1, const Vec3 & x1, Vec3* X_euclidean)
{
    
    
  // absolute to relative
  Mat3 R;
  Vec3 t, Rx0;
  AbsoluteToRelative(R0, t0, R1, t1, x0, R, t, Rx0);

  const double p_norm = Rx0.cross(x1).norm();
  const double q_norm = Rx0.cross(t).norm();
  const double r_norm = x1.cross(t).norm();

  // Eq. (10)
  const auto xprime1 = ( q_norm / (q_norm + r_norm) )
    * ( t + (r_norm / p_norm) * (Rx0 + x1) );

  // relative to absolute
  *X_euclidean = R1.transpose() * (xprime1 - t1);

  // Eq. (7)
  const Vec3 lambda0_Rx0 = (r_norm / p_norm) * Rx0;
  const Vec3 lambda1_x1 = (q_norm / p_norm) * x1;

  // Eq. (9) - test adequation
  return (t + lambda0_Rx0 - lambda1_x1).squaredNorm()
    <
    std::min(std::min(
      (t + lambda0_Rx0 + lambda1_x1).squaredNorm(),
      (t - lambda0_Rx0 - lambda1_x1).squaredNorm()),
      (t - lambda0_Rx0 + lambda1_x1).squaredNorm());
}

Guess you like

Origin blog.csdn.net/qq_28087491/article/details/130834660