2014年6月15日日曜日

VisualSfMの使い方 その3 -既知のカメラパラメータを用いた復元-

今回は、画像を撮影したカメラの内部パラメータが既知かつ全ての画像で同じ場合の復元について説明します。

Structure-from-motionでは、カメラの外部パラメータ(並進、回転)、カメラの内部パラメータ(焦点距離、画像中心、レンズ歪など)、特徴点の三次元位置を推定することが出来ます。VisualSfMもデフォルトではこれらのパラメータを推定するようになっています。

しかし、事前にカメラキャリブレーションを行ったカメラを用いて撮影した画像を用いる場合には、カメラの内部パラメータの推定は不要になります。VisualSfMでは、このような場合に事前のキャリブレーション結果を利用することが出来る機能が用意されています。
カメラパラメータは、SfM -> More Functions -> Set Fixed Calibrationを選択することで焦点距離 fx, fy [pixel]、画像中心 cx, cy、レンズ歪係数 rを指定することが出来ます。ただし、歪係数は1次の項のみなので、歪が大きな画像を入力する場合には、以下のように事前に歪を取り除いた画像を用意し、r=0を指定するのが良いかもしれません。

#include <opencv2/opencv.hpp>

int main(int argc, char** argv)
{
  cv::Mat K;
  cv::Mat distCoeffs;

  //内部パラメータの読み込み
  cv::FileStorage fs("camera.xml", CV_STORAGE_READ);
  fs["intrinsicMat"] >> K;
  fs["distCoeffs"] >> distCoeffs;

  cv::Mat input = cv::imread("image1.jpg");
  cv::Mat undistorted;

  //レンズ歪の除去
  cv::undistort(input, undistorted, K, distCoeffs);

  //オリジナル画像
  cv::namedWindow("Original");
  cv::imshow("Original", input);

  //レンズ歪除去後の画像
  cv::namedWindow("undistorted");
  cv::imshow("undistorted", undistorted);

  cv::imwrite("undistorted.jpg", undistorted);

  cv::waitKey();
  return 0;
}

経験的には、既知の内部パラメータを用いた復元の方が、精度よく推定されているように思います。

0 件のコメント:

コメントを投稿