OpenCV 4.13.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 4.13.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
キャリブレーションパターンの作成

次のチュートリアル: 正方形チェスボードによるカメラキャリブレーション

著者Laurent Berger, Alexander Panov, Alexander Smorkalov
互換性OpenCV > 4.12

このチュートリアルでは、カメラのキャリブレーションと姿勢推定のために OpenCV がサポートするすべてのパターンを、その長所、落とし穴、実践的な推奨事項とともに説明する。

キャリブレーションパターンとは何か?なぜ必要か?

平坦で印刷可能なパターンは次の用途に使える:

  1. カメラの内部パラメータ(intrinsics)のキャリブレーション。OpenCV によるカメラキャリブレーション を参照。
  2. ステレオまたはマルチカメラシステムの外部パラメータ(extrinsics: 各カメラの回転と並進)のキャリブレーション。詳細は cv::stereoCalibrate を参照。
  3. 3D 世界の既知の点に対するカメラ姿勢の登録。OpenCV 5.x のマルチビューキャリブレーションチュートリアルを参照。

パターンの種類

チェスボード。黒と白の正方形からなる古典的なキャリブレーションパターン。すべてのキャリブレーションアルゴリズムはチェスボードの内部コーナーを特徴として使う。ボードの検出には cv::findChessboardCorners を、サブピクセル精度でのコーナー座標の精緻化には cv::cornerSubPix を参照。ボードサイズは黒または白の正方形の数ではなく、内部コーナーの数として定義される。また、偶数サイズのボードは対称である点に注意。ボードがいずれかの方向に偶数個のコーナーを持つ場合、その姿勢は180度まで(2つの解)しか定まらない。ボードが N x N の正方形である場合、その姿勢は90度まで(4つの解)しか定まらない。後者の2つのケースはキャリブレーションには適さない。キャリブレーション用の特徴座標(オブジェクト点)を生成するサンプルコード:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; ++i) {
for (int j = 0; j < boardSize.width; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

印刷可能なチェスボードパターン: https://github.com/opencv/opencv/blob/4.x/doc/pattern.png (9x6 チェスボード、ページ幅: 210 mm、ページ高さ: 297 mm (A4))

円グリッド。円グリッドは、白背景上の黒い円(あるいはその逆)からなる対称または非対称(各偶数行をずらした)グリッドである。OpenCV でボードを検出するには cv::findCirclesGrid 関数を参照。この検出器は円の中心のサブピクセル座標を出力し、追加の精緻化を必要としない。ボードサイズは x 軸と y 軸方向のグリッド内の円の数として定義される。非対称グリッドの場合、ずらした行も考慮される。このボードは内部パラメータのキャリブレーションに適している。対称グリッドは偶数サイズのチェスボードパターンと同じ問題を抱える。その姿勢は180度までしか定まらない。対称グリッドでのキャリブレーション用の特徴座標(オブジェクト点)を生成するサンプルコード:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; ++i) {
for (int j = 0; j < boardSize.width; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

非対称グリッドでのキャリブレーション用の特徴座標(オブジェクト点)を生成するサンプルコード:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; i++) {
for (int j = 0; j < boardSize.width; j++) {
objectPoints.push_back(Point3f((2 * j + i % 2)*squareSize, i*squareSize, 0));
}
}

印刷可能な非対称円グリッドパターン: https://github.com/opencv/opencv/blob/4.x/doc/acircles_pattern.png (11x4 非対称円グリッド、ページ幅: 210 mm、ページ高さ: 297 mm (A4))

ChAruco ボード。ArUco マーカーを組み込んだチェスボード。ボードの各内部コーナーは隣接する2つの ArUco マーカーによって記述され、これにより一意となる。ボードサイズは内部コーナーの数ではなくユニット数で定義される。サイズ N x M の ChAruco ボードは、サイズ N-1 x M-1 のチェスボードパターンと等価である。OpenCV はボード検出のために cv::aruco::CharucoDetector クラスを提供している。検出アルゴリズムはまず ArUco マーカーを見つけ、ArUco のペアに関する知識を使ってボードを「組み立てる」。前述のパターンとは対照的に、すべてのコーナーにラベルが付いているため、部分的に隠れたボードも使用できる。このボードは回転不変だが、ArUco マーカーの集合とその順序は検出器にあらかじめ知られている必要がある。あらかじめ定められたサイズとランダムなマーカー集合からなる ChAruco ボードは検出できない。ユニット単位のボードサイズに対するキャリブレーション用の特徴座標(オブジェクト点)を生成するサンプルコード:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height-1; ++i) {
for (int j = 0; j < boardSize.width-1; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

印刷可能な ChAruco ボードパターン: https://github.com/opencv/opencv/blob/4.x/doc/charuco_board_pattern.png (7X5 ChAruco ボード、正方形サイズ: 30 mm、マーカーサイズ: 15 mm、ArUco 辞書: DICT_5X5_100、ページ幅: 210 mm、ページ高さ: 297 mm (A4))

独自パターンの作成

既製のパターンが要件を満たさない場合は、独自のパターンを生成できる。OpenCV はソースリポジトリまたはバイナリ配布物の apps/pattern-tools に generate_pattern.py ツールを提供している。唯一の要件は Python 3 である。

例:

9 行、6 列、正方形サイズ 20mm のチェッカーボードパターンをファイル chessboard.svg に作成する:

    python generate_pattern.py -o chessboard.svg --rows 9 --columns 6 --type checkerboard --square_size 20

7 行、5 列、半径 15 mm の円ボードパターンをファイル circleboard.svg に作成する:

    python generate_pattern.py -o circleboard.svg --rows 7 --columns 5 --type circles --square_size 15

7 行、5 列、正方形サイズ 10mm で円間の間隔をより狭くした円ボードパターンをファイル acircleboard.svg に作成する:

    python generate_pattern.py -o acircleboard.svg --rows 7 --columns 5 --type acircles --square_size 10 --radius_rate 2

findChessboardCornersSB() 用に、(7 4)、(7 5)、(8 5) のセルにマーカーを配置したラドンチェッカーボードを作成する:

    python generate_pattern.py -o radon_checkerboard.svg --rows 10 --columns 15 --type radon_checkerboard -s 12.1 -m 7 4 7 5 8 5

7 行、5 列、正方形サイズ 30 mm、aruco マーカーサイズ 15 mm で、aruco マーカーの辞書として DICT_5X5_100 (DICT_ARUCO.json ファイルに含まれる) を使った ChAruco ボードパターンを charuco_board.svg に作成する:

    python generate_pattern.py -o charuco_board.svg --rows 7 --columns 5 -T charuco_board --square_size 30 --marker_size 15 -f DICT_5X5_100.json.gz

測定単位を変更したい場合は -u オプションを使う(例: mm, inches, px, m)

ページサイズを変更したい場合は -w (幅) と -h (高さ) オプションを使う

ChAruco ボードに独自の辞書を使いたい場合は、辞書ファイルの名前を指定する。例えば:

    python generate_pattern.py -o charuco_board.svg --rows 7 --columns 5 -T charuco_board -f my_dictionary.json

samples/cpp/aruco_dict_utils.cpp に用意されたユーティリティを使えば、30 個のマーカーとマーカーサイズ 5 ビットの独自辞書をファイル my_dictionary.json に生成できる。

    bin/example_cpp_aruco_dict_utils.exe my_dict.json -nMarkers=30 -markerSize=5

パターンサイズ

パターンは、その物理的なボードサイズ、要素(正方形または円)の物理サイズ、要素数によって定義される。キャリブレーション品質に影響する要因:

  • 特徴の数。検出されたパターンを扱う OpenCV 関数の多くは、内部で最適化またはランダムなコンセンサス戦略を用いる。ボード上の特徴が多いほど最適化に使える点が増え、推定品質が向上する。キャリブレーション処理には複数の画像が必要である。つまり、ほとんどの場合、パターン特徴の数が少ないことは、フレーム数を増やすことで補える。
  • 要素サイズ。要素の物理サイズは、距離とピクセル単位のサイズに依存する。各検出器には信頼できる検出のための最小サイズが定められている。円グリッドでは円の半径、チェスボードでは正方形のサイズ、ChAruco ボードでは ArUco マーカーの要素サイズがそれにあたる。一般的な推奨: 要素を(フレームピクセル単位で)大きくすると検出の不確かさが減少する。
  • ボードサイズ。ボードは完全に見える状態で、シャープであり、OpenCVのアルゴリズムによって確実に検出される必要がある。したがって、一般的な対象距離で使用する場合、ボードサイズは前述の項目を満たす必要がある。通常はより大きなボードのほうが良いが、より小さなボードはコーナーをより正確にキャリブレーションできる。

一般的な推奨事項

  1. 最終的なパターンはできるだけ平坦であるべきである。これによりキャリブレーション精度が向上する。
  2. 光沢のあるパターンはマット仕上げよりも劣る。光沢面での反射や影はボード検出を大幅に低下させる。
  3. ほとんどの検出アルゴリズムは、マーカーの周囲に白(黒)の境界があることを前提としている。これらを切り取ったり覆ったりしないこと。