CV01_相机成像原理与坐标系之间的转换

目录

0.引言:小孔成像->映射表达式

1. 相机自身的运动如何表征?->外参矩阵E

1.1 旋转

1.2 平移

2. 如何投影到“像平面”?->内参矩阵K

2.1 图像平面坐标转换为像素坐标系      

3. 三维到二维的维度是如何丢失的?->透视变换

4. 坐标变换的应用

附:像平面投影实际的偏差问题

参考资料


0.引言:小孔成像->映射表达式

视觉包含着大量的信息,是几乎所有生物感知环境的主要工具,也是机器人的重要传感器之一,但是相机究竟是如何成像的呢?

现在我们假设一种情况:黑暗的环境下,空中有一个发光的小球,小球对面是铺满了墙壁的一张纸,我们会发现小球照亮了整个纸面,但是小球的二维投影圆却没有呈现在纸上。

现在我们再给一个平面放在小球和纸之间,这个平面中心有一个小孔,光透过小孔,我们发现纸面整体虽然变暗了,但是小球二维投影圆却能清晰看见了。这就是小孔成像。

但是小孔到底起着怎样的作用?从数学角度看,小孔就是一个映射或者函数表达式,它让“物点”与“像点”的空间位置有了一一对应的关系。如果没有“小孔”,那么物点会“漫射”到所有像点,自然不会呈现任何形状。

小孔成像就是相机的基本原理,因为镜头本身和小孔一样,也是一个映射。镜头将物点投射到图像传感器上,将光强信号转换到成电流信号,电流信号再由运算电路转化成数字信号,合成数字图像,就是照片。

下面我们就来具体求解这个镜头代表的映射函数的具体形式,从而构建物和像之间的数学关系。

1. 相机自身的运动如何表征?->外参矩阵E

首先,我们建立一个世界坐标系W,而我们的相机自身也有一个坐标系,我们称为相机坐标系C,而且相机坐标系C可以在世界坐标系W中运动,这就引出几个问题:

1.相机自身的运动如何表征?

2.世界坐标系中的“物点”投影到相机的成像平面,这又如何表示?

3.三维到二维的维度是如何丢失的?

4.这些坐标的变换有什么应用?

问题一个一个解决。我们先看第一个问题,为了明白背后的原理我先采用二维坐标(三维坐标是同理的),这样便于理解。

从世界坐标系变换到相机坐标系属于刚体变换。首先介绍刚体运动的概念:刚体(即形状和大小不变的理想化物体)进行的运动,这种运动保持了物体内部所有点之间的相对距离不变。刚体变换通常包括“平移”和”旋转“。

(注意说明旋转和平移时用的是二维举例,三维坐标系的原理是相同的,推广即可)

1.1 旋转

我们先看旋转。现在在二维空间(三维空间同理)有一点P,其W坐标系下(x,y),红色的相机坐标系原来与世界坐标系重合,现在其旋转了θ角:

那么,P点在做了旋转运动了的相机坐标系C下的坐标(x',y')是多少呢?

这个问题我们回头解决,我们先看一下二维平面内的旋转运动是如何表达的:

二维空间内一点P的坐标为(x,y),其绕原点旋转θ后得到P’的坐标是(x',y'),如何求x',y'?

假设OP连线与X轴夹角为 α,由于旋转不改变OP长度,所以有这个等式

\frac x{\cos\alpha}=\frac{x^{\prime}}{\cos{(\alpha+\theta)}}                     

利用和角公式展开可得到x',相似,我们也能得到y'

y'=x\sin\theta+y\cos\theta

我们利用线性代数的知识写成矩阵的形式,这就得到一个旋转矩阵R,也是一个二维的线性变换

\begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}

我们记作p'=Rp,R为上面的旋转矩阵。


我们回到刚才的问题,用同样的思路,还是有OP长度相等的关系,我们计算可得x'y'x^{\prime}=x\cos\theta+y\sin\theta\\y^{\prime}=-x\sin\theta+y\cos\theta

还是用矩阵来表达,我们就得到了一个坐标基变换的表达式

\begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}\cos\theta&\sin\theta\\-\sin\theta&\cos\theta\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}

上面的矩阵我们记作A,写作p'=Ap(其实这就是坐标基变换

矩阵A的作用就是对同一点不同坐标系下的表达式进行转化

如果我们把刚刚得到的R和A相乘,结果会发现是一个单位矩阵I,则A和R就是互逆的。换句话说:再量相同的情况下,旋转点和坐标系变换是互逆的操作。

\begin{aligned}\mathbf{AR}&=\begin{bmatrix}1&0\\0&1\end{bmatrix}=\mathbf{I}\\\mathbf{A}&=\mathbf{R}^{-1}\end{aligned}

这一点非常有用,也就是只要我们知道了相机的运动,就可以求表示相机运动的逆矩阵来求空间物点在运动后的相机坐标系下的表达

1.2 平移

上面的是旋转运动,下面我们看一下平移运动。

点P移动到P',(x',y')的坐标很容易得到。但是我们要注意,平移不是线性变换,也就是说我们不能用矩阵表示平移运动。但是如果我们硬要用矩阵来表示平移呢?----这就引出了齐次坐标(homogeneous)

我们可以用如下方式表示点P的平移

\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}1&0&a\\0&1&b\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}

上面的矩阵其实就是三维剪切变换,带入到三维中通过线性变换来达到“平移”的效果

那条白色的线其实都发生了成比例的缩放,缩放因子就是最后一个维度的值ω,ω=1时称为归一化平面,齐次坐标ω不同的点在笛卡尔坐标系下是同一个点。

这就是所谓的透视投影(中心投影变换)。透视中心就在ω=0的所谓无穷远点处。

这样我们就明白,我们可以通过高维的剪切变换来实现低维度的平移变换,从而解决了平移运动的矩阵表示问题。

我们通常把线性变换+ 平移称为“仿射变换”(Affine) 

同样地,对于相机坐标系的平移,我们可以通过直接求平移矩阵T的逆矩阵来得到基变换矩阵A。

\begin{aligned} &\mathbf{p}^{\prime}=\mathbf{Tp} \\ &\mathbf{p}^{\prime}=\mathbf{Ap}=\mathbf{T}^{-1}\mathbf{p} \\ &\mathbf{T}=\begin{bmatrix}1&0&a\\0&1&b\\0&0&1\end{bmatrix}\quad\mathbf{A}=\begin{bmatrix}1&0&-a\\0&1&-b\\0&0&1\end{bmatrix} \end{aligned}

然后我们把刚刚提到的平移和旋转合在一起,拼成一个矩阵,就得到了能够转换二维(三维同理)世界坐标到运动的相机坐标系的桥梁(线性变换)。

\left[\begin{array}{ccc}\cos\theta&\sin\theta&a\\-\sin\theta&\cos\theta&b\\0&0&1\end{array}\right]

我们把这个矩阵写成更一般的形式,T和R分别表示平移和旋转,我们称E为相机的“外参矩阵”(Extrinsic Matrix)

E=\begin{bmatrix}R&T\\0^T&1\end{bmatrix},\mathbf{p}'=E\mathbf{p}

写成这种形式的好处是,可以统一的表达有限维空间的情况,比如二维和三维

(注:基于欧拉角的旋转矩阵,其具体形式与旋转轴是否固定以及旋转顺序有关)

如此一来,我们就把第一个问题解决了。

2. 如何投影到“像平面”?->内参矩阵K

我们已经把世界坐标系通过外参矩阵E转换到了运动了的相机坐标系下了,现在我们把目光聚焦到相机坐标系就可以了。像平面与XY平面的距离我们称为焦距f,相机坐标系下一点P(x,y,z)与坐标原点所连直线与像平面的交点P'就是:P在像平面上或者说焦平面上的投影点。

现在我们来求P' 的坐标,根据两个三角形相似,可得

\frac{x'}x=\frac fz\\\frac{y'}y=\frac fz  则P'的坐标为p'(xf/z,yf/z,f)

我们再定义像平面上的坐标为(xf/z,yf/z)这就是图像坐标系下的坐标值。

写成齐次坐标下矩阵的形式为

z\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}f&0&0&0\\0&f&0&0\\0&0&1&0\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}, z代表点p的深度信息。


 


2.1 图像平面坐标转换为像素坐标系      

像素坐标系和图像坐标系都在成像平面上只是各自的原点和度量单位不一样。图像坐标系的原点为相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。图像坐标系的单位是mm,是物理单位,而像素坐标系的单位是pixel,我们平常描述一个像素点都是几行几列。所以这两者之间的转换关系如下:

\begin{array}{l}u=\frac{xf/z}{dx}+u_0\\\nu=\frac{yf/z}{dy}+\nu_0\end{array}

其中,dx和dy分别表示每一列和每一行分别代表多少mm,即1pixel=dxmm。以齐次坐标形式表示为:
 \begin{bmatrix}u\\\\\nu\\1\end{bmatrix}=\begin{bmatrix}\frac{1}{dx}&0&u_0\\\\0&\frac{1}{dy}&\nu_0\\\\0&0&1\end{bmatrix}\begin{bmatrix}{xf/z}\\{yf/z}\\1\end{bmatrix}

那么将上面得线性变换矩阵与之前的作矩阵乘法,有

\begin{bmatrix}\frac{1}{dx}&0&u_0\\0&\frac{1}{dy}&\nu_0\\0&0&1\end{bmatrix}\begin{bmatrix}f&0&0&0\\0&f&0&0\\0&0&1&0\end{bmatrix}=\begin{bmatrix}f_x&0&u_0&0\\0&f_y&\nu_0&0\\0&0&1&0\end{bmatrix} ,其中fx,fy是焦距(mm)像素值表示(pixel)

右侧的矩阵即为相机的内参矩阵,我们记作K。我们可以看到,这个矩阵其实也是一个仿射变换的形式。

这样,我们的第二个问题也解决了。

3. 三维到二维的维度是如何丢失的?->透视变换

我们把内外参矩阵写在一起,就得到了之前“小孔成像”所代表的映射的表达式P^{\prime}=KEP

内参矩阵K在三维空间是一个3x4的矩阵,外参矩阵E在三维空间是一个4x4的矩阵,作矩阵相乘,结果为一个3x4的矩阵。

这里本质上是一个透视变换,即齐次坐标转笛卡尔坐标(降维了),相机成像三维到二维的维度丢失,就是在这里发生的,得到的归一化像素坐标系下的uv值就是我们要找的图像坐标了。

一句话总结第三个问题的答案:相机坐标系到归一化像素坐标系的透视变换(投影)

4. 坐标变换的应用

1.相机标定:

每一个相机生产出来之后都要进行标定,这样才能把相机的内参写进产品手册卖给客户,而外参会随着相机运动变化而变化,一般把相机固定之后再校正。常用的标定方法是张正友老师提出的棋盘格校定法,此外还有直接线性法DLT。但无论哪种方法,本质都是求解内外参矩阵K和E

2.视觉测量:
iphone的measure也是通过内外参矩阵,才能把图像像素的距离和真实的物理距离对应起来。

3.视觉导航:

如果我们用摄像头作为传感器进行导航和定位,尤其是在视觉SLAM中,如果我们不知道相机的内外参矩阵,又怎么能通过摄像头提供的图像信息解算真实世界的位置,构建真实世界的物理地图呢?

附:像平面投影实际的偏差问题

在实际情况下,相机的成像并没有那么理想。

首先,由于图像传感器的尺寸和形状误差,导致像平面沿xy轴有不同尺度的缩放(scale):

\begin{aligned}(u,v)=(\alpha xf/z,\beta yf/z)\end{aligned}

再者,相机在实际生产过程中存在公差和不确定性因素,导致Z轴或者说主光轴未穿过像平面的中心而产生偏移(offset):
\begin{aligned}(u,v)=(\alpha xf/z+x_0,\beta yf/z+y_0)\end{aligned}

最后,由于工艺问题,像平面不再是矩形而是平行四边形,我们用θ来刻画这种偏斜(skew)。我们会发现这本质也是一个坐标基变换的问题,从垂直XY轴,变成了非垂直的xy轴,从正交基变为了非正交基。

x'=x-y\cot\theta\quad y'=y/\sin\theta

(u,v)=(\alpha(x-y\cot\theta)f/z+x_0,\beta(y/\sin\theta)f/z+y_0)

参考资料

参考1

参考2

参考3

参考4

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

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

相关文章

【CentOS7.6】docker部署EMQX教程,本地镜像直接导入(附下载链接),没法在云服务器上魔法拉取镜像的快来

总览 先把下载链接放在这里吧,这是 EMQX 的 tar 包,能够直接导入 CentOS 的 docker: 链接:https://pan.baidu.com/s/1rSGSLoVvj83ai6d5oolg8Q?pwd0108 提取码:0108 一、安装配置教程 1.将 EMQX-latest.tar 包导入…

记录第一次写脚本

使用csh语言,Linux系统操作的 写和执行csh(C Shell)脚本不需要额外的软件,只需要一个支持csh的终端环境。 1.检查是否安装了C Shell 在终端terminal运行以下命令 which csh 如果返回路径,比如/bin/csh&#xff0c…

【mybatis】mybatisX插件概述

一、主要功能 智能补全与提示 MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息,从而显著提高开发效率。代码生成器 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器,但它可能集成了或支持与其他代码生成工具&#…

【Linux进阶】磁盘分区2——MBR和GPT

1.磁盘的分区 因为如果你的磁盘被划分成两个分区,那么每个分区的设备文件名是什么? 在了解这个问题之前,我们先来复习一下磁盘的组成,因为现今磁盘的划分与它物理的组成很有关系。 我们谈过磁盘主要由碟片、机械手臂、磁头与主轴马…

Tomcat(+Servlet)笔记+代码

Tomcat安装和配置 安装在不含中文的路径,路径不能太长 Apache 官网👇 Apache Tomcat - Welcome! 配置部分 点击下图红框处,找到Tomcat安装位置 添加项目的文件 配好的话,红框这里有个猫 代码部分 新建jsp文件,里…

小程序渗透测试的两种方法——burpsuite、yakit

首先呢主要是配置proxifier,找到小程序的流量,然后使用burpsuite或者yakit去抓包。 一、使用burpsuiteproxifier的抓包测试 1、先配置proxifier,开启http流量转发 勾选确定 2、配置burp对应代理端口,选择profile,点…

基于React和TypeScript的开源白板项目(Github项目分享)

在学习前端开发的过程中,有时候我们需要一些有趣的项目来提升我们的技能。今天我要给大家介绍的是一个非常酷的项目——NinjaSketch,这是一个用React和TypeScript构建的简易白板工具。这个项目使用了Rough.js来实现手绘风格的效果。尽管这个应用不是响应…

vue中如何使用echarts和echarts-gl实现三维折线图和三维柱状图

一、vue中使用三维折线图 效果图: 二、使用步骤 1.引入库 安装echarts 在package.json文件中添加 "dependencies": {"echarts": "^5.1.2""echarts-gl": "^1.1.1",// "echarts-gl": "^2.0.8…

【C++】 解决 C++ 语言报错:Memory Leak

文章目录 引言 内存泄漏(Memory Leak)是 C 编程中常见且严重的内存管理问题之一。当程序分配了内存而没有正确释放,导致内存无法被重新利用时,就会发生内存泄漏。这种错误会导致程序占用越来越多的内存,最终可能导致系…

Zabbix动作与媒介

目录 前言 1. 动作的基本概念 2. 动作的常见用途 一. 环境准备 二. 创建动作 三. 添加媒介 前言 在 Zabbix 中,动作(Actions)用于在特定事件发生时执行一系列预定义的操作,比如发送通知、执行脚本等。动作通常与触发器&…

12款超良心好用APP推荐,每一款都值得下载!

AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/分享是奉献的果实,分享是快乐的前提。每天给小伙伴们分享自己认可的软件,也是莫大的幸福,今天获得12款好用的软…

扁鹊三兄弟的启示,保证系统稳定的秘诀

一、稳定性的重要性 1. 公司收益的角度 从公司收益的视角审视,系统不稳定可能会引发直接损失。例如,当系统突然出现故障导致交易中断时,可能造成交易款项的紊乱、资金的滞留或损失,这不但会阻碍当前交易的顺利完成,还…

ASP.NET MVC-razor编写-2-svg中使用js+添加事件监听

环境:win10 效果 初始状态: 鼠标移入某个text(比如KS primer)时,text和连接的线条与箭头都变色: 鼠标移出时回复正常。 如果是移入另一种红色的text(比如Cell Sceening Tag)&…

Using a text embedding model locally with semantic kernel

题意:在本地使用带有语义核(Semantic Kernel)的文本嵌入模型 问题背景: Ive been reading Stephen Toubs blog post about building a simple console-based .NET chat application from the ground up with semantic-kernel. Im…

HexPlane: A Fast Representation for Dynamic Scenes一种动态场景的快速表示方法

Abstract 动态三维场景的建模与再现是三维视觉领域的一个具有挑战性的课题。先前的方法基于 NERF 并依赖于隐式表示这是缓慢的,因为它需要许多 MLP 评估,限制真实世界的应用程序。我们展示了动态三维场景可以明确地表示为六个平面的学习功能&#xff0c…

【重磅】万能模型-直接能换迪丽热巴的模型

万能模型,顾名思义,不用重新训练src,直接可以用的模型,适应大部分原视频脸 模型用法和正常模型一样,但可以跳过训练阶段!直接到合成阶段使用该模型 本模型没有做Xseg,对遮挡过多的画面不会自动适…

信创-系统架构师认证

随着国家对信息技术自主创新的战略重视程度不断提升,信创产业迎来前所未有的发展机遇。未来几年内,信创产业将呈现市场规模扩大、技术创新加速、产业链完善和国产化替代加速的趋势。信创人才培养对于推动产业发展具有重要意义。应加强高校教育、建立人才…

2.4章节python中字符串类型

在Python中,字符串(String)是一种基本的数据类型,用于表示文本信息。字符串可以包含字母、数字、标点符号或任何Unicode字符。Python中的字符串是不可变的,这意味着一旦创建了字符串,就不能更改字符串中的字…

2007年下半年软件设计师【上午题】试题及答案

文章目录 2007年下半年软件设计师上午题--试题2007年下半年软件设计师上午题--答案2007年下半年软件设计师上午题–试题

YOLOV++ 详解 | 网络结构、代码解析、YOLOV 论文阅读、初识 VID

前言 代码地址:https://github.com/YuHengsss/YOLOV 本文网络结构按 YOLOV SwinTiny 绘制,不同的模型主要差异在于 Backbone,VID 相关的部分基本相同。 Predict Input 代码基于 vid_demo。首先会读取视频中的所有帧(只能用短视频…