web-dev-qa-db-ja.com

opencvバンドル調整の使用方法

5つのカメラ行列(c1, ... c5)を計算しました。カメラ行列は、3Dオブジェクトを5つの異なる位置に配置することによって計算され、各位置についてカメラ行列を計算しました(カメラは一定です)。カメラマトリックスは、SVD法を使用して計算されます。

次に、opencvでバンドル調整を使用して、1つの最適なカメラマトリックスを取得します。ドキュメントを見つけました ここ

しかし、ドキュメントは明確ではなく、サンプルコードも見つかりませんでした。 opencvバンドル調整を使用してoptimal camera matrixを取得する方法を誰かが説明できますか?

10
Deepak

私の答えは、寸法が正確にわかっている特定の3Dオブジェクトを使用して、1台のカメラの固有パラメーターを推定することを前提としていますオブジェクトの複数の画像。 @fireantの回答に対するあなたのコメントに照らして、これはあなたの質問にも当てはまると思います。

「カメラマトリックス」の意味に関する簡単なメモ

「カメラマトリックス」という用語は非常にあいまいであり、さまざまな方法で理解できます。

  • カメラポーズT = [R | t]、外部カメラパラメータとも呼ばれます。
  • 固有のカメラ行列K = [fx、s、cx; 0、fy、cy; 0、0、1]。
  • カメラ投影行列P = K. [R | t]。

複数の画像があるが、単一のカメラマトリックスが必要だと言うように、固有のカメラマトリックスKについて話していると思います。

バンドル調整を使用すべきでない理由

バンドル調整は、カメラのキャリブレーションよりも一般的な問題を解決するために使用される手法であり、外部カメラパラメータ(3Dの向きと位置)と3Dランドマーク(3Dポイントなど)の両方が不明です。 @fireantが指摘したように、このグローバルジョイント最適化に固有のカメラパラメータを含めることも可能です。一方、カメラキャリブレーションは、3Dランドマークが複数の画像で単一のカメラによって認識および観察されることを前提としているため、画像ごとに1セットの固有のカメラパラメータと1つのカメラポーズを最適化します。

理解すべきことは、より一般的な最適化問題には、最適化する変数が多く含まれるため、それらを十分に制約することが難しいということです。それらが十分に制約されていない場合、それらは実際にグローバルエラーを減らす方法で変数を最適化しますが、それは実際の問題の解決には対応しません。これが、共同最適化アルゴリズムを使用する場合、最適化する変数の数を常に減らすようにする必要がある理由です。

バンドル調整とカメラキャリブレーションの場合、3Dランドマークの位置が正確なアイデアがないの場合にのみバンドル調整を使用する必要があります。それでも、たとえば3Dオブジェクトを事前にキャリブレーションすることによって、問題を切り離してみることをお勧めします。 3Dランドマークの位置を正確に把握している場合は、それらを最適化する変数と見なすべきではないため、カメラキャリブレーション手法を使用する必要があります。

最適化の初期見積もり

カメラ行列Kの不正確な推定値が複数あり、共同最適化を実行して1つのより正確な推定値を取得したいと言っています。問題は、単一のカメラマトリックスを推定するため、共同最適化アルゴリズムに初期推定は1つのみを提供する必要があることです。

複数の近似推定値を引き続き使用するためにできることは、最適化アルゴリズムの初期推定値として、真の解に最も近いものを選択することです。この目的のために、いくつかのヒューリスティック基準を使用できます。たとえば、最小の再投影エラーに関連付けられているものを選択したり、キャリブレーションオブジェクトが最大の画像に関連付けられているものを使用したりできます。

ただし、カメラマトリックスの最終的な推定値に大きな違いはないでしょう。

このタスクに「calibrateCamera」を使用する方法

特性点を持つキャリブレーションオブジェクトがあるとします。これは、標準の2Dチェス盤、非対称円グリッド、または任意のキャリブレーションされた3Dオブジェクトにすることができます。また、画像内のこのキャリブレーションオブジェクトを検出する方法を開発したとします(たとえば、カスタム機能検出器、またはオブジェクトの位置を手動で決定するツール)。次に、検出可能なオブジェクト上の3Dポイントを含むベクトルallObjectPointsを定義できます。次に、各画像iについて、オブジェクトの3Dポイントの観測値として検出された2DポイントのベクトルimagePoints_iを決定できます(一部のオブジェクトポイントが遮られている可能性があるため、allObjectPointsよりもアイテムが少ない場合があります)。次に、すべてのオブジェクトポイントが(直接または推論によって)識別可能であるため、画像iで実際に観察され、objectPoints_iと一貫して順序付けられたオブジェクト3Dポイントを含むベクトルimagePoints_iを決定できます。

次に、すべてのobjectPoints_iベクトルを1つの大きなベクトルのベクトルobjectPointsにスタックします。同様に、すべてのimagePoints_iベクトルを1つの大きなベクトルのベクトルimagePointsにスタックします。次に、フラグCV_CALIB_USE_INTRINSIC_GUESSを指定してcalibrateCameraを呼び出し、指定した初期値を最適化アルゴリズムで使用することを示します。

10
BConic

OpenCVを使用した画像処理の学習 の155ページにあるサンプルコードを参照してください。このようなもの:

vector<CameraParams> cameras;
vector<MatchesInfo> pairwise_matches;
vector<ImageFeatures> features(num_images);

// initialize the above params here

Ptr<BundleAdjusterBase> adjuster;
adjuster = makePtr<BundleAdjusterReproj>();
if (!(*adjuster)(features, pairwise_matches, cameras)) {
    cout << "Camera parameters adjusting failed." << endl; 
    return -1;
}

MCVEを提供すると、支援が簡単になります。

編集:同じK行列の推定値が5つあるとします。最も簡単な方法は、5つの推定値を単純に平均して、より正確なKを取得することです。いくつかの穏やかな仮定の下では、最適な推定値になります。再投影誤差が大きく異なる場合は、加重平均を計算できます。

10
fireant