三角測量: 三角測量: なぜ最適化するのか?

参照:

  1. GitHub:openMVG
  2. 三角測量: なぜ最適化するのか?

1. 予備知識

ここに画像の説明を挿入

  • ベクトルv \mathbf{v}vのユークリッド ノルム∥ v ∥ \| \mathbf{v}\|v
  • 单音島地:v ^ = v / ∥ v ∥ \hat{\mathbf{v}} =\mathbf{v}/ \| \mathbf{v}\|v^=v /∥ v
  • 2 行L 0 \mathbf{L_0}L0L 1 \mathbf{L_1}L1角度: ∠ ( L 0 , L 1 ) ∈ [ 0 , π / 2 ] \angle(\mathbf{L}_0,\mathbf{L}_1)\in[0,\pi/2]( L0L1)[ 0 ,π /2 ]
  • 定义x 0 = [ x 0 , y 0 , z 0 ] T \mathbf{x_0}=[x_0, y_0, z_0]^Tバツ0=[ ×0y0z0Tx 1 = [ x 1 , y 1 , z 1 ] T \mathbf{x_1}=[x_1, y_1, z_1]^Tバツ1=[ ×1y1z1Tはカメラの基準フレームC 0 C_0C0C1C_1C1三次元座標。
  • R\mathbf{R}Rt \mathbf{t}tは 2 台のカメラ間の回転と変位であり、x 1 = R x 0 + t \mathbf{x}_1=\mathbf{R}\mathbf{x}_0+\mathbf{t} となります。バツ1=R ×0+
  • カメラ キャリブレーション マトリックス: K \mathbf{K}
  • 各フレーム点で観測される 2 番目のピクセル座標: u 0 = ( u 0 , v 0 , 1 ) ⊺ \mathbf{u}_{0}=(u_{0},v_{0},1)^{\intercal }あなた0=(あなた0v01 )u 1 = ( u 1 , v 1 , 1 ) ⊺ \mathbf{u}_{1}=(u_{1},v_{1},1)^{\intercal}あなた1=(あなた1v11 )
  • 正規化された画像座標: 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=[ ×0/ z0y0/ z01 ]Tf 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=[ ×1/ z1y1/ z11 ]T、それぞれf 0 = K − 1 u 0 \mathbf{f}_0=\mathbf{K}^{-1}\mathbf{u}_0f0=K1u _0f 1 = K − 1 u 1 \mathbf{f}_1=\mathbf{K}^{-1}\mathbf{u}_1f1=K1u _1得る;
  • 図 1a の理想的なケースでは、2 つの逆投影光線が交差し、エピポーラ制約を満たします: f 1 ⋅ ( t × R f 0 ) = 0 \mathbf{f}_1\cdot(\mathbf{t}\ 回\ mathbf{Rf}_0)=0f1( t×RF0)=0 (演習 P167、 x 2 T t ∧ R x 1 = 0 \mathbf{x_2}^Tt^{\wedge}\mathbf{R}\mathbf{x_1}=0バツ2tt _ Rx_1=0);
  • 上図の深さスカラーλ 0 \lambda_0を考えると、0λ 1 \lambda_11、交点x 1 \mathbf{x_1}バツ1デフォルト: x 1 = λ 0 R f 0 ^ + t \begin{aligned}\mathbf{x}_{1}& =\lambda_0\mathbf{R}\mathbf{\hat{f_0}}+\mathbf {t \end{整列}バツ1=0Rf0^+x 1 = λ 1 f 1 ^ \begin{aligned}\mathbf{x}_{1}& =\lambda_1\mathbf{\hat{f_1}}\end{aligned}バツ1=1f1^( f 0 ^ \mathbf{\hat{f_0}}f0^f 1 ^ \mathbf{\hat{f_1}}f1^理想的には、画像測定やカメラのモデルの不正確さが原因でこのようなことが起こることはほとんどありません。2 本の斜光線から 3D 点を推測するには、次の方法が導き出されます)。

1.1 3D 点精度の評価

何らかの三角測量法を使用して3D 点x 1 ' \mathbf{x}_{1}' が取得されると、バツ1、その精度はさまざまな方法で評価できます。

  1. 3D 誤差を計算します。つまり、e 3 D = ∥ x 1 ′ − xtrue ∥ e_{3D}=\|\mathbf{x}_1^\prime-\mathbf{x}_{\mathrm{true}}\ |e3D_ _=×1バツ本当 (図1bを参照);
  2. 2D 評価差、つまり再投影評価差の計算:
    di = ∥ K ( fi − fi ' ) ∥ = ∥ K ( fi − ( [ 0 0 1 ] xi ’ ) − 1 xi ’ ) ∥ (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)d私は=∥K _( f私はf)= K( f私は( [ 0 0 1 ]  バツ)1バツ) ために=0 1( 1 )インデックスx 0 ' = R ⊺ ( x 1 ' − t ) \mathbf{x}'_0=\mathbf{R}^\intercal(\mathbf{x}'_1-\mathbf{t})バツ0=R (×1ここ( [ 0 0 1 ] xi ' ) − 1 \left(\left[\mathbf{0}\ text { }\mathbf{0} \ text{ }\mathbf{1}\right]\mathbf{ x}_i'\right)^{-1}( [ 0 0 1 ]  バツ)1 zzをシークしますZ軸座標の逆数、 x 1 ' \mathbf{x}'_1を乗算したものバツ1正規化された平面座標が利用可能です (図 1b を参照)。2D
    誤差は測定値からの偏差を表し、3D 誤差は真の値からの偏差を表します。3D エラーとは異なり、3D ポイントの 2D エラーは、次のようなさまざまな基準に基づいて評価できます。
    • L1 L_1L1ノルム: d 0 + d 1 d_0+d_1d0+d1
    • L 2 L_2L2ノルム: d 0 2 + d 1 2 \sqrt{d_0^2+d_1^2}d02+d12
    • L ∞ L_\inftyLノルム: max ⁡ ( d 0 , d 1 ) \max(d_0,d_1)最大( d0d1
  3. 2D と 3D の精度に加えて、得られた視差角度の精度も評価でき (図 1c を参照)、視差誤差は次のように定義されます (ここでの表現は少し混乱しています。xtrue \mathbf{x}_{\ mathrm{true}}バツ本当C 1 C_1である必要がありますC1xtrue \mathbf{x}_{\mathrm{true}}バツ本当xtrueの直線− t \mathbf{x}_{\mathrm{true}}-\mathbf{t}バツ本当tはC0C_0ですC0xtrue \mathbf{x}_{\mathrm{true}}バツ本当定義:
    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)| \クアッド(2)eb=β本当b _=∣∠( ×本当バツ本当t )( ×1バツ1t )( 2 )「生の視差」を生の逆投影光線間の角度として定義します:
    β raw = ∠ ( R f 0 , f 1 ) . ( 3 ) \beta_{\mathrm{raw}}=\angle\left( \mathbf{ Rf}_0,\mathbf{f}_1\right). \quad(3)b=( Rf0f1)( 3 )これにより、平行移動や三角測量の方法に関係なく、視差角の大まかな推定値が得られます。

2. 提案手法

2.1 一般化された加重中点法

一般化された加重中点法は、次の 3 つのステップでGeneralized Weighted Midpoint (GWM)構成されます。

  1. 同じ点に対応する 2 つの逆投影光線が与えられた場合、何らかの方法を使用して 2 つの光線(λ 0 , λ 1 ) (\lambda_0, \lambda_1)を推定します。( l01深さ。
  2. これら 2 つの線の深さをλ 0 \lambda_0として計算します。0λ 1 \lambda_11光線の 3D 点、つまりC 1 C_1にあります。C1フレームt + λ 0 R f 0 ^ \mathbf{t} + \lambda_0\mathbf{R}\mathbf{\hat{f_0}}t+0Rf0^及びλ 1 f 1 ^ \lambda_1\mathbf{\hat{f_1}}1f1^
  3. 3D ポイントの最終推定値は、加重平均を計算することによって取得されます。

以前の古典的な中点法では、各光線の 2 つの点は、同じ重みを持つ最も近い点のペアです。一般化された加重中点のさらに別の考えられる例を、以下の図に示します。
ここに画像の説明を挿入

2.2 オプションの中点法

ここでは、GWM に属するオプションの中点法を提案します。まず、図 1a のように、2 つの逆投影が偶然交差する場合を考えてみましょう。この場合、最も合理的な解決策は交差であり、光線に沿った対応する深度は正弦則を使用して取得できます。
λ 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\|}。\クアッド(4)0=( ( R f0f1) )( ( f1t ) )_=∥R _f^0×f^1f^1× _1=( ( R f0f1) )( ( R f0t ) )_=∥R _f^0×f^1∥R _f^0× _( 4 ) 2 つの光線が斜めである場合、この式は深度の推定にも使用されます。各光線上の 3D 点のλ 0 \lambda_00λ 1 \lambda_11,得:
t + λ 0 R f ^ 0 = t + ∥ f 1 × t ∥ ∥ R f 0 × f 1 ∥ R f 0 と λ 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\回\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 \クアッド(5)t+0Rf^0=t+Rf0×f1f1× _RF01f1^=Rf0×f1Rf0× _f1( 5 )中点の 2 点を取ります:
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)バツ1=21( t+R f0×f1f1× _Rf _0+R f0×f1R f0× _f1)( 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 の場合、深さの式は次のように置き換えることができます:
λ 0 = ∣ ∣ r ∣ ∣ ∣ ∣ p ∣ ∣ , λ 1 = ∣ ∣ q ∣ ∣ ∣ ∣ ∣ p ∣ ∣ ( 7 ) \lambda_{0}={\frac {|| \mathbf{r}||}{||\mathbf{p}||}}、\quad\lambda_{1}={\frac{||\mathbf{q}||}{||\ mathbf{p }||}} \quad(7)0=∣∣ p ∣∣∣∣ r ∣∣1=∣∣ p ∣∣∣∣ q ∣∣( 7 )これらの形式は、以前の古典的な中点法によって与えられる深さに似ています:
λ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)ミッド0=p p^rミッド1=p p^q( 8 )これら 2 つの式の違いは分子です。式 7のサイズはr \mathbf{r}rq\mathbf{q}q、およびequ.8 はp \mathbf{p}に投影します。ページしたがって、常にλ 0 ≥ λmid 0 \lambda_0\geq \lambda_{\text{mid}0} が0ミッド0λ 1 ≧ λ ミッド 1 \lambda_1\geq \lambda_{\text{mid}1 }1ミッド1ほとんどの場合、これは、この方法で取得された中点が従来の中点よりも遠くになることを意味します。図 2 に示す例では、カメラから遠い点を推定すると、通常 (従来の三角測量法) 推定視差角が小さくなります。

2.3 キラリティ (マルチビュー ジオメトリの 3D 点を表す正のフィールド深度制約)

ここに画像の説明を挿入三角形化された点の深さが負の場合、3D 点の正の深さの制約に違反します。これは、点のペアの誤った相関や、極近くのノイズの多い画像点など、さまざまな理由で発生する可能性があります。各ポイントで適切な被写界深度をチェックし、悪いものを破棄するのは簡単なので、通常は深刻な問題は発生しません。古典的な中点法の場合、これは、equ.8で与えられる深さの符号をチェックすることで確認できます。しかし、この論文で与えられた方法では、与えられた深さが常に正であるため、これを確認することはできません。上の図は、2 つの方法の違いを示しています。したがって、この方法では、深さだけでは三角測量の結果が信頼できるかどうかを判断できません。

現時点では、他の方法を使用して、その点が不良ポイントであるかどうかをテストする必要があります (次の不等式が満たされる場合は不良ポイントです):少なくとも 1 つの深さの符号を負に変更すると、2 つの深さの間の距離が変化する場合関係:
∥ 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 _+0Rf0^1f^12( ∥t _+0Rf0^+1f1^2∥t _0Rf0^1f^12∥t _0Rf0^+1f1^2 )( 9 )古典的な中点法の場合、λ 0 = ∣ λmid 0 ∣ \lambda_0=|\lambda_{mid0}|0=λ・ド・0λ 1 = ∣ λmid 1 ∣ \lambda_1=|\lambda_{mid1}|1=λミディ1 _∣ は、正の被写界深度制約をテストするのと同じ結果を効果的に得ることができます (明らかに、この数値が 0 より大きいかどうかを検証するためです)。そして、現在の方法は式9と図3aで確立されます。なぜなら、λ 0 = − ∣ λmid 0 ∣ \lambda_0=-|\lambda_{mid0}|0=λ・ド・0及びλ 1 = − ∣ λmid 1 ∣ \lambda_1=-|\lambda_{mid1}|1=λミディ1 _ 2 つの点が最も近いとき。

2.4 逆深度加重 (IDW) 中間点

6で与えられる重み付けされた中点は、通常、2 つの画像の不釣り合いな再投影誤差をもたらしますが、図 3c はその一例です。深さが浅い光線は、再投影誤差が大きくなる傾向があることに注意してください。この不均衡を補償するために、論文では重みとして逆深度を使用することを提案しています:
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)バツ1=0 1+1 10 1( t+0Rf0^)+1 1( l1k1^)=q +r q( t+p r( kf0^+f1^) )( 10 )

3. コードを実装する

// 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());
}

おすすめ

転載: blog.csdn.net/qq_28087491/article/details/130834660