Edited at

OpenCV2系のAPIを使って歪み補正を行う

More than 3 years have passed since last update.

cvInitUndistortMap()&cvRemap()かcv::distort()を使ったやり方しか見つからなかったのでメモ。


opencv2_calibration.cpp

cv::Mat objectPoints;

cv::Mat imagePoints;
cv::Size imageSize(width, height);

// cv::findChessboardCorners, cv::cornerSubPixなどを使って
// objectPoints, imagePointsを求める。

//
// 中略
// 参考: OpenCV2 プログラミングブック 4.2.1章
// http://book.mycom.co.jp/support/pc/opencv2/
//

// キャリブレーションの実施
cv::Mat cameraMatrix;
cv::Mat distCoeffs;
cv::Mat rotationVectors,
cv::Mat translationVectors;

cv::calibrateCamera(
objectPoints, // 特徴点の世界座標系における座標値
imagePoints, // objectPointsに対応する特徴点の画像上での座標値
imageSize, // 画像サイズ
cameraMatrix, // 入出力用のカメラ内部パラメータ行列
distCoeffs, // 歪み係数の出力ベクトル
rotationVectors, // 各ビューにおいて推定された回転ベクトル
translationVectors // 各ビューにおいて推定された並進ベクトル
);

// 以降の処理は下記の呼び出しと同じ。ただしcv::undistortは歪みマップを都度求めるため遅い。
// cv::undistort(image, undistorted, cameraMatrix, distCoeffs);

// 歪みマップを求める
cv::Mat matx, maty;
cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(), cameraMatrix, imageSize, CV_32FC1, matx, maty);

// 歪み補正を行う
cv::Mat image = cv::imread("input_images.jpg");
cv::Mat undistorted;
cv::remap(image, undistorted, mapx, mapy, INTER_LINEAR);