Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

structure from motion の概要

structure from motion (SfM) は、一連の 2 次元イメージから 3 次元シーンの構造を推定するプロセスです。SfM は、3 次元スキャン、拡張現実、および Visual simultaneous localization and mapping (vSLAM) など、多くのアプリケーションで使用されています。

SfM は多くの異なる方法で計算することができます。問題に取り組む方法は、使用するカメラの台数やタイプ、イメージが順序付けられているかどうかなど、さまざまな要素によって異なります。キャリブレーションされた単一のカメラでイメージが撮影される場合、"スケールを除いた" 3 次元構造とカメラの動きのみを復元できます。"スケールを除いた" とは、構造とカメラの動きの大きさを再スケーリングしながら、測定値をそのまま維持できることを意味します。たとえば、カメラをオブジェクトの近くに置くと、オブジェクトを拡大してカメラを遠ざけたときと同じイメージを確認できます。構造と動きの実際のスケールをワールド単位で計算するには、以下のような追加情報が必要になります。

  • シーンにおけるオブジェクトのサイズ

  • 別のセンサーからの情報 (たとえば走行距離計など)

2 つのビューからの structure from motion

2 つの静止カメラまたは 1 つの移動カメラからの構造という単純なケースでは、1 つのビューがカメラ 1、もう一方のビューがカメラ 2 と見なされます。このシナリオでは、カメラ 1 が原点にあり、その光学軸は z 軸に沿っているとアルゴリズムによって仮定されます。

  1. SfM は、イメージ間の点の対応関係を必要とします。イメージ 1 からイメージ 2 へと、特徴のマッチングまたは点の追跡を行って対応点を見つけます。Kanade-Lucas-Tomasi (KLT) アルゴリズムなどの特徴追跡手法は、各カメラの位置が近い場合にうまく機能します。カメラの位置が遠くなるにつれ KLT アルゴリズムは機能しなくなり、代わりに特徴のマッチングが使用できるようになります。

    カメラ間の距離 (ベースライン)点の対応関係の判定手法
    遠いmatchFeatures を使用した特徴のマッチ自動特徴マッチングを使用したイメージの回転とスケールの検出
    近いvision.PointTracker を使用した特徴の追跡KLT アルゴリズムを使用した顔の検出と追跡

  2. カメラ 1 に対するカメラ 2 の姿勢を求めるには、基礎行列を計算しなければなりません。前の手順で見つけた対応点を使用して計算します。基礎行列は 2 つのカメラのエピポーラ幾何を記述します。これにより、一方のカメラでの点がもう一方のカメラのエピポーラ線に関連付けられます。関数 estimateFundamentalMatrix を使用して基礎行列を推定します。

  3. 基礎行列を関数 relativeCameraPose に入力します。relativeCameraPose は、カメラ 1 の座標系におけるカメラ 2 の向きと位置を返します。スケールを除いた位置のみが計算できるため、2 つのカメラ間の距離は 1 に設定されます。つまり、カメラ間の距離が 1 単位になるように定義されます。

  4. triangulate を使用して、マッチする点の 3 次元での位置を決定する。姿勢はスケールを除くため、構造を計算すると形状は正しくなりますが、実際のサイズは得られません。

    関数 triangulate では 2 つのカメラ行列を使用しますが、これは cameraMatrix を使って計算できます。

  5. pcshow または pcplayer を使用して、再構成を表示します。plotCamera を使用して、カメラの姿勢を視覚化します。

再構成のスケールを復元するには追加情報が必要です。スケールを復元する 1 つの手法は、シーン内でサイズが既知のオブジェクトを検出することです。2 つのビューからの structure from motionの例では、シーンの点群で既知サイズの球体を検出してスケールを復元する方法を説明します。

複数のビューからの structure from motion

ロボット工学や自動運転など、ほとんどのアプリケーションにおいて SfM は 3 つ以上のビューを使用します。

2 つのビューからの SfM で使用したアプローチは、複数のビューへと拡張できます。SfM で使用する複数のビューのセットには、順序を付けることも付けないことも可能です。ここでのアプローチでは、ビューのシーケンスが順序付けられていると仮定します。複数のビューからの SfM では、"トラック" と呼ばれる、複数のイメージにわたる点の対応関係が必要です。一般的な手法では、ペアごとの点の対応関係からトラックを計算します。imageviewset を使用してペアごとの対応関係を管理し、トラックを求めることができます。各トラックは、そのシーンにおける 3 次元点に対応します。トラックから 3 次元点を計算するには triangulateMultiview を使用します。3 次元点は、worldpointset オブジェクトに保存できます。worldpointset オブジェクトは、カメラ ビュー全体の 3 次元点と 2 次元イメージ点の間の対応についても保存します。

2 つのビューからの SfM におけるアプローチを使用して、カメラ 1 に対するカメラ 2 の相対的な姿勢を求めることができます。このアプローチを複数のビューの場合へと拡張するには、カメラ 2 に対するカメラ 3 の相対的な姿勢を求め、他のカメラについても同様にします。相対的な姿勢は、共通の座標系に変換しなければなりません。通常は、すべてのカメラの姿勢をカメラ 1 に対して計算し、すべての姿勢が同じ座標系のものとなるようにします。imageviewset を使用してカメラの姿勢を管理できます。imageviewset オブジェクトは、ビューおよびビュー間の接続を格納します。

各カメラの姿勢の推定には、1 つのビューと次のビューとの間で誤差が含まれます。その誤差は、イメージ内の点の不正確な位置情報、ノイズを含んだ一致および不正確なキャリブレーションから生じます。これらの誤差はビューの数が増えるにつれて累積され、"ドリフト" 効果と呼ばれています。ドリフトを減らす 1 つの方法は、カメラの姿勢と 3 次元点の位置を調整することです。関数 bundleAdjustment によって実装される "バンドル調整" と呼ばれる非線形最適化アルゴリズムを使用して調整することが可能です。bundleAdjustmentMotion を使用して、カメラの姿勢を修正し、3 次元点の位置のみを調整できます。また、bundleAdjustmentStructure を使用して、カメラの姿勢を修正し、3 次元点の位置のみを調整することもできます。

ドリフトを減らす別の方法は、imageviewset オブジェクトに対して "姿勢グラフの最適化" を使用することです。ループ クロージャが検出されたら、imageviewset オブジェクトに新しい接続を追加し、関数 optimizePoses を使用して、相対姿勢によって制約されたカメラの姿勢を調整します。

2 つのビューからの structure from motionの例では、2 次元ビューのシーケンスから 3 次元のシーンを再構成する方法を説明しています。この例ではカメラ キャリブレーターアプリを使用して、ビューを撮影するカメラのキャリブレーションを行います。imageviewset オブジェクトを使用して各ビューに関連付けられたデータの格納と管理を行います。

単眼の Visual Simultaneous Localization and Mappingの例では、単眼カメラのイメージ データを処理して、屋内環境のマップをビルドし、カメラの動きを推定する方法を説明します。

参考

アプリ

関数

オブジェクト

関連するトピック