読者です 読者をやめる 読者になる 読者になる

cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

OpenCVでステレオ画像処理(その3)

いろいろ順序が前後していますが、キャリブレーションボードを使ったいわゆる普通のステレオキャリブレーションOpenCVでやる方法を確認します。OpenCV3.0以降ではcv::Matが標準として扱われるようになり、cvMatやIplImageは使われなくなっていく流れのようですので、OpenCVc++版exampleのstereo_calibを参考にすることにします。

ソースコードの場所は、

C:\opencv248\sources\samples\cpp\stereo_calib.cpp

です。OpenCVのプロジェクトのビルドには一晩ぐらい時間がかかってしまいますので、新しいプロジェクトを作って、ソースコードをコピーしてきて自分でビルドした方がてっとり早いです。

同じフォルダにある

・left01.jpg~left14.jpg、

・right01.jpg~right14.jpg、

・stereo_calib.xml

もコピーして持ってきます。

 

入力は、左右同時に撮影したキャリブレーションボードの画像です。xmlファイルに対応するペアの画像リストが記されています。出力は、内部パラメータintrinsics.ymlと外部パラメータextrinsics.ymlです。キャリブデータの例を見てみましょう。

intrinsics.yml

%YAML:1.0

M1: !!opencv-matrix

   rows: 3

   cols: 3

   dt: d

   data: [ 5.3471330014109185e+002, 0., 3.3513862534045768e+002, 0.,

       5.3471330014109185e+002, 2.4020611211645166e+002, 0., 0., 1. ]

D1: !!opencv-matrix

   rows: 1

   cols: 8

   dt: d

   data: [ -2.7456948643916240e-001, -1.8313659599039273e-002, 0., 0.,

       0., 0., 0., -2.4476896026105649e-001 ]

M2: !!opencv-matrix

   rows: 3

   cols: 3

   dt: d

   data: [ 5.3471330014109185e+002, 0., 3.3401539789706163e+002, 0.,

       5.3471330014109185e+002, 2.4159046721727415e+002, 0., 0., 1. ]

D2: !!opencv-matrix

   rows: 1

   cols: 8

   dt: d

   data: [ -2.8073637368771431e-001, 9.3010333965398026e-002, 0., 0., 0.,

       0., 0., 1.6329629641388992e-002 ]

M1: 1台目のカメラ行列 [fx, 0, cx,

                                               0, fy, cy,

                                               0, 0, 1]

fx, fyは焦点距離、cx,cyは画像中心

D1: 1台目のレンズ歪み   (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])

k1 , k2 , k3 , k4 , k5 , k6 は半径方向の歪み係数, p1 , p2 は円周方向の歪み係数

M2: 2台目のカメラ行列

D2: 2台目のレンズ歪み

 

 extrinsics.yml

%YAML:1.0

R: !!opencv-matrix

   rows: 3

   cols: 3

   dt: d

   data: [ 9.9975845099223370e-001, 5.2938875802891888e-003,

       -2.1331067106374762e-002, -4.9129099555727165e-003,

       9.9982819095220643e-001, 1.7873217197994926e-002,

       2.1422021038591057e-002, -1.7764102328165273e-002,

       9.9961269183774204e-001 ]

T: !!opencv-matrix

   rows: 3

   cols: 1

   dt: d

   data: [ -3.3385294685465094e+000, 4.8752222149133176e-002,

       -1.0621612775973460e-001 ]

R1: !!opencv-matrix

   rows: 3

   cols: 3

   dt: d

   data: [ 9.9989926261613005e-001, -9.8656327048122546e-003,

       1.0204602444634284e-002, 9.7747186679340847e-003,

       9.9991243188225976e-001, 8.9209552329390027e-003,

       -1.0291719714510178e-002, -8.8203094412328143e-003,

       9.9990813710394366e-001 ]

R2: !!opencv-matrix

   rows: 3

   cols: 3

   dt: d

   data: [ 9.9938783533139086e-001, -1.4593963665815494e-002,

       3.1795767267948229e-002, 1.4875488104129789e-002,

       9.9985206173729635e-001, -8.6356524560469196e-003,

       -3.1665035059203130e-002, 9.1033435724789738e-003,

       9.9945707996416788e-001 ]

P1: !!opencv-matrix

   rows: 3

   cols: 4

   dt: d

   data: [ 4.2656306659615905e+002, 0., 3.2185713195800781e+002, 0., 0.,

       4.2656306659615905e+002, 2.4122907447814941e+002, 0., 0., 0., 1.,

       0. ]

P2: !!opencv-matrix

   rows: 3

   cols: 4

   dt: d

   data: [ 4.2656306659615905e+002, 0., 3.2185713195800781e+002,

       -1.4249656816691422e+003, 0., 4.2656306659615905e+002,

       2.4122907447814941e+002, 0., 0., 0., 1., 0. ]

Q: !!opencv-matrix

   rows: 4

   cols: 4

   dt: d

   data: [ 1., 0., 0., -3.2185713195800781e+002, 0., 1., 0.,

       -2.4122907447814941e+002, 0., 0., 0., 4.2656306659615905e+002, 0.,

       0., 2.9934971212534872e-001, 0. ]

R: 1番目と2番目のカメラ座標系間の回転行列

T: 出力される,それぞれのカメラ座標系間の並進ベクトル

R2 (R1) : 1番目と2番目のカメラに対する 3 \times 3 の平行化変換(回転行列).

P2 (P1) :  新しい(平行化された)座標系における 3 \times 4 の射影行列.

Q:  4 \times 4 の視差-デプス間のマッピング行列. reprojectImageTo3D() を参照

 

f:id:cvl-robot:20140222215214p:plain

opencvのstereo_calib.cppのフローチャートを書き起こしてみます。通常8枚以上、セッティングを変更してないステレオカメラで撮影した左右ペアのキャリブボードが写った画像を入力とします。内部パラメータ、外部パラメータと求めていって、校正マップを作ります。

普段のステレオ画像処理に必要なのは、赤線以下の部分で、校正マップと新しい入力画像を関数remapに渡すと、校正された画像を出力してくれます。それを、stereo_matchに渡してやれば良いわけです。

 

[1]http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html