1. 程式人生 > >OpenCV3.1.0魚眼相機標定及畸變校正

OpenCV3.1.0魚眼相機標定及畸變校正

       常用的相機模型為針孔模型,此模型在視場較小的情況下是適用的,隨著視場的增加,模型誤差越來越大。

       普通鏡頭和魚眼鏡頭成像原理的差異是造成此現象的根本原因。具體原理可以參見:

[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<Point2f> img_ptsTemp;
      vector<vector<Point2f>> img_ptsVector;


      vector<Point3f> obj_ptsTemp;
      vector<vector<Point3f>> obj_ptsVector;

       // 魚眼鏡頭引數
         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<double>(0, 0) *= 0.5;      //注意資料型別,非常重要
new_intrinsic_mat.at<double>(1, 1) *= 0.4; 


//調整輸出校正圖的中心
new_intrinsic_mat.at<double>(0, 2) += 0.0;   
new_intrinsic_mat.at<double>(1, 2) += 0.0;


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