前のチュートリアル: テクスチャ付き物体の実時間姿勢推定
次のチュートリアル: 複数視点カメラキャリブレーションのチュートリアル
| |
| 原著者 | Vladislav Sovrasov |
| 互換性 | OpenCV >= 3.1 |
古典的なキャリブレーション手法では、ユーザーはまずすべてのデータを収集し、その後 cv::calibrateCamera 関数を実行してカメラパラメータを取得する必要がある。平均再投影誤差が大きい場合や、推定されたパラメータが誤っているように見える場合は、データの選択や収集と cv::calibrateCamera の実行を繰り返す。
インタラクティブなキャリブレーション処理では、新しいデータが追加されるたびにユーザーが結果と誤差の推定値を確認できることを前提としている。また、最後に追加したデータを削除することもでき、最終的にキャリブレーション用のデータセットが十分な大きさになると、データの自動選択処理が開始される。
アプリケーションの主な機能
このサンプルアプリケーションは次のことを行う:
- 歪み行列と各要素の信頼区間を求める
- カメラ行列と各要素の信頼区間を求める
- カメラまたは動画ファイルから入力を受け取る
- XMLファイルから設定を読み込む
- 結果をXMLファイルに保存する
- 再投影誤差を計算する
- 悪条件なヤコビアンブロックの発生を防ぐため、鋭角のパターン視点を棄却する
- キャリブレーションフラグを自動切り替えする(必要に応じてアスペクト比や歪み行列の要素を固定する)
- 複数の基準を用いてキャリブレーションの完了を自動検出する
- 静止パターンを自動キャプチャする(ユーザーはフレームをキャプチャするためにキーを押す必要はなく、1秒間パターンを動かさないだけでよい)
サポートされているパターン:
- 白黒のチェスボード
- 非対称な円パターン
- デュアル非対称サークルパターン
- chAruco(Arucoマーカー付きチェスボード)
- 対称な円パターン
パラメータの説明
アプリケーションには2つの引数グループがある。1つは主要なもの(コマンドライン経由で渡す)、もう1つは高度なもの(XMLファイル経由で渡す)である。
基本パラメータ:
これらの引数はすべてコマンドライン経由でアプリケーションに渡される。
-[parameter]=[default value]: 説明
- -v=[filename]: filenameから動画を取得する。デフォルトの入力は id=0 のカメラ
- -ci=[0]: 指定したidのカメラから動画を取得する
- -flip=[false]: 入力フレームを垂直方向に反転する
- -t=[circles]: キャリブレーション用のパターン (circles, chessboard, dualCircles, chAruco, symcircles)
- -sz=[16.3]: キャリブレーションボード上で隣接する円または正方形の中心間の距離
- -dst=[295] dualCirclesパターンの白い部分と黒い部分の間の距離
- -w=[width]: パターンの幅(コーナー数または円の数)
- -h=[height]: パターンの高さ(コーナー数または円の数)
- -of=[camParams.xml]: 出力ファイル名
- -ft=[true]: キャリブレーションフラグの自動調整
- -vis=[grid]: キャプチャしたボードの可視化方法 (grid, window)
- -d=[0.8]: キャプチャ間の遅延(秒)
- -pf=[defaultConfig.xml]: 高度なアプリケーション引数のファイル
- -force_reopen=[false]: エラー発生時にカメラを強制的に再オープンする。接続が不安定なIPカメラで役立つことがある。
- -save_frames=[false]: 最終的なキャリブレーションに寄与するフレームを保存する
- -zoom=[1]: プレビュー画像に適用するズーム倍率
高度なパラメータ:
デフォルトでは、高度な引数の値はdefaultConfig.xmlに保存されている
<?xml version="1.0"?>
<opencv_storage>
<charuco_dict>0</charuco_dict>
<charuco_square_length>200</charuco_square_length>
<charuco_marker_size>100</charuco_marker_size>
<calibration_step>1</calibration_step>
<max_frames_num>30</max_frames_num>
<min_frames_num>10</min_frames_num>
<solver_eps>1e-7</solver_eps>
<solver_max_iters>30</solver_max_iters>
<fast_solver>0</fast_solver>
<frame_filter_conv_param>0.1</frame_filter_conv_param>
<camera_resolution>1280 720</camera_resolution>
</opencv_storage>
- charuco_dict: chArucoパターンの生成に使用された特別な辞書の名前
- charuco_square_length: chArucoボード上の正方形のサイズ(ピクセル単位)
- charuco_marker_size: chArucoボード上のArucoマーカーのサイズ(ピクセル単位)
- calibration_step: cv::calibrateCamera を起動するフレーム間隔
- max_frames_num: キャリブレーション用のフレーム数がこの値を超えると、フレームフィルタが動作し始める。フィルタリング後のキャリブレーションデータセットのサイズはmax_frames_numに等しくなる
- min_frames_num: フレーム数がこの値を超えると、フラグの自動調整、歪み補正後の表示、品質評価が有効になる
- solver_eps: cv::calibrateCamera における Levenberg-Marquardt ソルバの精度
- solver_max_iters: ソルバの反復回数の上限
- fast_solver: この値が非ゼロでLapackが見つかった場合、ソルバ内でSVDの代わりにQR分解が使用される。QRはSVDより高速だが、精度が劣る可能性がある
- frame_filter_conv_param: 二基準フレームフィルタの線形畳み込みで使用される引数
- camera_resolution: キャリブレーションに使用するカメラの解像度
注: charuco_dict、charuco_square_length、charuco_marker_size は chAruco パターンの生成に使用される (詳細は Aruco モジュールの説明を参照: Aruco tutorials)
デフォルトのchArucoパターン:
二重円パターン
このパターンを作成するには、標準のOpenCVサークルパターンとそれを二値反転したものが必要である。一方のパターンのすべての水平な円の列が、もう一方のパターンの対応する列の延長線上になるように、2つのパターンを同一平面上に配置する。下の図に示すようにパターン間の距離を測定し、それをdstコマンドライン引数として渡す。また、最も近い円の中心間の距離を測定し、その値をszコマンドライン引数として渡す。
このパターンは製作と測定の品質に対して非常に敏感である。
データのフィルタリング
キャリブレーションデータセットのサイズがmax_frames_numを超えると、データフィルタが動作し始める。これはデータセットから「悪い」フレームを取り除こうとするものである。フィルタは\(loss\_function\)が最大となるフレームを除去する。
\[loss\_function(i)=\alpha RMS(i)+(1-\alpha)reducedGridQuality(i)\]
RMSはフレームiに対して計算された平均再投影誤差であり、reducedGridQualityはフレームiを除いたシーンのカバレッジ品質の評価値である。\(\alpha\)はframe_filter_conv_paramに等しい。
キャリブレーションの手順
キャリブレーションを開始するには、アプリケーションを実行するだけでよい。パターンをカメラの前に置き、何らかの姿勢で固定する。その後、キャプチャを待つ(「Frame #i captured」のようなメッセージが表示される)。現在の焦点距離と再投影誤差がメイン画面に表示される。パターンを次の位置に移動し、同じ手順を繰り返す。画像平面を均一に覆うようにし、画像平面に対して鋭角になる向きでパターンを見せないようにする。
キャリブレーションが成功したと思われる場合(信頼区間と平均再投影誤差が小さく、フレームのカバレッジ品質とパターンの視点数が十分大きい場合)、アプリケーションは下の画面のようなメッセージを表示する。
ホットキー:
- Esc – アプリケーションを終了する
- s – 現在のデータをXMLファイルに保存する
- r – 最後のフレームを削除する
- d – すべてのフレームを削除する
- u – 歪み補正の適用を有効化/無効化する
- v – 可視化モードを切り替える
結果
結果として、カメラパラメータとそれらの信頼区間が得られる。
出力XMLファイルの例:
<?xml version="1.0"?>
<opencv_storage>
<calibrationDate>"Thu 07 Apr 2016 04:23:03 PM MSK"</calibrationDate>
<framesCount>21</framesCount>
<cameraResolution>
1280 720</cameraResolution>
<camera_matrix type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
1.2519588293098975e+03 0. 6.6684948780852471e+02 0.
1.2519588293098975e+03 3.6298123112613683e+02 0. 0. 1.</data></camera_matrix>
<camera_matrix_std_dev type_id="opencv-matrix">
<rows>4</rows>
<cols>1</cols>
<dt>d</dt>
<data>
0. 1.2887048808572649e+01 2.8536856683866230e+00
2.8341737483430314e+00</data></camera_matrix_std_dev>
<distortion_coefficients type_id="opencv-matrix">
<rows>1</rows>
<cols>5</cols>
<dt>d</dt>
<data>
1.3569117181595716e-01 -8.2513063822554633e-01 0. 0.
1.6412101575010554e+00</data></distortion_coefficients>
<distortion_coefficients_std_dev type_id="opencv-matrix">
<rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
1.5570675523402111e-02 8.7229075437543435e-02 0. 0.
1.8382427901856876e-01</data></distortion_coefficients_std_dev>
<avg_reprojection_error>4.2691743074130178e-01</avg_reprojection_error>
</opencv_storage>