草庐IT

相机的内外参与相机标定

Matrix_11 2024-02-23 原文

相机的内外参与相机标定

我们所生活的现实世界是一个三维的世界,人类生活期间,已经能够熟练地估计周围物体的深度及定位,但是,现在的照相机一般都只能拍摄二维图像,场景从三维变到二维的时候,一个最重要的信息,深度,就丢失了,在只是为了观赏的时候,一个二维的图像也是足够的,如果想做导航,定位及其它3D 重建等应用的时候,这个深度信息及物体之间的相对关系,距离就显得很重要了,如何从二维图像,估计出真实的三维世界,也是计算机视觉一个比较重要的任务,由此发展出多视几何,计算几何等学科。

相机的内外参估计,是几何测量的基础,相机的内外参,构建了三维世界坐标系到图像坐标系的变换关系,也就是完成了一个三维坐标到二维坐标的映射。相机的内外参,对我们理解相机成像模型也有很大的帮助。

我们先给出如下的定义:

  • 世界坐标系, P w = ( x w , y w , z w ) P_w = (x_w, y_w, z_w) Pw=(xw,yw,zw), 原点为 O w O_w Ow,这个原点可以是三维世界的任意一个点
  • 相机坐标系, P c = ( x c , y c , z c ) P_c = (x_c, y_c, z_c) Pc=(xc,yc,zc), 原点为 O c O_c Oc,一般把相机的原点设置在相机的光心处
  • 图像坐标系, P i = ( u i , v i , 1 ) P_i = (u_i, v_i, 1) Pi=(ui,vi,1), 原点为 O i O_i Oi,一般把图像的左上角设为图像坐标系的原点
相机外参

世界坐标系的一个点 P w P_w Pw,如果以相机作为参考系,相机原点在世界坐标系中的坐标为 O c O_c Oc,则该点的坐标就变成了 P w − C P_w - C PwC C C C 表示世界坐标系的原点与相机坐标系原点之间的偏移量,这个比较好理解,我们以二维平面坐标为例,如果二维坐标的原点为 (0, 0),那么在二维坐标系中的一个点为 (2, 3),如果相机的原点就在 (2, 3),那么以相机作为参考,该点的坐标就是 (0, 0),所以世界坐标系中的一个点在相机坐标系中有一个平移的关系。

另外,由于相机本身在三维坐标系中,会发生不同角度的旋转,就是我们常说的 pitch, yaw, roll,所以相机坐标系的三个坐标轴与世界坐标系的三个坐标轴,会存在三个夹角,所以相机坐标系中的一个点与世界坐标系中的一个点的关系满足如下的式子:

P c = R ( P w − C ) P_c = \mathbf{R}(P_w - C) Pc=R(PwC)

上式中的 R \mathbf{R} R 表示一个旋转矩阵, C C C 表示世界坐标系的原点与相机坐标系原点之间的偏移量,这两个量构成了相机的外参,将世界坐标系与相机坐标系联系起来了。

相机内参

接下来,我们再看一下相机的内参,相机的内参主要表示相机坐标系到图像坐标系的映射,在相机坐标系中,真实世界的一个点还是一个三维的点, P c = ( x c , y c , z c ) P_c = (x_c, y_c, z_c) Pc=(xc,yc,zc),但是投影到图像坐标系之后,深度消失了,也就是 z c z_c zc 消失了,只剩下 x c , y c x_c, y_c xc,yc,假设相机镜头的焦距为 f f f,在小孔成像模型中,像平面就在焦距 f f f 处,根据简单的三角关系,我们可以推出:

u i = f x c z c v i = f y c z c u_i = f \frac{x_c}{z_c} \quad v_i = f \frac{y_c}{z_c} ui=fzcxcvi=fzcyc

上面的式子说明了相机坐标系与图像坐标系存在一个尺度的变化,这个尺度和点的物距有关,这个式子也很好的解释了为什么小孔成像中会有近大远小的关系。

不过,上面的式子,像平面的原点是在像平面与主光轴的交点处,也就是图像的中心,我们一般设定的图像原点在图像的左上角,为了适配这种关系,可以给上面的式子再加一个平移量,则上式变为:

u i = f x c z c + p u v i = f y c z c + p v u_i = f \frac{x_c}{z_c} + p_u \quad v_i = f \frac{y_c}{z_c} + p_v ui=fzcxc+puvi=fzcyc+pv

上面的式子换成矩阵形式:

z c [ u i v i 1 ] = [ f 0 p u 0 f p v 0 0 1 ] [ x c y c z c ] z_c \begin{bmatrix} u_i \\ v_i \\ 1 \end{bmatrix} = \begin{bmatrix} f & 0 & p_u \\ 0 & f & p_v \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_c \\ y_c \\ z_c \end{bmatrix} zcuivi1=f000f0pupv1xcyczc

写成一个更紧凑的形式:

z c P i = K P c z_c P_i = \mathbf{K}P_c zcPi=KPc

上面这个式子描述了相机坐标系到图像坐标系的映射关系, z c z_c zc 表示一个点在相机坐标系下的深度, K \mathbf{K} K 表示相机内参矩阵

投影矩阵

现在,我们有了相机的外参,表示世界坐标系到相机坐标系的变换,也有了相机的内参,表示相机坐标系到图像坐标系的变换,那么将内外参联合起来,就可以得到世界坐标系到图像坐标系的映射:

z c P i = K P c = K R ( P w − C ) z_c P_i = \mathbf{K} P_c = \mathbf{K}\mathbf{R}(P_w - C) zcPi=KPc=KR(PwC)

为了写成一个更加紧凑的形式,引入齐次坐标,将世界坐标系写成 P w = ( x w , y w , z w , 1 ) P_w = (x_w, y_w, z_w, 1) Pw=(xw,yw,zw,1),则上述式子可以表示成:

z c P i = [ K R − K R C ] P w = H P w z_c P_i = \begin{bmatrix} \mathbf{K}\mathbf{R} & - \mathbf{K}\mathbf{R} C \end{bmatrix} P_w = \mathbf{H} P_w zcPi=[KRKRC]Pw=HPw

上式的 H \mathbf{H} H 是一个 3 × 4 3 \times 4 3×4 的投影矩阵,可以表示成:

H = K R [ I − C ] \mathbf{H} = \mathbf{K}\mathbf{R} \begin{bmatrix} \mathbf{I} & -C \end{bmatrix} H=KR[IC]

K \mathbf{K} K 就是相机内参矩阵, R \mathbf{R} R 是相机外参中的旋转矩阵, C C C 是平移量,上面的内参矩阵 K \mathbf{K} K 是理想的小孔成像模型,如果考虑到实际情况,更一般的内参矩阵会考虑到装配误差,像素的长宽不一致等问题,内参矩阵更一般的形式如下所示:

K = [ a x s p x 0 a y p y 0 0 1 ] \mathbf{K} = \begin{bmatrix} a_x & s & p_x \\ 0 & a_y & p_y \\ 0 & 0 & 1 \end{bmatrix} K=ax00say0pxpy1

其中,

a x = f d x a y = f d y a_x = \frac{f}{dx} \quad a_y = \frac{f}{dy} ax=dxfay=dyf

上式将尺度由实际的 mm 转换成像素为单位,dx,dy 表示单个像素的长宽值, p x , p y p_x, p_y px,py 也表示实际的像素个数

相机标定

为了得到相机的外参,内参,根据上面的表达式,可以通过精确地测量三维世界的坐标点和图像上的坐标点,建议对应关系,再求解线性方程,从而获得投影矩阵,然后再通过矩阵分析,获得相机的内参,外参,这种方法的缺陷就是需要知道精确的三维坐标,这个在实际使用的时候不太方便,在实际使用的时候,一般都是用张正友标定法,这个方法的具体细节后面可以找个时间单独讲,这里就大概介绍一下基本的流程,这个方法已经集成到 OpenCV 里了。

  • 准备一个标定板,比如黑白棋盘格,测量棋盘格格子的尺寸
  • 对需要标定的相机,从各个角度拍摄一组图像
  • 对获取的图像提取角点信息,获取角点在图像上的坐标,调用函数 cv2.findChessboardCorners
  • 进一步获取更精确的角点坐标,调用函数 cv2.cornerSubPix
  • 调用 OpenCV 的函数进行内外参的计算,调用函数 cv2.calibrateCamera
  • 最后会返回四组参数:mtx, dist, rvecs, tvecs
  • mtx 内参矩阵
  • dist 畸变系数
  • rvecs 外参的旋转矩阵
  • tvecs 外参的平移量
参考

CMU 计算摄影课 http://graphics.cs.cmu.edu/courses/15-463/

多视图几何基础——深入理解相机内外参数 https://zhuanlan.zhihu.com/p/54139614

相机标定的原理及实现 https://blog.csdn.net/weixin_43843780/article/details/89294131

有关相机的内外参与相机标定的更多相关文章

  1. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  2. 相机校准—外参矩阵 - 2

    在本文中,我们将探讨摄影机的外参,并通过Python中的一个实践示例来加强我们的理解。相机外参摄像头可以位于世界任何地方,并且可以指向任何方向。我们想从摄像机的角度来观察世界上的物体,这种从世界坐标系到摄像机坐标系的转换被称为摄像机外参。那么,我们怎样才能找到相机外参呢?一旦我们弄清楚相机是如何变换的,我们就可以找到从世界坐标系到相机坐标系的基变换的变化。我们将详细探讨这个想法。具体来说,我们需要知道相机是如何定位的,以及它在世界空间中的位置,有两种转换可以帮助我们:有助于确定摄影机方向的旋转变换。有助于移动相机的平移变换。让我们详细看看每一个。旋转通过旋转改变坐标让我们看一下将点旋转一个角度

  3. 有仰拍相机和俯拍相机时,俯拍相机中心和吸嘴中心的标定 - 2

    俯拍相机中心和吸嘴中心的标定文章目录俯拍相机中心和吸嘴中心的标定前言适用模型如下:一、使用一个标定片进行标定1.关键注意:2.标定步骤:二、使用一个L型的工件1.关键注意:2.标定步骤:总结前言在自动化设备领域,使用相机进行定位是很普遍存在的,而使用相机定位就必定会用到标定,本文介绍两种关于吸嘴上方的俯拍相机和吸嘴中心的标定方法(前提是带有仰拍相机和俯拍相机)。【还有很多相机的使用场景的标定方法将在以后的文章中进行阐述】适用模型如下:一、使用一个标定片进行标定1.关键注意:关键是使用两个相机的中心和识别偏差,得到两个相机的中心固定偏差。注:后续俯拍相机拍物料识别得到的偏差以吸嘴中心在俯拍相机中

  4. 相机内参标定,相机和激光雷达联合标定 - 2

    相机内参标定,相机和激光雷达联合标定一、相机标定原理1.1成像过程1.2标定详解二、相机和激光雷达联合标定2.1标定方法汇总2.2Autoware的安装与运行2.2.1安装方式2.2.2安装Autoware的依赖(Ubuntu16.04/kinetic)2.2.3编译Autoware1.创造工作空间2.下载Autoware源码3.其他依赖4.编译5.效果2.3Autoware标定激光雷达和相机的外参过程一、相机标定原理1.1成像过程现实物体在相机中的成像过程离不开世界坐标系、相机坐标系、图像坐标系以及像素坐标系,只有理解了这些才能对获取的图像进行准确的分析。成像过程:四个坐标系如下图所示:世界

  5. ruby-on-rails - 逐步参与,持续的 guest 用户与 Devise - 2

    我正在尝试在我的实用程序中设置渐进式参与,人们无需注册即可使用,例如notepad.cc和jsfiddle.net以及我计划在用户“写入”应用程序时为用户创建一个guest用户(使用Devise)。我在Devisewiki上找到了这个指南https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user它显示了如何在浏览器session期间创建访客用户。我想要的是用户在后续访问中继续使用相同的访客帐户,直到他注册为止,也许当我推出更多功能的订阅计划时。如何修改指南中的内容以实现此目的?上面链接的指南中的代码:

  6. 相机面试问题总结 - 2

    1,Camera基本工作原理答案:光线通过镜头Lens进入摄像头内部,然后经过IRFilter过滤红外光,最后到达sensor(传感器),senor分为按照材质可以分为CMOS和CCD两种,可以将光学信号转换为电信号,再通过内部的ADC电路转换为数字信号,然后传输给DSP(如果有的话,如果没有则以DVP的方式传送数据到基带芯片baseband,此时的数据格式RawData,后面有讲进行加工)加工处理,转换成RGB、YUV等格式输出。数据流是如何从sensor到APP的?上述描述结束后,在ISP处理后面的阶段,数据会进行分流,分为capture,preview,video等以供后续动作使用。例如

  7. Baumer工业相机VCX系列相机硬件触发流程和设置 - 2

    项目场景Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展性等特点。 Baumer堡盟VCX相机为堡盟全系列相机中的主流常用相机,性能强大、坚固可靠,易于集成,常用与一般行业的检测定位识别使用。问题描述工业相机的触发有多种方式:1.硬件触发:使用外部硬件设备来触发相机,如传感器或开关。2.软件触发:使用软件来触发相机,可以是手动的也可以是自动的。3.同步触发:使相机的触发与其他设备或系

  8. uniapp实现自定义相机 - 2

    自定义相机起因由于最近用uniapp调用原生相机容易出现闪退问题,找了很多教程又是压缩图片又是优化代码,我表示并没有太大作用!!实现自定义相机使用效果图拓展实现多种自定义相机水印相机身份证相机人像相机起因由于最近用uniapp调用原生相机容易出现闪退问题,找了很多教程又是压缩图片又是优化代码,我表示并没有太大作用!!于是开启了我的解决之路利用livePusher实现实现自定义相机拓展性挺强的,可以实现自定义水印、身份证拍摄、人像拍摄等这里我简单实现一个相机功能主要用于解决闪退Tip:这里需要创建nvue文件哦~创建camera.nvuetemplate> viewclass="pengke-c

  9. javascript - 在 Three.js 中向场景添加相机的原因? - 2

    虽然我已经将它传递给我的渲染方法,但我为什么要将它添加到场景中?我在存储库中看到的每个示例都将相机添加到场景中,例如weggl_geometries.但是在删除scene.add(camera)之后它仍然有效......初始化函数camera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,2000);camera.position.y=400;scene.add(camera);渲染函数renderer.render(scene,camera); 最佳答案

  10. javascript - 如何让我的文本标签始终面向相机?也许使用 Sprite ? - 2

    我在看两个例子,一个是Canvas交互对象,另一个是鼠标工具提示。我尝试将两者结合起来在每个单独的立方体上生成文本标签,这就是我目前所拥有的。但是,文本会随着旋转的立方体移动,并且有时会向后或向侧面显示文本。我怎样才能像鼠标工具提示(http://stemkoski.github.io/Three.js/Mouse-Tooltip.html)示例中那样将文本固定在Sprite中?我试图合并Sprite,但我不断收到错误。我不知道该怎么做。你能解释一下我该如何去做吗?谢谢。到目前为止,这是我的代码:three.jscanvas-interactive-cubesbody{font-fam

随机推荐