15 の nomo ( @nomotech )です。
この記事はrogy Advent Calender 2020 22日目の記事です。
RGB-Depthセンサを自作しよう【2-同期撮像編】の続きです。
今回はプロジェクタカメラのキャリブレーションについてです。
ステレオキャリブレーション
まずはステレオカメラシステムの場合のキャリブレーションについて説明します。
ステレオによる深度推定はそれぞれのカメラの画素で同じ3次元点を参照している対応点を見つけて、三角測量によって深度を測定します。
カメラのステレオの場合、特徴点などを使って対応点を見つけます。
三角測量の時に必要なのはそれぞれのカメラから対象までの方向ベクトルです。
内部パラメータ
カメラの中心から画像上の対応点 (u_0, v_0) に向かってのベクトルは焦点距離と画像中心によって決まります。焦点距離と画像中心はカメラ特有のものであり、カメラの位置姿勢によって変化しません。これを内部パラメータといいます。
内部パラメータはカメラ毎に事前に求めておけばいいです。 ggるとたくさん記事が出てきますが、チェスボードを使ったキャリブレーションが一般的です。
外部パラメータ
ワールド座標系でのカメラの位置姿勢は外部パラメータといいます。この外部パラメータは 4\times3 の Rt 行列によってあらわすことができます。
camera0 を原点としてワールド座標系を設定すると、camera1 の外部パラメータは camera0 からの相対位置姿勢です。
この外部パラメータもチェスボードを使って求めることができます。チェスボードの交点を使うことで、3次元点と2次元点の対応を簡単に求めることができるので、複数台のカメラで同時に同じチェスボードを撮像することで相対位置を計算することができます。
この内部パラメータと外部パラメータがわかれば、ワールド座標系での 3 次元位置を計算することができます。
カメラ-プロジェクタのキャリブレーション
ステレオシステムはそれぞれの画像での対応点が求められればいいので、カメラ-カメラでなくカメラ-プロジェクタでも成立します。
カメラの座標 (u_c, v_c) は撮像した画像上から探せばいいですが、プロジェクタの場合は画像出す装置であって撮る装置ではないので、単純に対応点の座標 (u_p, v_p) を得ることができません。そこでプロジェクタに代わってカメラで投影像を取ることによって、間接的にプロジェクタの画像上での座標を求めることができます。
キャリブレーション用パターン
プロジェクタからは以下のようなグレーコードパターンを投影します。
このグレーコードパターンを解析することによってプロジェクタにとっての画素 (u_p, v_p) を求めることができます。
チェスボードにこのパターンを投影したとき、撮像した画像のチェスボードの交点がカメラ画像上での点を (u_c, v_c) とすると、その画素でのグレーコードを解析することでプロジェクタにとって対応点 (u_p, v_p) を得ることができます。
カメラとプロジェクタの対応点さえわかってしまえばあとはカメラ-カメラのステレオキャリブレーションと同じ方法で内部パラメータおよび外部パラメータを求めることができます。
結果
キャリブレーションした結果を使って再投影誤差を計算した結果です。
下の画像はプロジェクタ場合の再投影の例です。
赤の点が検出したチェスボードで、緑が再投影した点です。
この再投影をキャリブレーションに使った約 30 枚で行い、すべての点の再投影誤差を計算しました。
カメラの再投影誤差は平均 0.47 pixelでキャリブレーション精度は充分であったのに対して、プロジェクタの再投影誤差は平均 2.0 pixel もずれていました。
またカメラだけでなくプロジェクタの投影もレンズゆがみが大きいということがわかりました。
プロジェクタのキャリブレーション精度が悪い理由は分かりませんが、グレーコードを使ったチェスボードの間接的な検知自体の精度が悪い可能性があります。
とりあえず今回はこの制度で次に進みます。
次回はついに構造化光法をやっていきます。
続きはこちら
RGB-Depthセンサを自作しよう【1-基礎知識編】
RGB-Depthセンサを自作しよう【2-同期撮像編】
RGB-Depthセンサを自作しよう【3-キャリブレーション編】
RGB-Depthセンサを自作しよう【4-構造化光法編】
RGB-Depthセンサを自作しよう【5-深度計算編】