【相机与图像】1. 相机模型的介绍:内参、外参、畸变参数

news2024/9/24 0:22:39

想着整理下相机模型(内容上参考 slam十四讲)、相机的内外参标定。方便自己的使用和回顾。
不过,内外参标定啥时候记录随缘 -_-

概述

构建相机模型
相机将三位世界中的坐标点(单位为米)映射到二维图像平面(单位为像素)的过程,使用一个集合模型进行描述。

  • 最简单且常见的为针孔模型,他描述了一束光通过针孔后,在针孔背面投影成像的关系;
  • 同时由于相机镜头上的透镜的存在,使得光线投影到成像平面过程中会产生畸变。所以使用针孔和畸变两个模型来描述整个投影过程。

单目相机成像过程】(这里先上最终的结论)

  • 1 【世界坐标】世界坐标系下有点P,世界坐标为 P w P_w Pw
  • 2 【相机坐标】相机在运动,对应的外参为 R , t R,t R,t。P的相机坐标为 P c = R P w + t P_{c}=RP_w+t Pc=RPw+t.
  • 3 【归一化坐标】此时 P c = ( X , Y , Z ) P_c=(X,Y,Z) Pc=(X,Y,Z),将点投影到归一化平面 Z = 1 Z=1 Z=1 上,得到P的归一化坐标为 P c ′ = [ X / Z , Y / Z , 1 ] T P_c^{'}=[X/Z,Y/Z,1]^T Pc=[X/Z,Y/Z,1]T
  • 4 【去畸变】存在畸变时,使用畸变参数计算 对应的坐标。
  • 5 【像素坐标】通过内参矩阵,计算对应的像素坐标: P ~ u v = K P c ′ \tilde{P}_{uv}=KP_c^{'} P~uv=KPc

公式与图示

  • 在不考虑畸变的影响,可将整过过程写成表达式如下,: s P ~ = K ( R P w + t ) s\tilde{P}=K(RP_w+t) sP~=K(RPw+t)
  • 以及图示公式细节( s = Z c s=Z_c s=Zc,所以图示等号左边与最终的uv还有个s倍的关系)
    在这里插入图片描述

1 针孔模型建模

小孔成像原理,成像平面的图像 为实际物品按照z轴旋转180度状态。在实际相机中,会将成像平面上倒转的图像处理成与3D目标,直观上是一致的。然后根据等边三角形相似原理,构建了一个 等效成像面,这样也简化了点 在坐标系的构建和空间与图像上映射时的坐标问题。
如下图
在这里插入图片描述
在上图中,构建3维坐标与2维坐标的转换中所需的坐标系(共四种)。

  • 世界坐标系 o w x w y w z w o_wx_wy_wz_w owxwywzw
    世界坐标系不是一个又明确定义的坐标系,可以任意制定一个字 “在当前场景下固定不变的坐标系” 作为世界坐标系。
  • 相机坐标系 o c x c y c z c o_cx_cy_cz_c ocxcyczc
    相机坐标系习惯上定义:假设手持相机,相机光心作为原点;右边为x轴正方向;下边为y轴正方向;相机前方为z轴正方向(拍摄远处的物体距离为正)。
  • 图像坐标系 o i x i y i o_ix_iy_i oixiyi
    为二维坐标系。图像坐标系的原点位于感光芯片的中心(感光芯片是位于镜头背后的用于成像的小板子),x、y轴方向和相机坐标系的x、y轴相同。
  • 像素坐标系 o p x p y p o_px_py_p opxpyp
    像素坐标系也位于成像平面上,是图像坐标系通过平移和缩放得到的。值得注意是,不同的软件或者库对于像素坐标 (u,v) 的定义不一样。
    在这里插入图片描述
    我们先探究目标从 相机坐标系 转换到 图像坐标系的关系。
    在这里插入图片描述
    在这里插入图片描述
    其中,3D点的坐标为 ( X c , Y c , Z c ) (X_c,Y_c,Z_c) (Xc,Yc,Zc),图片上的2D坐标为 ( X i , Y i ) (X_i, Y_i) (Xi,Yi)。则有 Z c f = X c X i = Y c Y i \frac{Z_c}{f}=\frac{X_c}{X_i}=\frac{Y_c}{Y_i} fZc=XiXc=YiYc

2 相机内参

内参矩阵为相机坐标系下的3D坐标转换到像素坐标的变化关系。

  1. 相机坐标–> 图像坐标
    通过上面的公式可以得到二者转换关系。其中 f f f 为相机焦距。
    X i = f Z c X c Y i = f Z c Y c \begin{aligned} X_i &=\frac{f}{Z_c}X_c \\ Y_i &=\frac{f}{Z_c}Y_c \end{aligned} XiYi=ZcfXc=ZcfYc

  2. 图像坐标–>像素坐标
    图像坐标实连续值,而像素坐标是离散的正值,经过平移和缩放,得到两者之间的关系:
    u = α X i + c x v = β Y i + c x \begin{aligned} u &=\alpha X_i+c_x \\ v &=\beta Y_i+c_x \\ \end{aligned} uv=αXi+cx=βYi+cx

    • α 、 β \alpha、\beta αβ 与实际传感器的物理尺寸相关,单位为 pixel每m。
      c x 、 c y c_x、c_y cxcy 为光心,单位为 pixel。
      X i , X j X_i, X_j Xi,Xj 为 图像坐标系下的坐标,单位为 m。
  3. 相机坐标–> 像素坐标
    通过上面的公式,可得以下转换关系
    u = α f Z c X c + c x                 u = f x X c Z c + c x v = β f Z c Y c + c y                   v = f y Y c Z c + c y \begin{aligned} u &=\alpha\frac{f}{Z_c}X_c+c_x\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,u =f_x\frac{X_c}{Z_c} +c_x\\ v &=\beta\frac{f}{Z_c}Y_c+c_y\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,v =f_y\frac{Y_c}{Z_c} +c_y \end{aligned} uv=αZcfXc+cxu=fxZcXc+cx=βZcfYc+cyv=fyZcYc+cy可以发现,当相机硬件固定下来, f x 、 f y 、 c x 、 c y f_x、f_y、c_x、c_y fxfycxcy 也就固定下来了。此时 u u u X c X_c Xc v v v Y c Y_c Yc 的变化并不成正比,因为还存在 Z c Z_c Zc的变量。
    为了公式更好的转换和表达,引入了齐次坐标(在原有的坐标维度额外补充1维,数值为1),在这里像素的齐次坐标为 P ~ u v \tilde{P}_{uv} P~uv

    在相机的坐标转换过程中,是否使用齐次式主要取决于转换的复杂性和需要表示的信息类型。对于涉及平移、旋转、缩放等多种变换的复杂场景,以及需要表示无穷远点或区分点和向量的场合,使用齐次坐标可以更方便地实现坐标的线性转换和统一处理。然而,在计算资源受限或特定应用场景下,可能会选择不使用齐次坐标进行坐标转换。

    则可将上面的表达式整理为 ( u v 1 ) = 1 Z c ( f x 0 c x 0 f y c y 0 0 1 ) ( X c Y c Z c ) \begin{pmatrix} u\\ v\\ 1 \end{pmatrix}=\frac{1}{Z_c}\begin{pmatrix} f_x & 0 & c_x\\ 0 & f_y & c_y\\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} X_c\\ Y_c\\ Z_c \end{pmatrix} uv1 =Zc1 fx000fy0cxcy1 XcYcZc 该式中,将中间的定量组成的矩阵成为相机的内参数(Camera Intrinsic)矩阵K。通常认为,相机的内参在出厂之后是固定的,不会在使用过程中发生变化。
    相机坐标转换到像素坐标的公式可记如下 s P ~ u v = K P c s \tilde{P}_{uv} = KP_c sP~uv=KPc其中 s = Z c s=Z_c s=Zc,将该值记成s也是说明它为一个缩放尺度,为数值。

    从另一个角度考虑该投影过程。
    相机坐标系下的点 除以最后一个维度(即该点距离相机成像平面的深度),即对最后一维度进行归一化处理,得到点P在相机的归一化平面上的归一化坐标。于是定义 z = 1 z=1 z=1为归一化平面,该平面上的点为归一化坐标 ( X c , Y c , Z c ) − ˜ ( X c / Z c ,   Y c / Z c ,   1 ) (X_c,Y_c,Z_c)\~{-}(X_c/Z_c, \,Y_c/Z_c,\,1) (Xc,Yc,Zc)˜(Xc/Zc,Yc/Zc,1)

注意:

  • 另外,有时会引入一个 λ \lambda λ 参数,来描述坐标轴垂直程度的误差(感光芯片的X,Y轴没有完全垂直) K = ( f x λ c x 0 f y c y 0 0 1 )   K= \begin{pmatrix} f_x & \lambda & c_x\\ 0 & f_y & c_y\\ 0 & 0 & 1 \end{pmatrix}\ K= fx00λfy0cxcy1  
  • 感光芯片的最小单位一般不是严格的正方形,所以得到的 f x f_x fx f y f_y fy 不一定相等。
  • K一般会由相机生产商提供,如果没有提供则可通过单目棋盘格张正友标定法进行获取,该过程被称作未内参标定。
  • 实际使用XY坐标轴的不垂直误差不需要考虑
  • 这个内参矩阵为小孔成像原理推导出来的,畸变模型后续进行介绍。

3 相机外参

外参矩阵描述的是,世界坐标系下的坐标转换为相机坐标系下的坐标的过程。这两个坐标系均为3维的,转换过程为旋转平移操作的刚体变换。
在这里插入图片描述
相机外参:旋转矩阵 R 为3x3,平移向量 t 为 3x1。
点P:相机坐标系下的坐标 P c P_c Pc为3x1,在世界坐标系下的坐标 P w P_w Pw为 3x1,对应的齐次世界坐标 P ~ w \tilde{P}_{w} P~w为 4x1。
则有 P c = R P w + t P_c=R P_w+t Pc=RPw+t对应的齐次公式为 P c = [ R t ] P ~ w P_c=\begin{bmatrix} R & t \end{bmatrix} \tilde{P}_{w} Pc=[Rt]P~w则,将世界坐标转换为像素坐标的完整的转换公式为 s P u v = s [ u v 1 ] = K ( R P w + t ) s P_{uv}=s \begin{bmatrix} u \\ v \\ 1 \end{bmatrix}=K(RP_w+t) sPuv=s uv1 =K(RPw+t)

4 畸变

畸变的分类
为了更好的成像效果,在相机的前方加入了透镜,会对成像过程中光线的传播产生新的影响。

  • 【径向畸变】透镜自身的形状对光线的传播产生的影响。
    • 桶形畸变:放大率随着光轴之间的距离增加而减小。
    • 枕形畸变:与桶形畸变刚好相反
      在这里插入图片描述
  • 【切向畸变】在机械组装过程中,透镜和成像平面不可能完全平行,对光的传播产生的映像。
    在这里插入图片描述

畸变的数学表达
为了更好理解畸变,使用更严格的数学形式对这两者进行描述。
考虑归一化平面上的任意一点 p,它的坐标为 [ x , y ] T [x,y]^T [x,y]T,对应的极坐标形式为 [ r , θ ] T [r,\theta]^T [r,θ]T,其中 r r r 表示点 p 与坐标系原点的距离, θ \theta θ 表示与水平轴的夹角。通常假设这些畸变呈多项式关系。

  • 径向畸变可以看成坐标点沿着长度方向发生了变化,即 点距离远点的长度发生了变化。 x d i s t o r e d = x ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) y d i s t o r e d = y ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) \begin{aligned} x_{distored}& =x(1+k_1r^2+k_2r^4+k_3r^6) \\ y_{distored}& =y(1+k_1r^2+k_2r^4+k_3r^6) \end{aligned} xdistoredydistored=x(1+k1r2+k2r4+k3r6)=y(1+k1r2+k2r4+k3r6)
  • 切向畸变可以看成坐标点沿着切线方向发生了变化,即 水平夹角发生了变化。
    x d i s t o r e d = x + 2 p 1 x y + p 2 ( r 2 + 2 x 2 ) y d i s t o r e d = y + p 1 ( r 2 + 2 y 2 ) + 2 P 2 x y \begin{aligned} x_{distored}& =x+2p_1xy+p_2(r^2+2x^2) \\ y_{distored}& =y+p_1(r^2+2y^2)+2P_2xy \end{aligned} xdistoredydistored=x+2p1xy+p2(r2+2x2)=y+p1(r2+2y2)+2P2xy

因此对于相机坐标系中的一点P,可通过5个畸变系数找到对应的像素平面上的正确位置。流程如下:

  1. 将三维空间点投影到归一化图像平面。设它的归一化坐标为 [ x , y ] T [x,y]^T [x,y]T
  2. 对于归一化平面上的点计算畸变 x d i s t o r e d = x ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) + x + 2 p 1 x y + p 2 ( r 2 + 2 x 2 ) y d i s t o r e d = y ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) + y + p 1 ( r 2 + 2 y 2 ) + 2 P 2 x y \begin{aligned} x_{distored} = x(1+k_1r^2+k_2r^4+k_3r^6)+x+2p_1xy+p_2(r^2+2x^2) \\ y_{distored} = y(1+k_1r^2+k_2r^4+k_3r^6)+y+p_1(r^2+2y^2)+2P_2xy \end{aligned} xdistored=x(1+k1r2+k2r4+k3r6)+x+2p1xy+p2(r2+2x2)ydistored=y(1+k1r2+k2r4+k3r6)+y+p1(r2+2y2)+2P2xy
  3. 将畸变后的点通过内参矩阵投影到像素平面,得到在图像上的 uv 坐标 u = f x x d i s t o r t e d + c x v = f y y d i s t o r t e d + c y \begin{aligned} u= f_xx_{distorted}+c_x \\ v = f_yy_{distorted}+c_y \end{aligned} u=fxxdistorted+cxv=fyydistorted+cy

去畸变
实际使用中,畸变矫正的做法:

  1. 先对整张图像进行去畸变,然后在该图像中讨论像素坐标与空间坐标的映射(更常用)
  2. 将畸变方程使用到3D点到畸变后图像的过程,会增加计算的麻烦程度

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode】71.简化路径

1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码&#xff1a; class Solution:def simplifyPath(self, path: str) -> str:operator [] # 操作符的栈dir_name [] # 文件名的栈idx 0cur_dir_name ""while(idx < len(path)):if path[idx] /:operator.ap…

MT6775(Helio P70)处理器规格参数_MTK联发科平台方案

联发科MT6775(Helio P70)采用台积电12nm工艺制程节省功耗达 15%&#xff0c;搭载了四颗Arm Cortex-A73 2.1GHz和四颗ArmCortex-A53 2.0GHz的八核处理器。 GPU为ARM Mali-G72 MP3&#xff0c;运行时频率高达900MHz&#xff0c;相较于上一代产品HelioP60&#xff0c;效能提升了1…

搜索与下载Stable Diffusion 模型

我只是一个刚开始学习SD没多久小白&#xff0c;拿到别人的工作流想要运行时&#xff0c;很多时候还要下载对应的模型才能正常运行&#xff0c;虽然也可以通过comfyui-manager下载&#xff0c;不过有时候好像会下载失败&#xff0c;而单独下载所需模型&#xff0c;我自己试过&am…

解析西门子PLC的String和WString

西门子PLC有两种字符串类型&#xff0c;String与WString String 用于存放英文数字标点符号等ASCII字符&#xff0c;每个字符占用一个字节 WString宽字符串用于存放中文、英文、数字等Unicode字符&#xff0c;每个字符占用两个字节 之前我搞过一篇解析String的 关于使用TCP-…

SparkSql oom原因以及参数调优+数据倾斜解决方案

1、Spark历史版本对比 spark1 vs spark2 vs spark3 1、spark1引入内存计算的理念&#xff0c;解决中间结果落盘导致的效率低下。在理想状况下性能可达到MR的100倍。虽然提高了一定的计算效率&#xff0c;但也带来了大量的内存管理问题&#xff0c;典型的如内存oom问题频发。…

第124天:内网安全-代理 Sockets协议路由不出网后渗透通讯CS-MSF 控制上线

目录 思维导图 环境配置 案例一&#xff1a;网络通讯&控制上线--CS-路由添加&节点建立&协议生成&正反连接 案例二&#xff1a;网络通讯&控制上线--MSF-路由添加&节点建立&协议生成&正反连接 思维导图 环境配置 这里由于系统内存问题我只设…

79页PDF免费下载 | 全域数字化转型评估模型研究报告

一、前言&#xff1a; 随着数字技术的飞速发展&#xff0c;零售行业正站在转型的十字路口。如何在变革中找到方向&#xff0c;如何通过数字化转型提升企业竞争力&#xff0c;已成为每个零售企业必须面对的课题。腾讯智慧零售与伏羲智库深度合作&#xff0c;推出《2024年全域数…

【Python selenium过极验滑块】用自动化selenium 操作GEETEST极验滑块,简单粗暴

文章日期&#xff1a;2024.07.24 使用工具&#xff1a;Python 文章类型&#xff1a;自动化过极验滑块 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 AES解密处理&#xff08;直接解密即可&#xff09;&#xff08;crypto-js.js 标准算法&…

使用FileZilla Cilent快速让手机与电脑进行文件互传(无需生态)

目录 前言使用 FileZilla笔者的话 前言 当设备多的时候文件的传输就成了一种问题。 就比如说我想将手机上的文件传到电脑里面&#xff0c;因为我使用的电脑跟我的手机不是一个生态的&#xff0c;它们唯一的联系或许就是连接到了统一 WIFI 下&#xff0c;也就是说它们在同一个…

Redis与MySQL的数据一致性问题

目录 一、策略模式 1、旁路缓存模式&#xff08;Cache Aside Pattern&#xff09; 2、读写穿透&#xff08;Read-Through/Write-Through&#xff09; 3、异步缓存写入&#xff08;Write Behind&#xff09; 二、一致性解决方案 1、缓存延迟双删 2、删除重试机制 3、读取…

【概率论】-2-概率论公理(Axioms of Probability)

上一篇文章我们学习了基本的概率论内容-排列组合&#xff0c;本次我们学习概率论公理的内容&#xff0c;正式开始计算概率&#xff0c;在开始前我们需要学习一些基本概念。 目录 一.样本空间和事件 1.样本空间 2.事件 3.交并补 二、概率公理 1.基本公理 2.对称差 2.布尔…

Mysql中(基于GTID方式)实现主从复制,单主复制详细教程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

Android Studio 一键删除 Recent Projects信息的方法

Android Studio打开项目多了就一堆最近项目的记录&#xff0c;在IDE里面只能一个个手动删除。 File - Recent Projects 解决方案&#xff1a;修改配置文件 Note&#xff1a;方法不唯一。 Android Studio 存储了一个包含最近打开项目信息的配置文件。通过手动编辑或删除recentP…

代码随想录算法训练营day7 | 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

文章目录 454.四数相加II思路 383.赎金信思路 15.三数之和思路剪枝去重 18.四数之和思路剪枝去重复习&#xff1a;C中的类型转换方法 总结 今天是哈希表专题的第二天 废话不多说&#xff0c;直接上题目 454.四数相加II 建议&#xff1a;本题是 使用map 巧妙解决的问题&#x…

Pytorch使用教学1-Tensor的创建

0 导读 在我们不知道什么是深度学习计算框架时&#xff0c;我们可以把PyTorch看做是Python的第三方库&#xff0c;在PyTorch中定义了适用于深度学习的张量Tensor&#xff0c;以及张量的各类计算。就相当于NumPy中定义的Array和对应的科学计算方法&#xff0c;正是这些基本数据…

JVM系列(三) -类加载器及双亲委派模型介绍

在之前的文章中&#xff0c;介绍了类的加载过程中&#xff0c;我们有提到在加载阶段&#xff0c;通过一个类的全限定名来获取此类的二进制字节流操作&#xff0c;其实类加载器就是用来实现这个操作的。 在虚拟机中&#xff0c;任何一个类&#xff0c;都需要由加载它的类加载器…

【ffmpeg命令入门】添加水印

文章目录 前言什么是水印&#xff1f;为什么要添加水印&#xff1f;ffmpeg添加水印添加图片水印添加文字水印基本使用方法drawtext的参数 总结 前言 在视频制作和编辑的过程中&#xff0c;添加水印是一个常见且重要的步骤。水印不仅可以保护版权&#xff0c;还能用于品牌宣传和…

netty入门-4 Channel与ChannelFuture

Channel 基本类似于NIO中的Channel概念。作为读写数据的通道。 常见方法 close() 可以用来关闭 channelcloseFuture() 用来处理 channel 的关闭 sync 方法作用是同步等待 channel 关闭而 addListener 方法是异步等待 channel 关闭 pipeline() 方法添加处理器write() 方法将数…

Stable Diffusion基本原理通俗讲解

Stable Diffusion是一种基于深度学习的图像生成技术&#xff0c;它属于生成对抗网络&#xff08;GANs&#xff09;的一种。简单来说&#xff0c;Stable Diffusion通过训练一个生成器&#xff08;Generator&#xff09;和一个判别器&#xff08;Discriminator&#xff09;&#…

算法力扣刷题记录 五十八【701.二叉搜索树中的插入操作】

前言 本文是二叉搜索树操作。 二叉树篇继续。 一、题目阅读 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节…