相机标定中 calibrateCamera函数介绍



本文转自:http://blog.youkuaiyun.com/ychl87/article/details/11473593

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

其中(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中的标定模块常用的标定函数:

  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>  
<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>


其中

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的使用例子:

  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>  
<span style="font-size: 18px;">	int cols = 10;
	int rows = 7;
	float distance = 30;	//间距30mm

	cv::Size patternSize(cols,rows);
	std::vector<cv::Point2f> corners;
	std::vector<std::vector<cv::Point2f>> cornersVect;
	std::vector<cv::Point3f> worldPoints;
	std::vector<std::vector<cv::Point3f>> worldPointsVect;

	for (int i=0;i<cols;i++)
	{
		for (int j=0;j<rows;j++)
		{
			worldPoints.push_back(cv::Point3f(i*distance,j*distance,0));
		}
	}
	
	bool find=cv::findChessboardCorners(image,patternSize,corners);
	cv::drawChessboardCorners(image,patternSize,corners,find);
	cv::Mat cameraMatirx,distCoeffs;
	std::vector<cv::Mat> rvecs,tvecs,rvecs2,tvecs2;
	if (find)
	{	
		cornersVect.push_back(corners);
		worldPointsVect.push_back(worldPoints);
		cv::calibrateCamera(worldPointsVect,cornersVect,image.size(),cameraMatirx,distCoeffs,rvecs,tvecs);
	}</span>

<think>好的,我现在需要帮助用户了解OpenCV中的calibrateCamera函数的定义用法,特别是函数原型参数说明。首先,我得回顾一下自己对这个函数的理解,确保信息准确无误。 用户提到参考了站内引用[^1],里面链接到OpenCV的官方文档,所以我应该直接参考该文档来确保信息正确。首先,calibrateCamera函数属于相机校准3D重建模块,用于估计相机的内参、外参以及畸变系数。接下来需要详细列出函数原型,包括各个参数的含义数据类型。 记得用户要求使用中文回答,所以需要将参数说明翻译成中文,同时保持术语的准确性。例如,objectPoints对应物体空间中的点,imagePoints是图像中的对应点,imageSize是图像尺寸等。还要注意区分输入输出参数,比如cameraMatrixdistCoeffs既是输入也是输出,但通常作为输出参数使用。 然后,函数返回的重投影误差需要解释清楚,这是评估校准质量的重要指标。另外,flags参数的不同选项可能需要简要说明,但用户可能不需要太深入,所以保持简洁。例如,CALIB_FIX_PRINCIPAL_POINT表示固定主点坐标,这在某些校准场景下会用到。 接下来,要确保LaTeX格式正确。行内公式用$...$,比如图像坐标系中的点$(u, v)$,独立公式如相机模型需要用$$...$$。同时,需要检查是否有遗漏的参数或错误的数据类型,比如rvecstvecs是向量组成的列表,每个元素对应一个视图的外参。 最后,生成的相关问题要围绕相机校准展开,可能涉及其他函数如solvePnP、标定板类型、畸变校正等,这些都是用户可能会进一步提问的方向。确保问题具体且有引导性,帮助用户深入理解相关内容。</think>### OpenCV中calibrateCamera函数说明 #### 1. 函数定义 `calibrateCamera`用于计算相机的内参矩阵、畸变系数外参(旋转/平移向量),其原型如下: $$cv2.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, flags=0)$$ #### 2. 参数详解 | 参数 | 类型 | 说明 | |------|------|------| | `objectPoints` | vector<vector<Point3f>> | 世界坐标系中的三维点集合,每个视图对应一个点集 | | `imagePoints` | vector<vector<Point2f>> | 图像坐标系中对应的二维点集 | | `imageSize` | Size | 用于校准的图像分辨率$(w, h)$ | | `cameraMatrix` | InputOutputArray | 输出3×3内参矩阵$ \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} $ | | `distCoeffs` | InputOutputArray | 输出畸变系数向量$(k_1, k_2, p_1, p_2[, k_3[, ...]])$ | | `rvecs` | OutputArray | 每个视图的旋转向量(轴角表示)| | `tvecs` | OutputArray | 每个视图的平移向量 | | `flags` | int | 校准标志位,如`CALIB_FIX_PRINCIPAL_POINT`等 | #### 3. 返回值 返回重投影误差的均方根值(RMS),计算公式为: $$RMS = \sqrt{\frac{1}{n}\sum_{i=1}^{n}\| \hat{p}_i - p_i \|^2}$$ 其中$\hat{p}_i$为投影点,$p_i$为实际检测点 #### 4. 使用示例 ```python import cv2 obj_points = [...] # 世界坐标 img_points = [...] # 图像坐标 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera( obj_points, img_points, (640,480), None, None ) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值