第17回目の今回は、スバルのEyeSightで採用されている「ステレオカメラ(パッシブステレオ法)」にフォーカスして、OpenCVに実装されている一般的な手法について説明します。

ステレオカメラによる3次元計測は、下記の要素技術に大別できます。
・カメラキャリブレーション
・レクティフィケーション
・対応点探索(ステレオマッチング)

カメラキャリブレーションとレクティフィケーション

ステレオカメラでは、図1に示すとおり視点の異なる2台(または3台以上)のカメラを用いて、三角測量の原理で距離を求めます。例えば、実空間中の3次元点P1をCameraLとCameraRで撮影すると、CameraLで撮像された点の座標PLとCameraRで撮像された点の座標PRにズレが生じます。パッシブステレオ法は、この見え方の差(視差)から距離を計測する手法です。

視差を求めるためには、CameraLの画像中の点に対応する点をCameraRの画像中から見つけ出す必要があります(対応点探索/ステレオマッチング)。そして、視差から3次元座標を計算するためには、CameraLとCameraRの内部パラメータ、歪係数、さらにCameraLとCameraR間の外部パラメータが必要となります。これらのパラメータを求める処理が、ステレオカメラに必要なカメラキャリブレーションです。

これらのパラメータが求められていれば、エピポーラ幾何と呼ばれる幾何学的な拘束条件により、対応点探索を効率的に行うことができます。CameraLとCameraRを結ぶ直線と画像平面との交点は、エピポール(eL , eR)と呼ばれています。また、3次元点P1とCameraLの位置、CameraRの位置は同一平面上に存在し、その平面と画像平面が交わる直線PR-eRがエピポーラ線です。点P1, P2,……,P5 は、CameraLの画像では同一の点PLに投影されます。一方、点PLに対応するCameraRの画像上の点PRはエピポーラ線上に必ず存在することになります(図1)。つまり、対応点探索はエピポーラ線上のみを処理すれば良いわけです。

図1 エピポーラ幾何

図1 エピポーラ幾何

エピポーラ幾何の拘束条件を用いることで、対応点探索はエピポーラ線上のみで良いのですが、エピポーラ線は多くの場合、画像上で斜めになってしまい、メモリアクセスやエピポーラ線の計算の効率が良くありません。そこで、カメラを平行に設置した平行ステレオ視が一般的に用いられます。カメラキャリブレーションにより求めた内部パラメータ、外部パラメータ、歪係数を用いることで画像を平行化できます(図2)。平行化処理は、レクティフィケーションと呼ばれています。レクティフィケーション後の画像では、エピポーラ線が画像の横軸と平行になるため、高速に対応点探索を行えるわけです。

図2 画像の平行化(レクティフィケーション)

図2 画像の平行化(レクティフィケーション)

対応点探索

対応点探索には、小領域毎に視差を求めるテンプレートマッチングによる方法、画像全体で最適な解を求めるグローバルマッチングによる方法、注目画素の周辺のみで最適な解を求めるセミグローバルマッチングによる方法があります。リアルタイム性を重視するのであれば、テンプレートマッチングによる方法が良いでしょう。リアルタイム性を重視しないのであれば、セミグローバルマッチングやグローバルマッチングを用いることもできます。

コーディング

OpenCVでは、“opencv/sources/samples/cpp/”にサンプルコード“stereo_calib.cpp”と“stereo_match.cpp”が用意されていますので参考にしてみてください。
ステレオカメラのカメラキャリブレーションでは、2台のカメラでキャリブレーションパターンを同時に撮影し、その画像セットをcv::stereoCalibrate(魚眼レンズの場合はcv::fisheye::stereoCalibrate、全方位カメラの場合はcv::omnidir::stereoCalibrate)の入力として、2台のカメラの内部パラメータ、歪係数、カメラ間の外部パラメータを求めることができます。
そして、画像を平行化するレクティフィケーション処理は、cv::StereoRectify (魚眼レンズの場合はcv::fisheye::StereoRectify、全方位カメラの場合はcv::omnidir::StereoRectify)で平行化するためのパラメータを求め、cv::initUndistortRectifyMap(魚眼レンズの場合はcv::fisheye::initUndistortRectifyMap、全方位カメラの場合はcv::omnidir::initUndistortRectifyMap)を用いて画素毎の変換テーブルを作成し、cv::remapで画像を補正します。

図3は、ステレオカメラの処理フローと処理結果です。Disparity Map(視差マップ)は、近くを白、遠くを黒として可視化したものです(テンプレートマッチングによる手法で求めた結果)。レクティフィケーションにより、2台のカメラにより撮像した画像を平行化できていることがお分かりいただけるかと思います。

図3 ステレオカメラの処理フローと処理結果

図3 ステレオカメラの処理フローと処理結果

次回は、高精度な3次元計測に必要なサブピクセル推定について解説します!