cvl-robot's diary

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

OpenCV3.4のChArUcoキャリブレーションを試す(その2)カメラキャリブレーション

キャリブレーションを進めていきます。対象は、シングルカメラのintrinsicパラメータの推定です。ここでは、intel EuclidのRGBカメラを使います。

calibrate_camera_charucoのビルド

ビルドは、ボードを作る時と同様にsamples以下にあるソースで行います。

cd ~/opencv_contrib/modules/aruco/samples
g++ -o calibrate_camera_charuco calibrate_camera_charuco.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`

calibrate_camera_charucoの実行

実際にキャリブレーションしてみます。helpによると、引数は次の通り。

> ./calibrate_camera_charuco
Calibration using a ChArUco board
To capture a frame for calibration, press 'c',
If input comes from video, press any key for next frame
To finish capturing, press 'ESC' key and calibration starts.

Usage: calibrate_camera_charuco [params] outfile

-a
Fix aspect ratio (fx/fy) to this value
--ci (value:0)
Camera id if input doesnt come from video (-v)
-d
dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16
--dp
File of marker detector parameters
-h
Number of squares in Y direction
--ml
Marker side length (in meters)
--pc (value:false)
Fix the principal point at the center
--rs (value:false)
Apply refind strategy
--sc (value:false)
Show detected chessboard corners after calibration
--sl
Square side length (in meters)
-v
Input from video file, if ommited, input comes from camera
-w
Number of squares in X direction
--zt (value:false)
Assume zero tangential distortion

outfile (value:)
Output file with calibrated camera parameters

  • sl, -mlには、前回作ったキャリブボードの実測サイズをメートル単位で渡してやります。
  • slは古典的なチェッカーの方の一つのスクエアの一辺の長さを与え、-mlにはマーカーの一辺の長さを与えます。

./calibrate_camera_charuco -w=5 -h=7 -sl=0.034 -ml=0.0205 -d=10 ./test.xml

f:id:cvl-robot:20180129160112p:plain
おかしな緑色の画像になってしまいました。おそらくRGBカメラ以外のデバイスを指定しているせいです。
intel Euclidの場合、camera id0やid1は、depthやfisheyeに割り振られているようなので、RGBカメラのid番号2を正しく指定してやると、

./calibrate_camera_charuco -w=5 -h=7 -sl=0.034 -ml=0.0205 -d=10 ./test.xml --ci=2

f:id:cvl-robot:20180129160404p:plain
正しく映像が取れました。

計測に使いたい範囲をまんべんなく、ボードの位置姿勢を変えながら、'c'を押して、キャプチャしていきます。画面の中にチェッカーボードが収まりきっていなくても構わないことが重要で、キャリブレーションの作業がとても手軽にできるようになっています。また、おそらくディストーションの大きい画像の4角の測定にも有効だろうと思います。
十分な数が取れたと思ったら、Escキーを押します。少し時間がかかりますが、やがてキャリブレーション結果を指定ファイルにXMLで出力してくれます。

Frame captured
Rep Error: 0.188544
Rep Error Aruco: 0.997946
Calibration saved to ./test.xml

その中身の例は、こんな感じ。

<?xml version="1.0"?>
<opencv_storage>
<calibration_time>"Sun 28 Jan 2018 10:49:36 PM PST"</calibration_time>
<image_width>640</image_width>
<image_height>480</image_height>
<flags>0</flags>
<camera_matrix type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    6.1678400163023969e+02 0. 3.0520119870239319e+02 0.
    6.1622386764798591e+02 2.3621372568629317e+02 0. 0. 1.</data></camera_matrix>
<distortion_coefficients type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    7.3842655143348923e-02 2.0145394049888204e-01
    -2.8227732060625431e-03 -2.5751890237041769e-03
    -1.1649335582959877e+00</data></distortion_coefficients>
<avg_reprojection_error>1.8854380064963244e-01</avg_reprojection_error>
</opencv_storage>

ボードが画像中に入っているかどうかをほとんど気にする必要がないので、とても楽になりました。精度は、円チェッカーの方がいいなんていう話を聞きますけれど、実際のところどのくらいちがうものでしょうか。気になりますね。

また、Intel EuclidのFisheyeカメラをキャリブレーションしたい場合、いろいろと改造が必要そうです。簡単なところでは、モノクロカメラなのでモノクロ画像にただしく変換するとか、fisheye用のキャリブ関数に変えるとか。