数字图像处理 --- 相机的内参与外参(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.rhkb.cn/news/87980.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习笔记第五十七天(Pandas 数据清洗)

Python学习笔记第五十七天 Pandas 数据清洗Pandas 清洗空值isnull() Pandas替换单元格mean()median()mode() Pandas 清洗格式错误数据Pandas 清洗错误数据Pandas 清洗重复数据duplicated()drop_duplicates() 后记 Pandas 数据清洗 数据清洗是对一些没有用的数据进行处理的过程…

Thinkphp6在线预约按摩系统H5对接杉德宝支付开发 第三方支付平台

在线预约按摩系统后端使用的是thinkphp6开发的 前端是使用uniapp开发的,在微信浏览器里面一打开就会自动授权登录 1、在\app\common.php底部增加一个打印测试使用的 if (!function_exists(ljLog)) {function ljLog($data, $logNameDEBUG, $fname"testlog&…

Qt做警告处理界面

解决的问题: 做上位机时,多有检测仪器状态,事实显示警告,错误等状态,笔者就是需要显示各种仪器状态,做显示,后做出处理逻辑 Axure设计图: 需求:更新状态,根…

考研算法第40天:众数 【模拟,简单题】

题目 本题收获 又是一道比较简单的模拟题,就不说解题思路了,说一下中间遇到的问题吧,就是说cin输入它是碰到空格就停止输入的,详细的看下面这篇博客对于cin提取输入流遇到空格的问题_while(cin) 空格_就是那个党伟的博客-CSDN博…

KafkaStream:Springboot中集成

1、在kafka-demo中创建配置类 配置kafka参数 package com.heima.kafkademo.config;import lombok.Data; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.StreamsConfig; import org.springframework.boot.context.properties.Configu…

C#引用Web Service 类型方法,添加搜索本地服务器Web Service 接口调用方法

首先保证现在网络能调用web service接口,右键项目添加服务引用 ![![在这里插入图片描述](https://img-blog.csdnimg.cn/555ba4fa5e2a418f8f85539a9406bcd6.png) 点击高级 添加web服务 输入搜索的服务器接口,选中你要添加调用的方法即可 添加完成调用方…

【快应用】list组件如何区分滑动的方向?

【关键词】 list组件、滑动方向、scroll 【问题背景】 有cp反馈list这个组件在使用的时候,不知道如何区分它是上滑还是下滑。 【问题分析】 list组件除了通用事件之外,还提供了scroll、scrollbottom、scrolltop、scrollend、scrolltouchup事件&#x…

Zookeeper集群

目录 一、Zookeeper 概述 1)Zookeeper 定义 2)Zookeeper 工作机制 3)Zookeeper 特点 4)Zookeeper 数据结构 5)Zookeeper 应用场景 6)Zookeeper 选举机制 ●第一次启动选举机制 ●非第一次启动选举机…

智能质检技术的核心环节:语音识别和自然语言处理

随着呼叫中心行业的快速发展和客户服务需求的不断提高,越来越多的企业开始采用智能质检技术,以提高呼叫中心的质量和效率。而在智能质检技术中,语音识别和自然语言处理是其核心环节,对于提高质检的准确性和效率具有重要作用。 语音…

python爬虫5:requests库-案例3

python爬虫5:requests库-案例3 前言 ​ python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论,并不会对网…

centos7 nginx1.18.0离线升级至1.25.1

centos7 nginx1.18.0离线升级至1.25.1 项目背景 系统:centos 7 nginx版本: 1.18.0 最近护网行动查出来 有关Nginx的几个安全漏洞,解决方案只需要更新Nginx版本到最新即可。 Nginx升级过程 1. 下载新版本nginx 下载地址:https:…

SpringBoot复习:(41)配置文件中配置的server开头的属性是怎么配置到Servlet容器中起作用的?

ServletWebServerFactoryAutoConfiguration类: 可以看到其中使用了EnableConfigurationProperties导入了ServerProperties 而ServerProperties通过使用ConfigurationProperties注解导入了配置文件中已server开头的那些配置项。 可以看到ServletWebServerFactory定…

Centos7.6 安装mysql过程全记录

在centos 7.6上 离线安装mysql 的步骤,可参考下文: 一、查看当前MySQL的安装情况并卸载 1. 查看当前MySQL的安装情况 查找之前是否安装了MySQL rpm -qa|grep -i mysql 2.卸载mysql 如果已经安装mysql,则需要先停止MySQL,再删除…

前后端分离------后端创建笔记(03)前后端对接(上)

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论,如有侵权请联系 源码:https://gitee.com/green_vegetables/x-admin-project.git 素材:https://pan.baidu.com/s/…

Mybatis动态SQL

此文章为笔记,为阅读其他文章的感受、补充、记录、练习、汇总,非原创,感谢每个知识分享者。 文章目录 一、MyBatis动态 sql 是什么二、MyBatis标签三、MyBatis关联查询 一、MyBatis动态 sql 是什么 动态 SQL 是 MyBatis 的强大特性之一。在 …

JavaWeb 中对 HTTP 协议的学习

HTTP1 Web概述1.1 Web和JavaWeb的概念1.2 JavaWeb技术栈1.2.1 B/S架构1.2.2 静态资源1.2.3 动态资源1.2.4 数据库1.2.5 HTTP协议1.2.6 Web服务器 1.3 Web核心 2 HTTP2.1 简介2.2 请求数据格式2.2.1 格式介绍2.2.2 实例演示 2.3 响应数据格式2.3.1 格式介绍2.3.2 响应状态码2.3.…

Nonebot实战之编写插件1

前言 应粉丝群内粉丝要求,我也决定写一个Nonebot插件编写教程,从0开始教学。有些不对的地方也欢迎大家指正,修改。 开始 准备 合适的代码编辑器一定的python基础懂得提问的方式 代码编辑器 代码编辑器有很多种选择,比如 vsc…

TFRecords详解

内容目录 TFRecords 是什么序列化(Serialization)tf.data 图像序列化(Serializing Images)tf.Example函数封装 小结 TFRecords 是什么 TPU拥有八个核心,充当八个独立的工作单元。我们可以通过将数据集分成多个文件或分片(shards)…

Redis 搭建分片集群

文章目录 0.10.2 散列插槽0.3 集群伸缩0.3.1 需求分析0.3.1 创建新的 Redis 实例0.3.3 添加新节点到 Redis0.3.4 转移插槽 0.4 故障转移0.4.1 自动故障转移0.4.2 生动故障转移 0.5 RedisTemplate访问分片集群 1. 集群架构2. 准备实例和配置3. 启动4. 创建集群5. 测试 0.1 主从…

企业服务器被devos勒索病毒攻击后怎么处理,devos勒索病毒如何攻击的

众所周知,科学技术是第一生产力,科学技术的发展给企业与人们的生活带来了极大变化,但随之而来的网络安全威胁也不断增加。最近,我们收到很多企业的求助,企业的计算机服务器遭到了devos勒索病毒的攻击,导致企…