数字图像处理 --- 相机的内参与外参(CV学习笔记)

Pinhole Camera Model(针孔相机模型)

        针孔相机是一种没有镜头、只有一个小光圈的简单相机。 光线穿过光圈并在相机的另一侧呈现倒立的图像。为了建模方便,我们可以把物理成像平面(image plane)上的图像移到实际场景(3D object)和焦点(focal point)之间,把他想象成一个和物理成像平面等大小的虚拟图像平面(Virtual image plane),这样一来就不再是倒立的图像,而是直立图像。

 

        有了相机后,上图中的蓝色盒子就变成了相机,上图中的物理成像平面Image plane也被数字化到由一个个pixel组成的sensor上,并保存下来。因此,对于相机而言,上图中的焦点就是相机的镜头,而上图中的物理成像平面,需要被转换成像素平面(pixel plane),物理成像平面(image plane)与像素平面(pixel plane)大小相同,计量单位不同。物理成像平面的单位是一个物理单位,例如mm,,而像素平面实际上就是一个二维图像,他的单位实际上是某某pixel在图像中的第几行第几列。

为了后续的描述方便我们这里先定义四个坐标系:

1,二维像平面(焦平面)坐标系Image plane,原点为O_{i},坐标轴用x_{i}y_{i}表示。

2,二维图像坐标系pixel plane,原点为O_{p},坐标轴用u_{p}v_{p}表示。

3,三维相机坐标系pinhole plane/camera,原点为O_{c},坐标轴用x_{c}y_{c}z_{c}表示。

4,三维世界坐标系world,原点为O_{w},坐标轴用x_{w}y_{w}z_{w}表示。

        将3D世界场景映射成2D图像(像素平面pixel plane)总共分两步,第一步是把定义在世界坐标系中的实际3D物体映射到3D相机极坐标系中。相当于是把实际世界中的物体分别通过两个不同的坐标系来表示,然后通过找到这两个不同坐标系之间的差异,建立这两个坐标系之间的联系。这一转换关系就是下图中O_{w}O_{c}的转换。

        从3D世界坐标系(world coordinates)到3D相机坐标系(camera coordinates),需要用到外参(extrinsic parameters)或外参矩阵(extrinsic matrix)--->[R t]

        其次,从3D相机坐标系(camera coordinates)到2D像素坐标系(pixel plane)需要用到内参(intrinsic parameters)或内参矩阵(intrinsic matrix)--->K。同样是把成像后的图像,用两个不同的坐标系来表示,然后再建立这两个坐标系(物理成像坐标系与二维图像坐标系)之间的联系,使两者可以相互转换。


extrinsic parameters外参:世界坐标系到相机坐标系

        对于世界坐标系中的某一点大M而言,他本身是存在了,并不会因为我们有没有建立坐标系而受影响。但当我们人为的建立坐标系以后,这个点在我们所定义的坐标系下就有坐标值了。首先,对于点M而言,他在世界坐标系下可表示为M=[x_{w}^{M},y_{w}^{M},z_{w}^{M}],而在相机坐标系中M=[x_{c}^{M},y_{c}^{M},z_{c}^{M}],这是同一个点,只不过在不同的坐标系所对应的坐标值不同。(其中:x_{w}^{M}中的上角标“M”表示点M,下角标"w"表示世界坐标系worl,以此类推,关于下角标的定义可参照我上面定义的四个坐标系。)

         相机坐标系相对于世界坐标系而言,我们不能保证两个坐标系的原点完全重合,因此,对于x-y-z都存在一定的位移,由一个3x1矩阵t(translation)表示,其中每个元素分别对应了x-y-z方向上的位移:

t=\begin{bmatrix} t_{x}\\ t_{y}\\ t_{z} \end{bmatrix}

此外,我们也不能保证相机在拍照时没有任何角度的偏差,因此,这两个坐标系的坐标轴存在一个整体的旋转。由一个3x3矩阵R(rotation)表示:

R=\begin{bmatrix} r_{11} &r_{12} &r_{13} \\ r_{21} &r_{22} &r_{23} \\ r_{31} &r_{32} & r_{33} \end{bmatrix}

二者合并得到增广矩阵[R|t],使得:

[R|t]\begin{bmatrix} x_{w}^{M}\\ y_{w}^{M}\\ z_{w} ^{M}\end{bmatrix}=\begin{bmatrix} x_{c}^{M}\\ y_{c}^{M}\\ z_{c}^{M} \end{bmatrix} 

其中:

[R|t]=\begin{bmatrix} r_{11} &r_{12} &r_{13} & t_{x}\\ r_{21} & r_{22} &r_{23} & t_{y} \\ r_{31} &r_{32} &r_{33} & t_{z} \end{bmatrix}

        这一数学表达式的意义是:一个在世界坐标系中定义的点,如果要用相机坐标系来表示,可以用矩阵[R|t]左乘该点的世界坐标系坐标实现。

这样一来就完成了大M点在世界坐标系下的坐标值到相机坐标系下的坐标值的转化:

\begin{bmatrix} x_{c}^{M}\\ y_{c}^{M}\\ z_{c}^{M} \end{bmatrix} = \begin{bmatrix} r_{11} &r_{12} &r_{13} & t_{x}\\ r_{21} & r_{22} &r_{23} & t_{y} \\ r_{31} &r_{32} &r_{33} & t_{z} \end{bmatrix} \begin{bmatrix} x_{w}^{M}\\ y_{w}^{M}\\ z_{w}^{M}\\ 1 \end{bmatrix}


Intrinsic parameters内参:

        通过前面的研究,我们找到了世界坐标系与相机坐标系的联系,相当于学会了用相机坐标系来表示世界的物体(3D Object),现在,我们用相机坐标系来分别描述世界中的实际物体“挪到前面来的”物理成像平面中物体的像,即,在相机坐标系中用不同的坐标值定义了世界中的实际物体大M点虚拟成像平面上的像---小m点(图一),并找到他们之间的联系。

 (图一)

        O表示光心,也叫摄影中心。过光心做垂直于物理成像平面的直线叫主光轴(principal axis),垂点O主点(principal point)。光心O与主点O_{c}之间的距离为焦距f。

        现在,在相机坐标系中,我们令世界中的某一点大M的坐标值为M=[x_{c}^{M},y_{c}^{M},z_{c}^{M}]。在虚拟成像平面中所成的像为小m,且小m的坐标值为m=[x_{c}^{m},y_{c}^{m},z_{c}^{m}](注意:x-y-z的上角标,我用大写的M表示实际点大M所对应的坐标值,用小写的m表示虚拟成像平面中的点小m)。同时,我们令主光轴与相机坐标系中的z_{c}轴重合,单看相机坐标系中由y_{c}z_{c}轴组成的平面(图二),我们令大M在这一平面上的投影为M_{y},令小m在y_{c}-z_{c}平面上的投影为m_{y}

 (图二)

        在三角形O_{c}Om_{y}中,线段O_{c}O的长度为小m在z_{c}轴方向的坐标值z_{c}^{m},线段m_{y}O的长度为小m在y_{c}轴方向的坐标值y_{c}^{m}。在三角形O_{c}QM_{y}中,线段O_{c}Q的长度为z_{c}^{M},线段M_{y}Q的长度为y_{c}^{M}。根据三角形O_{c}Om_{y}与三角形O_{c}QM_{y}相似,可以建立如下关系:

z_{c}^{M}/z_{c}^{m}=y_{c}^{M}/{y_{c}^{m}}

        又因为小m点一定在物理成像平面上,则,在3D相机坐标系中,z_{c}^{m}恒等于等于焦距f,代入上式后得出:

z_{c}^{M}/f=y_{c}^{M}/{y_{c}^{m}}

{y_{c}^{m}}={f}*y_{c}^{M}/z_{c}^{M}

        同样,如果单看相机坐标系中的x_{c}z_{c}轴所组成的平面(见图三),且用M_{x}表示大M在这一平面上的投影,用m_{x}表示小m在x_{c}-z_{c}平面上的投影:

  (图三)

根据相似相似三角形 O_{c}Om_{x}与三角形O_{c}QM_{x},可以建立如下关系

z_{c}^{M}/z_{c}^{m}=x_{c}^{M}/{x_{c}^{m}}

z_{c}^{M}/{f}=x_{c}^{M}/{x_{c}^{m}}

{x_{c}^{m}}={f}*x_{c}^{M}/z_{c}^{M}

        这样一来,我们就建立了世界中的大M与虚拟成像平面上的对应点小m,在相机坐标系中的关系:

{x_{c}^{m}}={f}*x_{c}^{M}/z_{c}^{M}

{y_{c}^{m}}={f}*y_{c}^{M}/z_{c}^{M}

(上面两式合称为公式1


相机坐标系到像平面坐标系:

        又因为,虚拟成像平面中的小m点,不仅在3D相机坐标系中,也在2D像平面坐标系中。且,像平面坐标系的中心在主光轴上。这就意味着,对于同一个点光心O而言,他在相机坐标系下的坐标值和在2D像平面坐标系下的坐标值相同。即,光心在相机坐标系下的坐标值为[{x_{c}^{O}}=0,{y_{c}^{O}}=0],同时,他在2D像平面坐标系中的坐标值也等于[{x_{i}^{O}}=0,{y_{i}^{O}}=0]

        同理,已知相机坐标系中小m点的坐标值为m=[{x_{c}^{m}}{y_{c}^{m}}],令小m点在相平面中的坐标值为m=[{x_{i}^{m}}{y_{i}^{m}}],则有:

{x_{i}^{m}}={x_{c}^{m}}

{y_{i}^{m}}={y_{c}^{m}}

公式2

如图四所示:

 (图四)

这就完成了相机坐标系到像平面坐标系的转换。


像平面坐标系到图像坐标系:

        在相机内部,物理成像平面被sensor以pixel为单位采样了,且,图像坐标系的原点O_{p}在图像的左上角,见图五。因此,像平面坐标系中的小m点的坐标值,还需要一个转换关系。

 (图五)

        一方面,图像坐标系是用mxn个像素对像平面坐标系的采样。所以需要一个由mm为单位的像平面坐标系到以pixel为单位的图像坐标系的转换。

        假设图像传感器的物理尺寸,也就是物理成像平面的大小为mxn(mm),传感器保存的图像尺寸为wxh(pixel)。要想把mxn的像保存到wxh的图上,则,以mm为单位的物理成像平面与以pixel为单位的图像之间的比例关系为:

dx=m/w(mm/pixel)

dy=n/h(mm/pixel)

第一个等式表示,图像中每个pixel的物理尺寸有多宽mm。

第二个等式表示,图像中每个pixel的物理尺寸有多高mm。

        这样一来,就能用图像坐标系的坐标值(第几行第几列)来替换小m点在像平面坐标系中的坐标值(即,在x_{i}方向的长度为x_{i}^{m}(mm)和在y_{i}方向的长度为y_{i}^{m}(mm)):

u_{p}^{m}(pixel)=x_{i}^{m}(mm)/dx(mm/pixel)

v_{p}^{m}(pixel)=y_{i}^{m}(mm)/dy(mm/pixel)

公式3


        另一方面:二维图像坐标系的原点在图像(sensor)的左上角,而像平面坐标系的原点则是在senor的中心。因此,对于同一个点光心O而言,他在2D图像坐标系下的坐标值和在2D像平面坐标系下的坐标值不同,这两个坐标值之间存在一个偏移量Offset。我们在图像坐标系内定义u_{p}方向上O_{p}O_{i}的偏移量为u_{p}^{offset},他等于图像的宽度的一半---w/2,在v_{p}方向上O_{p}O_{i}的偏移量为v_{p}^{offset},他等于图像的长度的一半---h/2。

光心O在图像坐标系中的坐标值是:

{u_{p}^{O}}(pixel)={x_{i}^{O}}(mm)+{u_{p}^{offset}}(pixel)

{v_{p}^{O}}={y_{i}^{O}}+{v_{p}^{offset}}

公式4

其中:

{u_{p}^{offset}}=w/2(pixel)

{v_{p}^{offset}}=h/2(pixel)

        公式4的意思是:光心O在图像平面中的坐标值等于他在像平面中的坐标值加上一定的偏移量。同理,已经转换到图像坐标系内的小m点的坐标值(见公式3),加上Offset后为:

u_{p}^{m}(pixel)=x_{i}^{m}(mm)/dx(mm/pixel)+{u_{p}^{offset}}(pixel)

v_{p}^{m}(pixel)=y_{i}^{m}(mm)/dy(mm/pixel)+{v_{p}^{offset}}(pixel)

公式5) 

进一步,将公式2带入公式5后有:

u_{p}^{m}(pixel)=x_{c}^{m}(mm)/dx(mm/pixel)+{u_{p}^{offset}}(pixel)

v_{p}^{m}(pixel)=y_{c}^{m}(mm)/dy(mm/pixel)+{v_{p}^{offset}}(pixel)

然后再带入公式1,得到:

u_{p}^{m}(pixel)={f}*x_{c}^{M}/z_{c}^{M}(mm)/dx(mm/pixel)+{u_{p}^{offset}}(pixel)

v_{p}^{m}(pixel)={f}*y_{c}^{M}/z_{c}^{M}(mm)/dy(mm/pixel)+{v_{p}^{offset}}(pixel)

公式6

我们令f_{x}=f/d_{x},f_{y}=f/d_{y},则上式可简化为:

u_{p}^{m}(pixel)=f_{x}*x_{c}^{M}/z_{c}^{M}(pixel)+{u_{p}^{offset}}(pixel)

v_{p}^{m}(pixel)=f_{y}*y_{c}^{M}/z_{c}^{M}(pixel)+{v_{p}^{offset}}(pixel)

公式7

其中:

1,f_{x}表示以mm为单位的物理焦距f,在横向等于多少个像素。

2,f_{y}表示以mm为单位的物理焦距f,在竖向等于多少个像素。

 

公式7用矩阵的方式可表示为:

\begin{bmatrix}u_{p}^{m} \\v_{p}^{m} \\1 \end{bmatrix}=\begin{bmatrix} f_{x} & 0&u_{p}^{offset} \\ 0& f_{y} &v_{p}^{offset} \\ 0& 0& 1\end{bmatrix}\begin{bmatrix}x_{c}^{M}/z_{c}^{M} \\y_{c}^{M}/z_{c}^{M} \\1 \end{bmatrix}

其中的3x3矩阵,就叫内参矩阵,用大写的英文字母K表示。


 总结:

最后我们来梳理一下整个转换过程:

1,大M点在世界坐标系下的坐标值[x_{w}^{M},y_{w}^{M},z_{w}^{M}],通过外参矩阵[R t]得到了大M点在相机坐标系中的坐标值[x_{c}^{M},y_{c}^{M},z_{c}^{M}]。(通过同一点在不同坐标系中的坐标值,找到两个坐标系之间的关系。)

2,在相机坐标系中,根据相似三角形求出大M点在虚拟成像平面中所对应的小m点的坐标值[x_{c}^{m},y_{c}^{m},z_{c}^{m}]。(通过同一坐标系下的不同点,找到这两个点之间坐标值的联系)

3,根据虚拟成像平面在相机坐标系中的位置,根据小m点在相机坐标系下的坐标值[{x_{c}^{m}}{y_{c}^{m}}{z_{c}^{m}}=f]得到他在像平面坐标系下的坐标值[{x_{i}^{m}}={x_{c}^{m}}{y_{i}^{m}}={y_{c}^{m}}]。(通过同一点在不同坐标系中的坐标值,找到两个坐标系之间的关系。)

4,最后,根据像平面坐标系与图像坐标系的相对关系,通过内参矩阵把小m点在像平面中的坐标值[{x_{i}^{m}}{y_{i}^{m}}]转到了图像坐标系中所对应的坐标值[u_{p}^{m}v_{p}^{m}]。

参考文献:

        1,https://www.cnblogs.com/xiaohuidi/p/15711767.html

        2,What Is Camera Calibration?- MATLAB & Simulink- MathWorks 中国

        3,2.3 透视投影的相机模型_哔哩哔哩_bilibili

版权声明:文中的部分图片,文字或者其他素材,可能来自很多不同的网站和说明,在此没法一一列出,如有侵权,请告知,立即删除。欢迎大家转载,但是,如果有人引用或者COPY我的文章,必须在你的文章中注明你所使用的图片或者文字来自于我的文章,否则,侵权必究。 ----松下J27 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/70526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring-2-透彻理解Spring 注解方式创建Bean--IOC

今日目标 学习使用XML配置第三方Bean 掌握纯注解开发定义Bean对象 掌握纯注解开发IOC模式 1. 第三方资源配置管理 说明:以管理DataSource连接池对象为例讲解第三方资源配置管理 1.1 XML管理Druid连接池(第三方Bean)对象【重点】 数据库准备 -- 创建数据库 create …

Python基础小项目

今天给大家写一期特别基础的Python小项目,欢迎大家支持,并给出自己的完善修改 (因为我写的都是很基础的,运行速率不是很好的 目录 1. 地铁票价题目程序源码运行截图 2. 购物车题目程序源码运行截图 3. 名片管理器题目程序源码运行…

opencv实战项目 实现手势跟踪并返回位置信息(封装调用)

OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 需要提前准备opencv 和 mediapipe库 pip --default-timeout5000 install -i https://pypi.tuna.tsi…

nodejs+vue+elementui社区流浪猫狗救助救援网站_4a4i2

基于此背景,本研究结合管理员即时发布流浪猫狗救助救援信息与用户的需求,设计并实现了流浪猫狗救助救援网站。系统采用B/S架构,java语言作为主要开发语言,MySQL技术创建和管理数据库。系统主要分为管理员和用户两大功能模块。通过…

【Linux取经路】进程的奥秘

文章目录 1、什么是进程?1.1 自己写一个进程 2、操作系统如何管理进程?2.1 描述进程-PCB2.2 组织进程2.3 深入理解进程 3、Linux环境下的进程3.1 task_struct3.2 task_struct内容分类3.3 组织进程3.4 查看进程属性 4、结语 1、什么是进程? 在…

FreeRTOS

FreeRTOS官网:www.freertos.org 调度 实时操作系统 特点:如果有一个任务需要执行,实时操作系统会马上(在较短时间内)执行该任务,不会有较长的延时。这种特性保证了各个任务的及时执行。 实现方式&#…

web前端之CSS操作

文章目录 一、CSS操作1.1 html元素的style属性1.2 元素节点的style属性1.3 cssText属性 二、事件2.1 事件处理程序2.1.1 html事件2.1.2 DOM0事件(适合单个事件)2.1.3 DOM2事件(适合多个事件) 2.2 事件之鼠标事件2.3 事件之Event事…

详解Kafka分区机制原理|Kafka 系列 二

Kafka 系列第二篇,详解分区机制原理。为了不错过更新,请大家将本号“设为星标”。 点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达 上一篇文章介绍了 Kafka 的基本概念和术语,里面有个概念是 分区(Part…

计算机竞赛 opencv python 深度学习垃圾图像分类系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 opencv python 深度学习垃圾分类系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 这是一个较为新颖的竞…

pytest结合 allure 打标记之的详细使用

前言 前面我们提到使用allure 可以生成漂亮的测试报告,下面就Allure 标记我们做详细介绍。 allure 标记 包含:epic,feature, story, title, testcase, issue, description, step, serverity, link, attachment 常用的标记 allure.feature…

Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理?

索引所占空间的增长确实会对MySQL数据库的写入性能和查询性能造成影响,这主要是由于索引数据过多时会导致磁盘I/O操作变得非常频繁,从而使性能下降。为此,可以采取以下几种方式来减缓这种影响: 1. 限制索引的大小:可以…

PHP8定义字符串的方法-PHP8知识详解

字符串,顾名思义,就是将一堆字符串联在一起。字符串简单的定义方法是使用英文单引号( )或英文双引号(" ")包含字符。另外,还可以使用定界符定义字符串。本文还介绍了字符串的连接符。…

数据结构和算法三(排序)

列表排序 排序类型&#xff1a; 一、冒泡排序&#xff1a; 屏幕录制2023-07-25 13.05.12 def bubble_sort(li):exchangeFalseif len(li)<1:return lifor i in range(len(li)-1):for j in range(len(li)-i-1):if li[j]>li[j1]:li[j],li[j1]li[j1],li[j]print(li)exchangeT…

mac harbor的安装

harbor的安装 为什么要整这个呢&#xff0c;因为我在学习k8s&#xff0c;但是需要一个自己的镜像仓库。于是&#xff0c;最开始想到的就是在本地直接部署一个&#xff0c;还比较安全、快速。 直接下载了官方的项目&#xff0c;运行脚本发现出了异常&#xff0c;这种异常我已经…

项目知识点记录

1.使用druid连接池 使用properties配置文件&#xff1a; driverClassName com.mysql.cj.jdbc.Driver url jdbc:mysql://localhost:3306/book?useSSLtrue&setUnicodetrue&charsetEncodingUTF-8&serverTimezoneGMT%2B8 username root password 123456 #初始化链接数…

LiveNVR监控流媒体Onvif/RTSP功能-视频流水印如何叠加视频水印叠加动态图片叠加视频流时间示例

LiveNVR视频流水印如何叠加视频水印叠加动态图片叠加视频流时间示例 1、介绍2、摄像头OSD设置水印3、前端页面叠加4、视频流水印4.1、图片水印示例4.2、时间戳水印示例 5、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、介绍 监控视频平台播放视频监控的时候&#xff0c;除了满足正…

SpringMVC的架构有什么优势?——控制器(三)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

CentOS 7中,配置了Oracle jdk,但是使用java -version验证时,出现的版本是OpenJDK,如何解决?

1.首先&#xff0c;检查已安装的jdk版本 sudo yum list installed | grep java2.移除、卸载圈红的系统自带的openjdk sudo yum remove java-1.7.0-openjdk.x86_64 sudo yum remove java-1.7.0-openjdk-headless.x86_64 sudo yum remove java-1.8.0-openjdk.x86_64 sudo yum r…

STM32单片机蓝牙APP宠物自动喂食器定时语音提醒喂食系统设计

实践制作DIY- GC00162---蓝牙APP宠物自动喂食器 一、功能说明&#xff1a; 基于STM32单片机设计---蓝牙APP宠物自动喂食器 二、功能说明&#xff1a; STM32F103C系列最小系统板LCD1602显示器DS1302时钟模块5个按键语音播报模块ULN2003步进电机模块LED灯板HC-05蓝牙模块&#x…

XML方式AOP快速入门XML方式AOP配置详解

目录 1.XML方式AOP快速入门 1&#xff1a;导入AOP相关坐标 2&#xff1a;准备目标类&#xff0c;准备增强类&#xff0c;并配置给Spring管理 3&#xff1a;配置切点表达式&#xff08;那些方法要被增强&#xff09; 4&#xff1a;配置织入&#xff08;切点被哪些方法增强&…
最新文章