博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
相机标定中 calibrateCamera函数介绍
阅读量:4158 次
发布时间:2019-05-26

本文共 3450 字,大约阅读时间需要 11 分钟。



本文转自:

世界坐标系的三维点投影到成像坐标系中的二维点的投影公式如下:

其中(X,Y,Z)为世界坐标系中的三维点;

u,v)为成像面坐标系中的二维点;

A为相机的内参数矩阵:(cx,cy)为主光轴点,一般为图像的中心;fxfy为焦距;

[R|t]为相机的外参数矩阵:R为旋转矩阵,t为位移矩阵;

上述公式的简单推理过程如下

考虑到镜头畸变

其中,k1,k2,k3,k4,k5k6为径向畸变,p1p2为轴向畸变。在opencv中,畸变矩阵的参数为(k1,k2,p1,p2[,k3[,k4,k5,k6]]])

Opencv中的标定模块常用的标定函数:

[cpp]
  1. <span style="font-size: 18px;">double calibrateCamera(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags=0)</span>  
double calibrateCamera(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags=0)

其中

objectPoints为世界坐标系中的点。在使用时,应该输入一个三维点的vectorvector,即vector<vector<Point3f>> objectPoints

imagePoints为其对应的图像点。和objectPoints一样,应该输入std::vector<std::vector<cv::Point2f>> imagePoints型的变量。

imageSize为图像的大小,在计算相机的内参数和畸变矩阵需要用到;

cameraMatrix为内参数矩阵。输入一个cv::Mat cameraMatrix即可。

distCoeffs为畸变矩阵。输入一个cv::Mat distCoeffs即可。

rvecs为旋转向量;应该输入一个cv::Matvector,即vector<cv::Mat> rvecs因为每个vector<Point3f>会得到一个rvecs。

tvecs为位移向量;和rvecs一样,也应该为vector<cv::Mat> tvecs。

flags为标定是所采用的算法。可如下某个或者某几个参数:

CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,在cameraMatrix矩阵中应该有fx,fy,cx,cy的估计值。否则的话,将初始化(cx,cy)图像的中心点,使用最小二乘估算出fxfy如果内参数矩阵和畸变居中已知的时候,应该标定模块中的solvePnP()函数计算外参数矩阵。

CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。

CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fxfy将会被忽略。只有fx/fy的比值在计算中会被用到。

CV_CALIB_ZERO_TANGENT_DIST:设定切向畸变参数(p1,p2)为零。

CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6:对应的径向畸变在优化中保持不变。如果设置了CV_CALIB_USE_INTRINSIC_GUESS参数,

CV_CALIB_RATIONAL_MODEL:计算k4k5k6三个畸变参数。如果没有设置,则只计算其它5个畸变参数。

在使用calibrateCamera标定前,一般使用findChessboardCorners()函数获得棋盘标定板的角点位置。

还需要注意的是,在目前的opencv版本中(opencv2.4),当需要计算获得内参数矩阵时,即不使用CV_CALIB_USE_INTRINSIC_GUESS参数时,要求输入的objectPoints的为平面标定模式,即Z轴都为零。否则会出错。

如果对calibrateCamera的详细算法感兴趣,可以阅读张正友的标定算法A Flexible New Technique for Camera Calibration。可以从google scholar上搜索下载。

calibrateCamera的使用例子:

[cpp]
  1. <span style="font-size: 18px;"int cols = 10;  
  2.     int rows = 7;  
  3.     float distance = 30;    //间距30mm  
  4.   
  5.     cv::Size patternSize(cols,rows);  
  6.     std::vector<cv::Point2f> corners;  
  7.     std::vector<std::vector<cv::Point2f>> cornersVect;  
  8.     std::vector<cv::Point3f> worldPoints;  
  9.     std::vector<std::vector<cv::Point3f>> worldPointsVect;  
  10.   
  11.     for (int i=0;i<cols;i++)  
  12.     {  
  13.         for (int j=0;j<rows;j++)  
  14.         {  
  15.             worldPoints.push_back(cv::Point3f(i*distance,j*distance,0));  
  16.         }  
  17.     }  
  18.       
  19.     bool find=cv::findChessboardCorners(image,patternSize,corners);  
  20.     cv::drawChessboardCorners(image,patternSize,corners,find);  
  21.     cv::Mat cameraMatirx,distCoeffs;  
  22.     std::vector<cv::Mat> rvecs,tvecs,rvecs2,tvecs2;  
  23.     if (find)  
  24.     {     
  25.         cornersVect.push_back(corners);  
  26.         worldPointsVect.push_back(worldPoints);  
  27.         cv::calibrateCamera(worldPointsVect,cornersVect,image.size(),cameraMatirx,distCoeffs,rvecs,tvecs);  
  28.     }</span>  
	int cols = 10;	int rows = 7;	float distance = 30;	//间距30mm	cv::Size patternSize(cols,rows);	std::vector
corners; std::vector
> cornersVect; std::vector
worldPoints; std::vector
> worldPointsVect; for (int i=0;i
rvecs,tvecs,rvecs2,tvecs2; if (find) { cornersVect.push_back(corners); worldPointsVect.push_back(worldPoints); cv::calibrateCamera(worldPointsVect,cornersVect,image.size(),cameraMatirx,distCoeffs,rvecs,tvecs); }
你可能感兴趣的文章
java多线程中的join方法详解
查看>>
ECLIPSE远程调试出现如下问题 ECLIPSE中调试代码提示找不到源
查看>>
java abstract修饰符
查看>>
数组分为两部分,使得其和相差最小
查看>>
有趣的排序——百度2017春招
查看>>
二叉树的最近公共祖先LCA
查看>>
数组中累加和为定值K的最长子数组长度
查看>>
素数对--腾讯2017校招编程
查看>>
JAVA集合--ArrayList实现原理
查看>>
synchronized与Lock
查看>>
数据库索引
查看>>
实现包含min,max,push,pop函数的栈
查看>>
实验2-6 字符型数据的输入输出
查看>>
实验3-5 编程初步
查看>>
实验4-1 逻辑量的编码和关系操作符
查看>>
实验5-2 for循环结构
查看>>
实验5-3 break语句和continue语句
查看>>
实验5-4 循环的嵌套
查看>>
实验5-5 循环的合并
查看>>
实验5-6 do-while循环结构
查看>>