1

点対応のある 3 つのビューがあり、2 番目と 3 番目のビューでカメラのポーズを計算したいと考えています。したがって、最初のビューに対する 2 番目と 3 番目のビューでのカメラの既知の回転と平行移動を使用して、さまざまなビューのポイントを含むランダム データセット (ノイズなし) を生成します。まず最初のビューでランダムな 2D ポイントを生成し、次にランダムな (正の) 深度を割り当てて対応する 3D ポイントを取得し、最後にランダムに生成された回転と平行移動を使用して、これらの 3D ポイントを 2 番目と 3 番目のビューに投影します。

最初に、3 焦点テンソルを計算します (Hartley & Zisserman、Multiple View Geometry Chapter 15 を参照)。次に、この回答で説明されているアプローチに従って、 2 番目と 3 番目のビューの回転R_iと平行移動を取得しt_iます。

計算では常に正しい回転が得られますが、残念ながら、並進ベクトルの符号は常に正しいとは限りません。t2t3正しいスケールを持っていますが、ランダムに生成された新しいデータセットを使用すると、グラウンドトゥルースの翻訳に対して符号が反転することがあります (!)

グラウンド トゥルース:

R2 = [0.9942   -0.0998    0.0393
      0.1069    0.9541   -0.2798
     -0.0096    0.2823    0.9593]
t2 = [0.4267
      0.3747
      0.3544]
R3 = [0.9764   -0.0626    0.2069
      0.1358    0.9222   -0.3622
      -0.1681    0.3817    0.9089]
t3 = [0.3963
      0.0285
      0.2093]

私のアルゴリズムの出力(翻訳は最大スケールで決定されます):

R2 = [0.994229 -0.0998196  0.0393062
      0.106851   0.954105  -0.279761
     -0.00957664   0.282346   0.959265]
t2 = [-0.637428
      -0.559842
      -0.529398]
R3 = [0.976367 -0.0625748   0.206861
      0.135829    0.92217  -0.362151
      -0.168099    0.38169   0.908876]
t3 = [-0.591991
      -0.0426261
      -0.312637]

グラウンド トゥルースと と の私の出力を比較するとt2t3それらがスケールアップして同一であることがわかります (この例では、符号によって反転されていますt2./t3)。アルゴリズムの利回り:

for ground truth:
[ 1.0768
 13.1338
  1.6933]

for my algorithm:
[ 1.0768
 13.1338
  1.6933]

私の最初の質問は、翻訳ベクトルの符号の不一致の原因は何でしょうか? (特に、そうでなければ結果が正しいという事実を考えると)。

私の2番目の質問は、上記のリンクされた回答のステップ4で与えられたこれらの式はどこから来たのですか? Hartley & Zisserman による「Multiple View Geometry」という本を持っていますが、記載されているアルゴリズムが見つかりませんでした。

上記のリンクのアルゴリズムのステップ 4 の実装のコード スニペットを次に示します ( Eigenライブラリを使用しRます。OpenCV は使用したくありません) 。 -一様な 2D 点対応を表示、、および:tEp1p2p3

getPoseFromEssentialMat(Matrix3d E)
{
  Matrix3d W, U, V;
  W << 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0;

  // calculate the SVD of the essential matrix
  JacobiSVD<MatrixXd> svdE(E, ComputeThinU | ComputeThinV);
  // if det(U) < 0 -> U = -U, if det(V) < 0 -> V = -V
  U = svdE.matrixU();
  if (U.determinant() < 0.0)
  {
    U *= -1.0;
  }
  V = svdE.matrixV();
  if (V.determinant() < 0.0)
  {
    V *= -1.0;
  }

  R = U * W * V.transpose();
  t = U.col(2);

  findCorrectSolution(R, t, W, U, V);
}


findCorrectSolution(Matrix3d& R, Vector3d& t, Matrix3d W, Matrix3d U, Matrix3d V)
{
  MatrixXd P(3, 4); // P = [R | t]
  P.block(0, 0, 3, 3) = R;
  P.col(3) = t;

  Vector3d Rtpt = R.transpose() * t;
  Matrix3d M = crossProductMatrix(Rtpt);
  Vector3d X_1 = M * K_inv_ * p1; // point in 1. view

  Vector3d X_i = M * R.transpose() * K_inv_ * pi; // point in i. view

  if (X_1(2) * X_i(2) < 0.0) // depth components
  {
    R = U * W.transpose() * V.transpose();
    Rtpt = R.transpose() * t;
    M = crossProductMatrix(Rtpt);
    X_1 = M * K_inv_ * p1;
  }
  if (X_1(2) < 0.0) // depth of 1. 3D point
 {
    t = -t;
 }
4

0 に答える 0