您的位置:首页 > 运维架构

双目视觉学习总结(1)——相机标定

2015-09-29 15:54 411 查看
1.相机标定目标

相机标定的目标就是为了获得相机的内参数和相机的外参数,相机的内参数是(Sx,Sy,Cx,Cy,f)代表相机的内部结构参数,相机外参数是相机的旋转矩阵R和平移向量t。

参数说明:Sx和Sy代表相机芯片单个像素的物理尺寸Sx = 1/dx, Sy = 1/dy,单位是像素/毫米,一般情况下Sx=Sy,除非单个像素点在成像仪上是矩形而不是正方形。

Cx和Cy分别代表相机芯片的中心可能的偏移,这是因为芯片的安装通常无法绝对精准。

f代表相机的焦距,fx = f * Sx,fy=f * Sy。

2.针孔成像模型

相机模型中最简单的就是针孔模型也是运用最多的模型,首先介绍相机成像过程中定义的四个参考坐标系如图1.1所示:



图1.1 四个坐标系关系图



图1.2 图像坐标系与像素坐标系之间的关系图

世界坐标系:是客观三维空间的绝对坐标系,可以建立在任意位置。例如使用张正友的标定方法时,对于每张标定图,世界坐标系是建立在以标定板的左上角角点为原点,以标定板平面为XY平面,Z轴垂直标定板平面向上。

相机坐标系:以相机光心为坐标系的原点,以相机的光轴作为Z轴,X轴Y轴分别平行于图像坐标系的X轴Y轴。

图像坐标系:主点是光轴与图像平面的交点。图像坐标系以主点为原点。

像素坐标系:原点定义在图像平面的左上角位置。

3.坐标系转换关系

最终的转换关系为:



式中s为一个任意系数比例,目的是两边相等,左边一列是像素坐标系的齐次坐标,最右为世界坐标系的齐次坐标,这样就完成了从像素坐标系到世界坐标系的转换。转换的具体过程主要利用了小孔成像原理,相似三角形原理等。

4.透镜畸变

径向畸变来自于透镜形状,实际摄像机的透镜总是在成像仪的边缘产生显著的畸变。对于径向畸变,成像仪中心的畸变为0,随着向边缘移动,畸变越来越严重。通常,成像仪某点的径向畸变调整公式为:



切向畸变是由于透镜制造上的缺陷是的透镜本身与图像不平行而产生的。切向畸变使用两个额外的参数p1和p2来描述:



综合上述两公式,共有5个所需要的畸变参数。在opencv程序中,它们被放置在一个畸变向量中:(k1,k2,p1,p2,k3)。

关于单应性矩阵和张正友标定方法的具体算法推导即流程可以阅读《学习opencv》第11章 p423

5.opencv 标定代码示例

(部分代码,仅供参考)

bool CameraCalibration::getCalibrationResult(CameraResult* &cr)
{
FileOperator fo;
vector<string> files;
fo.getFiles(this->imageDir,this->imageFormat,files);

Mat cameraMatrix=Mat::eye(3, 3, CV_64F);
Mat distCoeffs=Mat::zeros(5, 1, CV_64F);
Size boardSize=Size(this->chessBoardW,this->chessBoardH);
vector<Mat> rvecs;
vector<Mat> tvecs;

vector<Point2f> pointbuf;
vector<vector<Point2f>> imagePoints;
vector<vector<Point2f>> validImagePoints;
vector<bool> foundLabel;

Size imgSize;
bool found;
for(int i=0;i<files.size();i++)
{
Mat view,viewGray;
view=imread(files.at(i));
if(imgSize.area()==0)
{
imgSize=view.size();
}
cvtColor(view,viewGray,COLOR_BGR2GRAY);
found=findChessboardCorners( view, boardSize, pointbuf,
CV_CALIB_CB_ADAPTIVE_THRESH);
cornerSubPix( viewGray, pointbuf, Size(10,10),
Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

foundLabel.push_back(found);
imagePoints.push_back(pointbuf);
pointbuf.clear();
}

vector<vector<Point3f>> objectPoints(1);
calcChessboardCorners(boardSize,this->squareWidth,objectPoints[0]);

for(int i=0;i<foundLabel.size();i++)
{
if(foundLabel.at(i))
{
validImagePoints.push_back(imagePoints.at(i));
}
}
objectPoints.resize(validImagePoints.size(),objectPoints[0]);

if(validImagePoints.size()==0)
{
return false;
}

int error=calibrateCamera(objectPoints,validImagePoints,imgSize,cameraMatrix,distCoeffs,rvecs,tvecs,CV_CALIB_FIX_K3,TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,100,DBL_EPSILON));
cr=new CameraResult(cameraMatrix,distCoeffs,rvecs,tvecs,imagePoints,imgSize,foundLabel);
return true;
}


至于标定过程中更细节的实现步骤,opencv中焦距和偏移的求解算法是使用[2]中的方法,求解畸变参数的算法是使用[3]中的方法。

6.参考文献

1.G. Bradski. & A. Kaehler. 学习opencv[M]. 北京:清华大学出版社, 2009.

2.Z. Zhang. A Flexible New Technique for Camera Calibration[J]. IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, 2000, 22(11): 1330-1334

3.D. C. Brown, Colse-range camera calibration, Photogrammetric Engineering 37(1971):855-866.

4.冯焕飞. 三维重建中的相机标定方法研究[D]. 重庆:重庆交通大学, 2013.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv 双目视觉