分享

(学习笔记)摄像机模型与标定——标定函数

 学海无涯GL 2014-04-10

摄像机内参数,能够让我们将3D坐标转换为2D图像坐标。

说明:要理解下面的函数中参数的真实用法还需要阅读一下相机标定程序。

摄像机标定函数:

  1. void cvCalibrateCamera2(  
  2. CvMat* object_points,  
  3. CvMat* image_points,  
  4. int* point_counts,  
  5. CvSize image_size,  
  6. CvMat* intrinsic_matrix,  
  7. CvMat* distortion_coeffs,  
  8. CvMat* rotation_vectors = NULL,  
  9. CvMat* translation_vectors = NULL,  
  10. int flags = 0  
  11. );  

1、object_points,是一个N×3的矩阵,如果对于每一个棋盘,我们有k个角点,并且我们通过旋转棋盘,得到棋盘的M的视场图,那么此时N=k×M。

在使用棋盘的场合,我们另点z的坐标值为0,而x,y坐标用里面来度量,选用英寸单位,那么所有参数计算的结果也是用英寸表示。类似地,如果设置所有x坐标为0(而不是z坐标),那么意味着与摄像机相关的棋盘位置将主要在x方向上而不是在z方向上。棋盘上的正方形定义了一个单位,即如果正方形的边长为90mm,那么物体和摄像机坐标单位应该是mm/90。最简单的方式是我们定义棋盘的每一个方块为一个单位。

2、image_points,是一个N×2的矩阵。包含object_points所提供的所有点的坐标。即算法在图像中寻找到的角点的坐标。

3、point_counts,每个图像上角点的个数,以M×1矩阵形式提供,M是视场的数目

4、image_size,图像的大小,以像素为衡量单位。

5、intrinsic_matrix,摄像机内参数矩阵3×3大小。可以作为输入变量(此时会影响计算的结果),可以作为输出变量(本来主要就是为了求解该参数),内参数矩阵完全定义了理想摄像机模型的摄像机行为。

6、distortion_matrix,畸变系数,为5×1大小的矢量,可以作为输入变量,可以作为输出变量(同上),畸变系数的记录顺序是:k1,k2,p1,p2,k3

7、rotation_vectors,大小为M×3,M为视场的个数。旋转矢量的讲解参考上一篇文章。可以通过cvRodrigues2()将旋转矢量转换为旋转矩阵。

8、translation_vectors,大小为M×3矩阵。

函数中的标志位:

1、CV_CALIB_USE_INTRINSIC_GUESS  cvCalibrateCamera2()计算内参数矩阵的时候,通常不需要额外的信息。具体来说,参数cx和cy(图像中心)的初始值可以直接从变量image_size中得到(即(H-1)/2,(W-1)/2)),如果设置了该变量那么instrinsic_matrix假设包含正确的值,并被用作初始猜测,为cvCalibrateCamera2()做优化时所用。


2、CV_CALIB_USE_PRINCIPAL_POINT 可以和CV_CALIB_USE_INTRINSIC_GUESS 一起使用。如果设置了该标志位,那么设置图像的中心作为主点。如果一起使用,则设置主点位置为intrinsic_matrix矩阵提供的初始值。(这也是为什么,instrinsic_matrix不仅可以作为输出,也可以作为输入的原因了)


3、CV_CALIB_FIX_ASPECT_RATIO 如果设置了该标志位,那么在调用标定程序时,优化过程只同时改变fx和fy,而固定intrinsic_matrix的其他值(如果 CV_CALIB_USE_INTRINSIC_GUESS也没有被设置,则intrinsic_matrix中的fx和fy可以为任何值,但比例相关)。


4、CV_CALIB_FIX_FOCAL_LENGTH 该标志位在优化的时候,直接使用intrinsic_matrix传递过来的fx和fy。


5、CV_CALIB_FIX_K1,CV_CALIB_FIX_K2,CV_CALIB_FIX_K3 固定径向畸变k1,k2,k3。径向畸变参数可以通过组合这些标志设置为任意值。一般地最后一个参数应设置为0,初始使用鱼眼透镜。


6、CV_CALIB_ZERO_TANGENT_DIST 该标志在标定高级摄像机的时候比较重要,因为精确制作将导致很小的径向畸变。试图将参数拟合0会导致噪声干扰和数值不稳定。通过设置该标志可以关闭切向畸变参数p1和p2的拟合,即设置两个参数为0。


只计算外参数


函数cvFindExtrinsicCameraParam2()只计算外参数,接口如下:

  1. void cvFindExtrinsicCameraParams2(  
  2. const CvMat* object_points,  
  3. const CvMat* image_points,  
  4. const CvMat* intrinsic_matrix,  
  5. const CvMat* distortion_coeffs,  
  6. CvMat* rotation_vector,  
  7. CvMat* translation_vector  
  8. );  

函数的形参和标定函数是一样的,只是内参数矩阵和畸变系数是直接提供,而非计算得到的。


矫正


标定摄像机通常想做两件事情:

1)矫正畸变效应

2)根据获得的图像重构三维场景


“矫正”是数学上去掉透镜畸变

“校正”是数学上将图像排列整齐。


OpenCV提供了直接使用的校正算法,下面两个方法均能完成矫正:

1)直接一次性调用函数cvUndistort2()完成。

2)通过函数cvInitUndistortMap()和cvRemap()来更有效的处理,通常适合处理视频,或从同一个摄像机得到多个图像的应用。(其实很好理解的,我们利用一帧图像计算畸变映射,将后面的图像帧均利用该映射,并且计算畸变映射是一个耗时的操作)。


cvInitUndistortMap()函数计算畸变映射。

cvRemap()表示在任意图像上应用该映射。


  1. // Undistort images  
  2. void cvInitUndistortMap(  
  3. const CvMat* intrinsic_matrix,//内参数矩阵  
  4. const CvMat* distortion_coeffs,//畸变系数  
  5. cvArr* mapx,//32位单通道矩阵  
  6. cvArr* mapy  
  7. );  
  8. void cvRemap(  
  9. const CvArr* src,  
  10. CvArr *dst,  
  11. const CvArr *mapx,  
  12. const CvArr *mapy,  
  13. int flags=CV INTER LINEAR+CV WARP FILL OUTLIERS,  
  14. CvScalar fillval=cvScalarAll(0) );  
  15. void cvUndistort2(  
  16. const CvArr* src,  
  17. CvArr* dst,  
  18. const cvMat* intrinsic_matrix,  
  19. const cvMat* distortion_coeffs  
  20. );  
  21. // Undistort a list of 2D points only  
  22. void cvUndistortPoints( //函数的功能:将一些列来至于原始图像的2维点坐标并且计算相应的矫正点坐标。  
  23. const CvMat* _src,   
  24. CvMat* dst,   
  25. const CvMat* intrinsic_matrix,   
  26. const CvMat* distortion_coeffs,  
  27. const CvMat* R = 0,//R表示两个摄像机之间的旋转矩阵  
  28. const CvMat* Mr = 0; //Mr表示矫正后的摄像机内参数。  
  29. );  




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多