相机标定中 calibrateCamera函数介绍
2015-05-02 16:03
357 查看
本文转自:http://blog.csdn.net/ychl87/article/details/11473593
世界坐标系的三维点投影到成像坐标系中的二维点的投影公式如下:
其中(X,Y,Z)为世界坐标系中的三维点;
(u,v)为成像面坐标系中的二维点;
A为相机的内参数矩阵:(cx,cy)为主光轴点,一般为图像的中心;fx和fy为焦距;
[R|t]为相机的外参数矩阵:R为旋转矩阵,t为位移矩阵;
上述公式的简单推理过程如下
考虑到镜头畸变
其中,k1,k2,k3,k4,k5和k6为径向畸变,p1和p2为轴向畸变。在opencv中,畸变矩阵的参数为(k1,k2,p1,p2[,k3[,k4,k5,k6]]])。
Opencv中的标定模块常用的标定函数:
[cpp]
view plaincopyprint?
<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为世界坐标系中的点。在使用时,应该输入一个三维点的vector的vector,即vector<vector<Point3f>> objectPoints。
imagePoints为其对应的图像点。和objectPoints一样,应该输入std::vector<std::vector<cv::Point2f>> imagePoints型的变量。
imageSize为图像的大小,在计算相机的内参数和畸变矩阵需要用到;
cameraMatrix为内参数矩阵。输入一个cv::Mat cameraMatrix即可。
distCoeffs为畸变矩阵。输入一个cv::Mat distCoeffs即可。
rvecs为旋转向量;应该输入一个cv::Mat的vector,即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)图像的中心点,使用最小二乘估算出fx,fy。如果内参数矩阵和畸变居中已知的时候,应该标定模块中的solvePnP()函数计算外参数矩阵。
CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。
CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有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:计算k4,k5,k6三个畸变参数。如果没有设置,则只计算其它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]
view plaincopyprint?
<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>
本文转自:http://blog.csdn.net/ychl87/article/details/11473593
世界坐标系的三维点投影到成像坐标系中的二维点的投影公式如下:
其中(X,Y,Z)为世界坐标系中的三维点;
(u,v)为成像面坐标系中的二维点;
A为相机的内参数矩阵:(cx,cy)为主光轴点,一般为图像的中心;fx和fy为焦距;
[R|t]为相机的外参数矩阵:R为旋转矩阵,t为位移矩阵;
上述公式的简单推理过程如下
考虑到镜头畸变
其中,k1,k2,k3,k4,k5和k6为径向畸变,p1和p2为轴向畸变。在opencv中,畸变矩阵的参数为(k1,k2,p1,p2[,k3[,k4,k5,k6]]])。
Opencv中的标定模块常用的标定函数:
[cpp]
view plaincopyprint?
<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为世界坐标系中的点。在使用时,应该输入一个三维点的vector的vector,即vector<vector<Point3f>> objectPoints。
imagePoints为其对应的图像点。和objectPoints一样,应该输入std::vector<std::vector<cv::Point2f>> imagePoints型的变量。
imageSize为图像的大小,在计算相机的内参数和畸变矩阵需要用到;
cameraMatrix为内参数矩阵。输入一个cv::Mat cameraMatrix即可。
distCoeffs为畸变矩阵。输入一个cv::Mat distCoeffs即可。
rvecs为旋转向量;应该输入一个cv::Mat的vector,即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)图像的中心点,使用最小二乘估算出fx,fy。如果内参数矩阵和畸变居中已知的时候,应该标定模块中的solvePnP()函数计算外参数矩阵。
CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。
CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有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:计算k4,k5,k6三个畸变参数。如果没有设置,则只计算其它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]
view plaincopyprint?
<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>
<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>
相关文章推荐
- 相机标定原理介绍(二)
- 相机标定原理———标定原理介绍
- 相机标定原理介绍
- OpenCV3.1.0的calibrateCamera()函数计算相机内参数
- 相机标定原理介绍(一)
- opencv中3D点根据相机参数投影成2D点+solvePnP函数计算相机姿态+2D坐标到3D+相机参数calibration(标定与配准,求得深度彩色相机的内参与外参,再进行配准)
- 自识别标记(self-identifying marker) -(2) 用于相机标定的CALTag介绍
- 相机标定原理介绍
- 摄像机模型与标定(二):opencv2相关函数介绍
- 相机标定原理介绍(一)
- 详细介绍Opencv实现张正友法相机标定
- 【OpenCV3学习笔记 】相机标定函数 calibrateCamera( ) 使用详解(附相机标定程序和数据)
- 相机标定原理———标定原理介绍
- ORACLE常用数值函数、转换函数、字符串函数介绍
- 一.Select 函数详细介绍【转】
- ORACLE常用数值函数、转换函数、字符串函数介绍
- 相机标定之三种坐标系间的映射关系
- C++文件读写函数介绍
- 常用函数介绍
- 单目相机标定原理