利用OpenCV3進行魚眼鏡頭標定


  OpenCV3.0 alpha在8月21日發布,其中增加了魚眼鏡頭模型,提供了標定、去畸變等一系列api,其實現方法參考了{Camera Calibration Toolbox for Matlab}。本文簡單介紹了OpenCV 中實現的魚眼鏡頭模型,給出調用demo的關鍵代碼、注釋和去畸變的結果。

魚眼鏡頭模型

  魚眼鏡頭的內參模型可以表示為,與普通鏡頭的內參一樣,但畸變參數不同,為,含義如下:

  設(X,Y,Z)為一個三維坐標點,投影在圖像上的二維坐標為(u,v),如果不考慮畸變,投影關系如下:

  

  R和t分別代表相機外參中的旋轉矩陣和平移向量。

  當考慮魚眼鏡頭的畸變后,投影關系轉化為:

  

標定流程

  首先調用OpenCV的FindChessboardCorners()來尋找圖像上的標定板的角點,再根據標定板的尺寸指定這些角點對應的三維點的三維坐標,再調用fisheye::calibrate()來進行標定,利用標定結果中的內參和畸變參數調用fisheye::undistortImage()對圖像做去畸變操作。

代碼片段

  

tuple<Mat, Mat, double> calibrate_fisheye(const vector<Mat>& images, const Settings& s) {
    /*尋找二維角點*/
    auto corners = chessboard_corners(images, s);
    /*計算二維角點對應的三維點坐標*/
    auto object_points = vector<vector<Point3d>>(corners.size(), object_positions(s));
    cv::Matx33d K;
    cv::Vec4d D;int flag = 0;
    flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
    flag |= cv::fisheye::CALIB_CHECK_COND;
    flag |= cv::fisheye::CALIB_FIX_SKEW;/*非常重要*/

    double rms = fisheye::calibrate(object_points, 
        corners, 
        s.imageSize,
        K, D, 
        cv::noArray(), cv::noArray(), 
        flag, 
        cv::TermCriteria(3, 20, 1e-6));
    return make_tuple(Mat(K), Mat(D), rms);
}

  代碼非常簡單,和標定普通的鏡頭的區別在於:

  1. 角點坐標和和對應的三維點坐標為double類型,普通鏡頭為float類型,弄混后不能正確執行
  2. flag必須指定CALIB_FIX_SKEW,代表求解時假設內參中fx=fy,與魚眼鏡頭標定論文中一致,沒有這個假設的話是得不到結果的

結果

 

  測試了OpenCV的測試數據,34張圖像進行標定,重投影誤差均值為0.343542。

  左邊為源圖像,右邊為去畸變結果:

未完成工作

  本來以為在畸變圖像上找棋盤格角點會比一般的方法復雜一些,沒想到利用FindChessboardCorners就可以成功找到,所以就暫時這樣用了,對於畸變比較大的圖像,或者手工標出角點,或者實現論文《Automatic Detection of Checkerboards on Blurred and Distorted Images》中自動提取棋盤格的方法。

參考:

http://docs.opencv.org/master/modules/calib3d/doc/calib3d.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM