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);