鱼眼相机

OpenCV3.0 alpha在8月21日发布,其中增加了鱼眼镜头模型,提供了标定、去畸变等一系列api,其实现方法参考了{Camera Calibration Toolbox for Matlab}。本文简单介绍了OpenCV 中实现的鱼眼镜头模型,给出调用demo的关键代码、注释和去畸变的结果。

鱼眼镜头模型

  鱼眼镜头的内参模型可以表示为,与普通镜头的内参一样,但畸变参数不同,为,含义如下:

  设(X,Y,Z)为一个三维坐标点,投影在图像上的二维坐标为(u,v),如果不考虑畸变,投影关系如下:

  

  R和t分别代表相机外参中的旋转矩阵和平移向量。

  当考虑鱼眼镜头的畸变后,投影关系转化为:

  (x'/x = seta'/r相似比相等)

标定流程

  首先调用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。

  左边为源图像,右边为去畸变结果:

你可能感兴趣的:(鱼眼相机)