相机内参标定理论篇------相机模型选择

相机种类:

当拿到一款需要标定内参的相机时,第一个问题就是选择那种的相机模型。工程上相机类型的划分并不是十分严格,一般来说根据相机FOV可以把相机大概分为以下几类:

长焦相机:<= 30^{o}

标准相机:40^{o}~60^{o}

广角相机:60^{o}~140^{o}

鱼眼相机:>140^{o}

这里按角度的划分并不是绝对严格,临界处的相机用两种模型中的任意一种都可以。并且对相机的命名也没有统一的规范,读者可能会遇到不同的命名方法。不过这些都不是很重要,最终也是按角度来对应相机模型,知道多大角度相机用什么相机模型就可以了。

有时可能会遇到变焦相机,但变焦相机在标定内参时也需要固定焦距,因此也可以划分到上面几类。这里需要注意内参和焦距严格对应,当调焦后需要重新标定相机内参。

不同角度的相机需要选择不同的相机模型来标定相机内参。相机模型又分为投影模型畸变模型。接下来分别进行讨论。

长焦相机:

长焦相机的标定采用针孔相机模型,但在实际标定中我们很难通过标定板来标定长焦相机。长焦相机的景深太大,普通标定板由于尺寸较小会导致其在采集的图像中所占区域太小,无法提供足够的约束来标定外参。如果强行在近处采集标定板图像,会造成图像上标定图像模糊不清,从而导致角点提取误差较大,甚至失败。因此标定时外参的计算会有非常大的误差,又因为相机内参和外参在投影时具有耦合的效应,即使重投影误差非常小也无法保证内参的正确性。这也是为什么重投影误差只能作为内参精度的参考,而无法作为精度衡量的标准。

所以一般来说不建议个人去标定长焦相机,即使标定出来结果也很有可能是错误的。之前笔者还是小白的时候尝试使用标定板标定长焦相机,虽然重投影误差很小但内参精度较差,点云投影效果还没有使用相机厂商提供的参考内参值精确。如果必须自己标定的话也不建议用标定板的方式,需要设计新的方法,核心是保证参照物能够提供足够的约束。

标准相机:

针对标准相机工程上采用针孔相机模型标定。其原理类似于小孔成像,不同之处在于为了增加透光量采用凸透镜。其投影模型为针孔投影模型,原理如下图所示:

接下来考虑其畸变模型,这里需要了解一下概念:径向畸变和切向畸变。

一般来说,制造透镜很难保证曲率和设计的一致,曲率制造的误差会造成相机成像是在径向产生误差即径向畸变。径向畸变主要有以下两种:桶型畸变和枕型畸变。

径向畸变主要描述畸变量和像素到图像中心距离的关系,后续会在具体公式讨论。

同样安装时镜头和成像平面无法保证绝对平行,因此会产生切向畸变:

切向畸变主要描述成像平面和光轴之间的倾斜角度。因此针孔相机模型的畸变模型是径向切向畸变模型

接下来看如何将相机坐标系下的点投影到图像上:相机坐标系->图像坐标系->像素坐标系。

具体公式如下:

\begin{bmatrix} x\\ y\\ 1 \end{bmatrix} = \frac{1}{Z}\begin{bmatrix} fx & r & cx\\ 0 & fy & cy\\ 0 & 0 & 1 \end{bmatrix}\begin{bmatrix} X\\ Y\\ Z \end{bmatrix}

一般投影时先对空间三维点归一化:

\begin{bmatrix} x\\ y\\ 1 \end{bmatrix} = \begin{bmatrix} fx & r & cx\\ 0 & fy & cy\\ 0 & 0 & 1 \end{bmatrix}\begin{bmatrix} \frac{X}{Z}\\ \frac{Y}{Z}\\ 1 \end{bmatrix}

其中u v是无畸变点,r描述相机坐标xy轴是否垂直,很多相机模型认为该值为0。接下来对点加径向畸变:

x_{distored} = x(1 + k_{1}r^{2} + k_{2}r^{4} + k_{3}r^{6})

y_{distored} = y(1 + k_{1}r^{2} + k_{2}r^{4} + k_{3}r^{6})

其中k1 k2 k3是径向畸变参数。有时会遇到k4 k5,也是径向畸变参数,不过一般用到k3就行了。因为径向畸变是泰勒展开的多项式拟合,用到太多畸变参数就会存在过拟合问题反而效果不好。

上面提到的枕型畸变和桶型畸变与k的取值有关,当k都大于零时就会产生枕型畸变,反之则会产生桶型畸变。

接下来再加上切向畸变:

x_{distored} = x + [2p_{1}xy + p_{2}(r^{2} + 2x^{2})]

y_{distored} = y + [2p_{2}xy + p_{1}(r^{2} + 2y^{2})]

以上就是相机坐标系下点投影到图像上像素的整个过程。

广角相机:

广角相机和鱼眼相机其实都属于鱼眼相机的范畴,只是标定时选择的相机模型不一样。在介绍接下来的相机模型前还是简单介绍鱼眼相机相关的基础知识以方便理解。

                 

        你以为的鱼眼相机                                                       实际的鱼眼相机

我们知道鱼眼相机的初衷是为了让相机看到尽可能大的视野,也就是尽可能将场景中的物体投影到图像上,因此鱼眼相机通过组合多个镜头将光线多次折射到图像平面上。这时就需要引入较大的径向畸变以保证有限的图像平面上看到甚至超过180度的视野。所以鱼眼相机需要根据某种投影模型进行设计,常见的模型主要分为四种:等距投影模型、等立体角投影模型、正交投影模型和体视投影模型。其投影过程如下图所示,除了f*tan(\theta)对应针孔投影模型外,其它四种对应上面四种。

鱼眼相机四种投影模型其中最常用的是等距相机模型,所以主要对等距相机模型进行讨论,其它模型感兴趣自己上网搜索。等距相机模型:

由上图可以看出经典相机模型一般都是先将相机坐标系下的点投影到单位球(Unit Sphere)。然后引入与\theta相关的比例系数得到单位平面上加完畸变后的投影点,接着再加上由于制造等因素引起的畸变,得到最终单位平面的投影点。有了单位平面上带畸变的投影点直接使用针孔投影模型就可以将其投用到图像上。

等距相机模型的投影公式为:rd = f * \theta,rd为成像的高,\theta为入射角。该模型描述成像的像高和入射角成正比。等距相机模型映射关系很简单,观察图像可以发现中心畸变小边缘处畸变严重。

广角相机最好选择等距相机模型,但是可以看出等距相机的通用性较差,因此OpenCV中使用的模型是由Kannala在等距投影模型的基础上提出的一种近似模型。接下来对OpenCV中fisheye相机模型进行分析。整体过程如下图所示:

上图是利用相机模型将世界坐标系下点投影到图像上的过程。第一步是将世界坐标系的点通过外参转到相机坐标系下,然后转到归一化平面上。

这里可以看出OpenCV中fisheye模型是先在归一化平面上加畸变然后利用针孔投影模型将加完畸变的点投影到图像上。可以看出等距相机模型的畸变只考虑了径向畸变没有考虑切向畸变。

已知等距相机模型r = f * \theta,但模型通用性较差,并且在实际中很难按设计模型制造出不存在误差的镜头,尤其是鱼眼相机中包含多个镜头。因此常用的方法是使用多项式拟合。最后得到包含畸变后新的\thetad,这里\thetad类似于等距相机模型中的rd,只不过是在归一化平面上。如下图所示,但f为1时rd就是加畸变后点到相机光轴的距离。

接着计算\thetad在归一化平面上的坐标x^{'},y^{'},公式中是利用\thetad和r的比例关系求得的。然后利用针孔投影模型将点投影到图像上。上面公式中有一个\alpha,这个是表征图像平面xy是否垂直的参数也叫斜率系数,很多情况下默认为0。到此就得到了空间点到图像上的整个投影过程。

总结来说OpenCV fisheye相机模型是先加畸变,然后利用针孔相机模型投影到图像上。

鱼眼相机:

如下图所需,鱼眼相机主要有以下几类:

Dioptric cameras,通过组合多个透镜来实现,主要靠光线多次折射,也可以做到180度以上。

Catadioptric cameras,使用一个标准相机加一个面镜,实际中很少应用;

polydioptric camera,通过多个相机重叠视野,实际中也很少应用。

实际工程中,鱼眼相机可以分为大于180度的和小于180度两种相机。作者个人经验,小于180度的相机可以使用基于等距模型的OpenCV fisheye中相机模型来标定相机。但是如果相机度数大于180度时OpenCV fisheye标定出来的效果并不是十分好。曾经作者曾遇到一款相机可以看到220度以上,这时利用OpenCV中fisheye模型来标定会失败,即使成功内参值也有较大的误差。

对应大于180度的相机,这时标定相机可以用的相机模型有kalibr的MEI模型或是Davide Scaramuzza的ocam相机模型。但在实际应用中ocam相机模型更好一些。不过OpenCV对ocam模型没有支持,但是支持了MEI模型的相关函数。

虽然实际中ocam模型效果较好,但很多人也可能用到MEI模型,所以先对其进行介绍。MEI模型的投影过程如下图所示:

上图描述了MEI模型投影过程,可以看出为了让图像看到更大的视野,MEI模型重新构建了新的相机坐标系进行投影。新相机坐标系和真实相机坐标系在Z轴上存在\xi偏移量。通过在新的坐标系下进行投影实现对像素在径向上的压缩。

具体流程如下:

求相机坐标系下点投影到单位圆上:

构建新的坐标系,新坐标系相对原坐标系在Z轴偏移-\xi。求\chi _{s}在新坐标系下的坐标:

然后求在新坐标系下归一化平面上的投影:

对投影点m_{u}加畸变得到m_{d},这里的畸变是径向切向畸变可以参加针孔模型部分:

然后利用针孔投影模型将m_{d}投影到图像上: 

 接下来介绍ocam模型,由于暂时没法翻墙,不好查资料后续再更新吧。需要的同学可以访问下面连接查询。

https://sites.google.com/site/scarabotix/ocamcalib-toolbox

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

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

相关文章

2022年全国职业院校技能大赛(高职组)“云计算”赛项赛卷①第一场次:私有云

2022年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算”赛项赛卷1 第一场次&#xff1a;私有云&#xff08;30分&#xff09; 目录 2022年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算”赛项赛卷1 第一场次&#xff1a;私有云&#xff0…

千里马2023年终总结-android framework实战

背景&#xff1a; hi粉丝朋友们&#xff1a; 2023年马上就过去了&#xff0c;很多学员朋友也都希望马哥这边写个年终总结&#xff0c;因为这几个月时间都忙于新课程halsystracesurfaceflinger专题的开发&#xff0c;差点都忘记了这个事情了&#xff0c;今天特别花时间来写个bl…

最优化方法Python计算:无约束优化应用——神经网络回归模型

人类大脑有数百亿个相互连接的神经元&#xff08;如下图(a)所示&#xff09;&#xff0c;这些神经元通过树突从其他神经元接收信息&#xff0c;在细胞体内综合、并变换信息&#xff0c;通过轴突上的突触向其他神经元传递信息。我们在博文《最优化方法Python计算&#xff1a;无约…

SpringMVC框架

SpringMVC 三层架构MVC模式SpringMVC入门案例总结 三层架构 表现层&#xff08;web&#xff09; 页面数据的收集&#xff0c;产出页面 业务逻辑层&#xff08;service&#xff09; 业务处理 数据访问层&#xff08;Dao&#xff09; 数据持久化 MVC模式 SpringMVC 基于Java…

影视后期:PR 调色处理,灰片还原,校色偏色素材

灰片还原 确定拍摄灰片的相机型号品牌官网下载专用log文件LUT-浏览-导入slog3分析亮部波形-增加画面对比分析矢量示波器-提高整体饱和 校正LUT可以将前期拍摄的log色彩模式的视频转换为成709色彩模式&#xff0c;即将灰度视频转换为正常效果(灰片还原) 各个相机有对应的校正L…

开源预约挂号平台 - 从0到上线

文章目录 开源预约挂号平台 - 从0到上线演示地址源码地址可以学到的技术前端技术后端技术部署上线开发工具其他技术业务功能 项目讲解前端创建项目 - 安装PNPM - 使用VSCODE - 安装插件首页顶部与底部 - 封装组建 - 使用scss左右布局中间内容部分路由 - vue-routerBANNER- 走马…

RFC6749-OAuth2.0

前言 最近在项目中需要实现SSO(单点登录)功能,以实现一处注册,即可在任何平台之间登录的功能。我们项目中并没有直接对接第三方认证系统而是通过集成keycloak 完成一系类安全协议的对接工作。如果我们在代码级别自己完成各种安全协议的对接是一项十分大的工程。不仅要走统一的…

jsp介绍

JSP 一种编写动态网页的语言&#xff0c;可以嵌入java代码和html代码&#xff0c;其底层本质上为servlet,html部分为输出流&#xff0c;编译为java文件 例如 源jsp文件 <% page contentType"text/html; charsetutf-8" language"java" pageEncoding&…

Django 学习教程-介绍与安装

系列 Django 学习教程- Hello world入门案例-CSDN博客 介绍 Django 是一个由 Python 编写用于Web 应用程序开发的高级 Python Web 框架 Django 提供了一套强大的工具&#xff08;无需重新发明轮子&#xff09;&#xff0c;使得开发者能够快速构建 Web 网站。 Django 采用了…

【每日一题】收集巧克力

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;枚举操作数 写在最后 Tag 【枚举】【数组】【2023-12-28】 题目来源 2735. 收集巧克力 题目解读 有长度为 n, 下标从 0 开始的整数数组 nums, 表示收集不同类型的巧克力的成本. nums[i] 表示收集类型 i 巧克力的成本…

linux下docker搭建Prometheus +SNMP Exporter +Grafana进行核心路由器交换机监控

一、安装 Docker 和 Docker Compose https://docs.docker.com/get-docker/ # 安装 Docker sudo apt-get update sudo apt-get install -y docker.io# 安装 Docker Compose sudo apt-get install -y docker-compose二、创建配置文件及测试平台是否正常 1、选个文件夹作为自建…

simulink代码生成(六)——多级中断的配置

假如系统中存在多个中断&#xff0c;需要合理的配置中断的优先级与中断向量表&#xff1b;在代码生成中&#xff0c;要与中断向量表对应&#xff1b;中断相关的知识参照博客&#xff1a; DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…

WPF Button使用漂亮 控件模板ControlTemplate 按钮使用控制模板实例及源代码 设计一个具有圆角边框、鼠标悬停时颜色变化的按钮模板

续前两篇模板文章 模板介绍1 模板介绍2 WPF中的Button控件默认样式简洁&#xff0c;但可以通过设置模板来实现更丰富的视觉效果和交互体验。按钮模板主要包括背景、边框、内容&#xff08;通常为文本或图像&#xff09;等元素。通过自定义模板&#xff0c;我们可以改…

jmeter的常用功能及在测试中的基本使用和压测实战

Jmeter基础功能 了解Jmeter的常用组件 元件&#xff1a;多个类似功能组件的容器&#xff08;类似于类&#xff09; 一&#xff1a;Test Plan&#xff08;测试计划&#xff09; 测试计划通常用来给测试的项目重命名&#xff0c;使用多线程脚本运行时还可以配置线程组运行方式…

SQLSERVER排查CPU占用高

操作系统是Windows2008R2 ,数据库是SQL2008R2 64位 64G内存,16核CPU 硬件配置还是比较高的,他说服务器运行的是金蝶K3软件,数据库实例里有多个数据库 现象 他说是这几天才出现的,而且在每天的某一个时间段才会出现CPU占用高的情况 内存占用不太高,只占用了30个G CPU…

Java---网络编程

文章目录 1. 网络编程概述2. InetAddress3. 端口和协议4. Java网络API5. URL6. URLConnection类 1. 网络编程概述 1. 计算机网络&#xff1a;是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统、网络管理软…

Java中利用Redis,ZooKeeper,数据库等实现分布式锁(遥遥领先)

1. 分布式锁 1.1 什么是分布式锁 在我们进行单机应用开发涉及并发同步的时候&#xff0c;我们往往采用synchronized或者ReentrantLock的方式来解决多线程间的代码同步问题。但是当我们的应用是在分布式集群工作的情况下&#xff0c;那么就需要一种更加高级的锁机制&#xff0…

音视频技术开发周刊 | 326

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 全球最强「开源版Gemini」诞生&#xff01;全能多模态模型Emu2登热榜&#xff0c;多项任务刷新SOTA 最强的全能多模态模型来了&#xff01;就在近日&#xff0c;智源研究院…

云计算复习提纲

第一章 大数据的概念&#xff1a;海量数据的规模巨大到无法通过目前主流的计算机系统在合理时间内获取、存储、管理、处理并提炼以帮助使用者决策 大数据的特点&#xff1a;①数据量大&#xff0c;存储的数据量巨大&#xff0c;PB级别是常态&#xff1b;②多样&#xff0c;数…

第9章 继承和派生习题(详解)

一、选择题 1&#xff0e;下列表示引用的方法中&#xff0c; &#xff08;&#xff09; 是正确的。已知&#xff1a;int m10&#xff1a; A&#xff0e;int &xm&#xff1b; B&#xff0e;int &y10&#xff1b; C&#xff0e;int &z&#xff1b; D&#xff0e;fl…