常用的相机模型为针孔模型,此模型在视场较小的情况下是适用的,随着视场的增加,模型误差越来越大。
普通镜头和鱼眼镜头成像原理的差异是造成此现象的根本原因。具体原理可以参见:
[1] http://docs.opencv.org/master/db/d58/group__calib3d__fisheye.html#gsc.tab=0
[2] Juho Kannalaand Sami S. Brandt. A generic camera model and calibration method for conventional,wide-angle and fish-eye lenses. IEEE Transactions on Pattern Analysis andMachine Intelligence, vol. 28, no. 8, August 2006.
[3] Juho Kannala,Janne Heikkila and Sami S. Brandt. Geometric camera calibration. WileyEncyclopedia of Computer Science and Engineering, 2008.
我的源程序:
vector
vector
vector
vector
// 鱼眼镜头参数
Mat intrinsic_mat; //Matx33d intrinsic_mat亦可; Mat intrinsic_mat(3, 3, CV_64FC1, Scalar(0))亦可,注意数据类型;
Mat distortion_coeffs; //Vec4d distortion_coeffs亦可
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW; /*非常重要*/
cv::fisheye::calibrate(
obj_ptsVector,
img_ptsVector,
board_img_size,
intrinsic_mat,
distortion_coeffs,
cv::noArray(),
cv::noArray(),
flag,
cv::TermCriteria(3, 20, 1e-6)
);
//畸变校正
void FishEyeImgUndistort()
{
Mat DistortImg = cv::imread("fore_1.jpg");
Mat UndistortImg;
Mat new_intrinsic_mat; //Mat new_intrinsic_mat(3, 3, CV_64FC1, Scalar(0))亦可,注意数据类型;
//fx,fy变大(小),视场变小(大),裁剪较多(少),但细节清晰(模糊);很关键,new_intrinsic_mat决定输出的畸变校正图像的范围
intrinsic_mat.copyTo(new_intrinsic_mat);
//调整输出校正图的视场
new_intrinsic_mat.at
new_intrinsic_mat.at
//调整输出校正图的中心
new_intrinsic_mat.at
new_intrinsic_mat.at
cv::fisheye::undistortImage(
DistortImg,
UndistortImg,
intrinsic_mat,
distortion_coeffs,
new_intrinsic_mat //
); //最后一个camera_matrix必须写上 Ref:http://answers.opencv.org/question/64614/fisheyeundistortimage-doesnt-work-what-wrong-with-my-code/
cv::imshow("DistortImg", DistortImg);
cv::imshow("UndistortImg", UndistortImg);
cv::imwrite("feModelUndistortFore.jpg", UndistortImg);
cv::waitKey(0);
}