2018年8月20日月曜日

OpenCVでカメラパラメータの解像度を変更したい

OpenCVでカメラキャリブレーションを行ったときと異なる解像度で補正したい場合がある。
例えば、Raspberry Pi + PiCameraのような組込用途の場合、高い解像度でインタラクティブなキャリブレーションを行う場合、以下のような制約がでてくる。

  • カメラキャプチャの画像を表示するモニターがない
    (まあ、自分がFullHDより大きいモニターを持っていないのが原因なんだけど・・・)
  • キャリブレーションの処理が遅くなる
    Raspberry Pi 3 Model B+ でも、1640 x 1232の解像度でCircle Patternの場合、フレームレートがかなり遅くなる(chAruco Patternはそこまで遅くならない)。

まあ、撮影したパターンをマシンパワーのあるPCなどで解析することも可能なのだが、やはり、"インタラクティブ"にできることはメリットが大きいと思う。

OpenCVの場合、cv::getOptimalNewCameraMatrixを使うことで、カメラパラメータの解像度を変更することができる。

cv::getOptimalNewCameraMatrixは、解像度の変更だけでなく、歪み係数とフリースケールパラメータ(alpha)から周りの画像の欠損を考慮したカメラパラメータを作成してくれる(*1)。
歪み係数は解像度に依存しない(*2)。

Pythonでcv::getOptimalNewCameraMatrixを使って解像度を変更してみる。

使い方


カメラキャリブレーション

まずは、640 x 480でカメラキャリブレーションを行う。
その時のカメラパラメータ抜粋。

<cameraResolution>
  640 480</cameraResolution>
<cameraMatrix type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    5.3447832911092576e+02 0. 3.1759911211440613e+02 0.
    5.3447832911092576e+02 2.3505836099223782e+02 0. 0. 1.</data></cameraMatrix>
...
<dist_coeffs type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    2.7780784561125338e-01 -7.6282457474037868e-01 0. 0.
    6.2366706868917043e-01</data></dist_coeffs>

カメラパラメータの読み込み

前回のブログの通り、cv::FileStorageを使ってカメラパラメータ、歪み係数を読み込む。
fs = cv2.FileStorage("PathToCameraParameterFile", cv2.FILE_STORAGE_READ)
if fs.isOpened():
        width = (int)(camera_fs.getNode("cameraResolution").at(0).real())
        height = (int)(camera_fs.getNode("cameraResolution").at(1).real())
        camera_matrix = camera_fs.getNode("cameraMatrix").mat()
    dist_coeffs = camera_fs.getNode("dist_coeffs").mat()

新しいカメラパラメータの作成

cv::getOptimalNewCameraMatrixを使って新しいカメラパラメータを生成する。
このとき、引数のnewImgSizeに新しい解像度を指定する。
    frame_width = 1640
    frame_height = 1232
    new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(camera_matrix, dist_coeffs,
            (width, height), 0.0, (frame_width, frame_height))

戻り値のnew_camera_matrixに新しい解像度のカメラパラメータが返る。

確認

念の為、カメラパラメータの値を確認する。
確認方法は、前回のブログcv::calibrationMatrixValuesを使ってみる。
Fx, Fy, Cx, Cy はカメラパラメータを出力。

まずは、解像度を変更しない場合(640 x 480 → 640 x 480)
  Fx   =  550.963135
  Fy   =  551.406250
  Cx   =  317.560888
  Cy   =  235.058842
  FOVX =  60.295405
  FOVY =  47.039412
  Focal length    =  3.168038
  Principal point =  1.825975, 1.351588
  Aspect ratio    =  1.000804

次に、解像度を変更する場合(640 x 480 → 1640 x 1232)
  Fx   =  1411.843018
  Fy   =  1415.276123
  Cx   =  813.749768
  Cy   =  603.317729
  FOVX =  60.295406
  FOVY =  47.039410
  Focal length    =  3.168038
  Principal point =  1.825975, 1.351588
  Aspect ratio    =  1.002432

カメラパラメータが適切に変更されていることがわかった。

参考情報



0 件のコメント:

コメントを投稿