基于OpenCV的相机标定
1.什么是相机标定
相机参数的估计过程称为相机标定。这意味着我们拥有关于相机的所有信息(参数或系数),这些信息用于确定真实世界中的3D点与其在该标定相机捕获的图像中的相应2D投影(像素)之间的精确关系。通常这意味着恢复两种参数。
内部参数相机/镜头系统。例如透镜的焦距、光学中心和径向畸变系数。 外部参数这是指相机相对于某些世界坐标系的方位(旋转和平移)。 使用几何标定估计的透镜参数来消除图像失真。
2.图像形成几何学
要理解标定的过程,我们首先需要了解成像几何。我们将从几何的角度来解释图像的形成。具体来说,我们将讨论三维点如何在图像平面上投影的数学问题。也就是说,你所需要知道的就是矩阵乘法。
2.1 设定
为了容易理解这个问题,假设你在房间里安装了一台照相机。给定三维点P在这个房间里,我们想要找到这个3D点的像素坐标(u,v)在相机拍摄的图像中。在这个设置中有三个坐标系在起作用。我们来解释一下
2.1.1 世界坐标系
世界坐标系和相机坐标系是通过旋转和平移联系起来的。这六个参数(3个用于旋转,3个用于平移)称为相机的外部参数。
要定义房间中点的位置,我们首先需要为这个房间定义一个坐标系。它需要做两件事:
- 原点:我们可以随意地把房间的一角作为原点。(0,0,0).
- X,Y,Z轴:我们还可以沿着地板上的二维定义房间的X轴和Y轴,沿着垂直墙定义房间的Z轴。
通过测量空间内任意点沿X、Y和Z轴与原点的距离来找到它的三维坐标。这个与房间相连的坐标系称为世界坐标系。在图中,它使用橙色轴显示。我们将使用粗体字体表示轴,用普通字体表示点的坐标。
这个房间的P点。在世界坐标系中,P的坐标只需沿三个轴测量该点距原点的距离,就可以找到该点的X、Y和Z坐标。
2.1.2 相机坐标系
把相机放在这个房间里,房间的图像将用相机拍摄.连接到这个相机上的三维坐标系. 将相机放在房间的原点,使其X Y和Z轴与房间的xyz轴对齐,则两个坐标系将是等同的.
如果将相机放在房间的任何地方,就需要找到三维房间(世界)坐标和三维相机坐标之间的关系
相机位于任意位置(tx,ty,,tz). 可以说相对于世界坐标来转换相机坐标,相机是相对于世界坐标系旋转的.
3D中的旋转是用三个参数捕捉的 三个参数可以看作yaw,pitch,roll.
将旋转编码为3x3矩阵旺旺便于数学操作. 世界坐标系和相机坐标系是由旋转矩阵R和一个三元平移矢量 t关联的
其关联方程是:
将旋转表示为一个矩阵,整理成更紧凑的形式
其中,外参矩阵 P是由下式给出的:
在射影几何学中,我们经常用一个有趣的坐标即齐次坐标表示,在坐标上附加一个额外的维度。笛卡尔坐标系中的三维点(X,Y,Z)可以在齐次坐标系中写成(X,Y,Z,1)。更广泛地说,齐次坐标中(X, Y, Z, W)点与笛卡尔坐标中的点(Xw,Yw,Zw)相同。齐次坐标允许我们用有限的数字来表示无限量。例如,无穷远处的点可以在齐次坐标系中表示为(1,1,1,0)。你可能会注意到我们在外参矩阵中使用了齐次坐标来表示世界坐标
2.1.3 图像坐标系
一旦我们通过对点世界坐标应用旋转和平移来获得相机三维坐标系中的点,我们就可以将该点投影到图像平面上以获得该点在图像中的位置。
在上面的图像中,我们看到的是一个点P,在相机坐标系中有坐标(Xc,Yc,Zc)。只是提醒一下,如果我们不知道这个点在相机坐标系中的坐标,我们可以使用外参矩阵变换它的世界坐标,从而使用外参矩阵获得相机坐标系中的坐标。上图显示了简单针孔相机的相机投影。
光学中心(针孔)用Oc表示,实际上在像面上形成点的倒像。为了数学上的方便,我们简单地做所有的计算,就好像图像平面在光学中心的前面一样,因为从传感器读出的图像可以轻微地旋转180度来补偿反转。实际上,这是不需要的。它甚至更简单:一个真正的相机传感器只是按照相反的顺序(从右到左)从最下面一行读出,然后从下到上读取每一行。通过这种方法,图像自动垂直形成,左右顺序正确。因此在实践中,不再需要旋转图像。
图像平面放置在距离光学中心f(焦距)的位置 三维点(Xc,Yc,Zc)的投影图像(x,y)则是:
这两个方程可以用矩阵形式重写:
矩阵K如下所示,称为内参矩阵并包含相机的内在参数
上述简单矩阵只显示焦距。然而,图像传感器中的像素可能不是方形的,因此我们可能有两个不同的焦距。f_x和f_y。光学中心(c_x, c_y)相机的中心可能与图像坐标系的中心不重合。 此外,相机传感器的x轴和y轴之间可能有一个小的倾斜γ \gammaγ。考虑到以上所有因素,相机矩阵可以重新编写为:
x和y像素坐标相对于图像的中心.在处理图像时,原点位于图像的左上角. 用(u,v)表示图像坐标,则有下式:
2.2 图像形成方法总结
将世界坐标系中的三维点投影到相机像素坐标上,有以下步骤:
- 利用由两个坐标系之间的旋转和平移组成的外部矩阵,将三维点从世界坐标转换为相机坐标。
- 在相机坐标系中,利用相机内部焦距、光心等参数构成的内部矩阵将新的三维点投影到图像平面上。
3.基于Opencv的相机标定原理
3.1 相机标定相关参数
要找到三维点在图像平面上的投影,我们首先需要使用外部参数(R和t)将点从世界坐标系转换为相机坐标系。
使用相机的内部参数,我们将点投影到图像平面上。 将世界坐标系中的三维点(Xw,Yw,Zw)与其在图像坐标系中的投影(u,v)相关的方程式如下所示:
内参矩阵K 外参包括:旋转矩阵R和平移向量t
内参矩阵K是上三角矩阵
其中
- fx,fy是x和y焦距 (通常是相同的)
- cx,cy是图像平面上光学中心的x和y坐标.使用图像的中心通常是一个足够好的近似
- γ是轴之间的倾斜度.通常是1
3.2 相机标定的目标
标定过程的目标是使用一组已知的三维点(Xw,Yw,Zw)及其对应的图像坐标(u、v),找到3×3矩阵K、3×3旋转矩阵R、3×1平移向量T。当我们得到相机的内部和外部参数值时,相机就被称为标定相机。总之,相机标定算法具有以下输入和输出:
输入:具有已知二维图像坐标和三维世界坐标的点的图像集合。 输出:3×3相机内参矩阵,每幅图像的旋转和平移。 注意OpenCV中,相机内部矩阵不包含倾斜参数。所以矩阵的形式是:
4 相机标定示例步骤
- 使用棋盘格模式定义真实世界坐标;
- 从不同的角度捕获棋盘的多个图像;
- 查找棋盘的2D坐标;
- 校准相机
思路
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
# ret 返回值
# mtx 内参矩阵
# dist 畸变矩阵
# rvecs 旋转向量
# tvecs 平移向量
利用rvecs和rvecs转R t时,遇到了问题
遇到的问题
https://blog.csdn.net/gxsheen/article/details/52636852
这篇文章讲解了如何通过opencv标定得到的向量如何转化为R t矩阵 但是,实际实践时出现了问题
在python接口下:
R = Rodrigues(rvec)
出现TypeError: Expected Ptr<cv::UMat> for argument '%s'
的问题
https://stackoverflow.com/questions/52119190/relative-rotation-between-pose-rvec
回答里面说了一下具体的方法,目前还没有找到解决办法
这个还需要进一步研究