机器视觉【3】非线性求解相机几何参数

news2024/10/7 12:25:48

线性求解相机几何参数的缺点

上一章节介绍学习了(DLT)线性求解相机几何参数,了解到线性求解法当中比较明显的缺点:

  • 没有考虑到镜头畸变的影响
  • 不能引入更多的约束条件融入到DLT算法当中优化
  • 最关键的是,代数距离并不是计算相机矩阵的最佳距离函数

基于以上问题点,提出非线性求解方法。

  • 将包括镜头畸变参数、内外参矩阵等所有信息都当做待求解
  • 定义一个比代数距离更好的距离函数
  • 通过迭代的非线性最优化算法,最优化上述距离函数,从而得到待求解

在《计算机视觉中的多视角几何》的第7.2节中,用一个插图来说明了线性求解出来的代数距离的几何意义。可以看见,代数距离实际上优化的是已知的3D点X和2D点Xi的反投影点Xi'之间的距离。这并不是一个最优的距离函数。

下面我们来看看几何距离,这里假设3D点的位置是准确的(比如我们有一个制作得非常精确的标定板),如下图所示。那么几何距离就是3D点Xi通过投影矩阵投影的2D点xi'和实际成像的2D点xi之间的距离(下图中的红线段)

用公式表达式如下所示,整个优化过程就变成了最小化这个距离的过程,如(2)式

结合之前在 相机的成像(畸变)模型 中的数学模型,式子(2)又可以演变为如下的式子(3)

为了执行这个最优化的过程,需要给相机矩阵及畸变参数初始值。其中P的初始值可以用第一节所讲述的DLT算法得到。而畸变参数的初值可以先设置为0。 

张正友标定法的实现和完整的过程

在相机几何标定的各种算法中,最出名的无疑是张正友博士发明的“张氏标定法”,这个算法在整个业界得到了广泛的应用,它最大的特点就是灵活、鲁棒、低成本。整个标定过程只需要用相机在不同的方向拍摄平面标定板(最少两次),而它实际上的核心思想就是我上面描述的非线性优化求解方法。

在Matlab和OpenCV中都有张氏标定法的实现,具体使用时先准备好一个足够平整的棋盘格标定板,然后通过不同的方向对标定板进行拍摄,然后进行计算。不需要提前知道相机和标定板之间的具体位姿关系,每次拍摄时的相机和标定板的位姿变换也是独立的,整个使用过程非常友好。

在Matlab中,把上面这些图像输入算法,算法会自动检测出棋盘格角点,并利用前面说的方法优化出各项参数,如果某幅图的平均投影误差超出了用户设置的阈值,还可以方便的过滤掉这幅图来重新进行优化计算。甚至还可以可视化每次拍摄时相机和标定板的位姿,非常方便。

下面简单介绍张正友标定法的关键知识要点。

要点1:引入新的约束条件,从而可以采用平面标定板替代立体标定板

之前讲过标定板需要是立体的,否则无法唯一确定相机矩阵。 然而,立体的标定板是较难去制作的,张氏标定法追求的是低成本的标定方式,因此采用了多次拍摄平面标定板的方式来执行标定。而正因为是多次拍摄,所以每次拍摄时相机矩阵都是变化的,之前讲解的约束条件不再适用:

因此,张氏标定法重新寻求了新的约束条件,用于对内参矩阵进行约束,进而进行求解。作者观察到平面板上的点和对应的像点之间可以用一个单应矩阵H关联在一起,而且只要平面板上的角点足够多(单应矩阵有8个自由度,一对点提供2个约束,所以理论上超过4个即可),就可以求出这个单应矩阵,求解方法类似于上一节所介绍的DLT方法;或者之前学习过的 几何变换模型 中的透视模型,利用最小二乘法求解。

接下重点:作者将单应矩阵表达为H,并观察到内参矩阵K和单应矩阵之间存在着一对约束关系。

怎么理解上面的两个等式?回想 机器视觉【1】相机的成像(畸变)模型 整合:世界坐标系→像素坐标系的知识点

这里的λ只是1/s的另一种表示,只是换了一种写法

这里有人会不理解,r1=和r2=是怎么来的?其实自己可以推导一下,把A设成[3X3]的矩阵,乘进去,应该能够看到,组成了[Ar1 Ar2 Ar3],它们互相还是独立的。至于为什么A到A逆,这个是线性代数最基本的转换,左右同时左乘A逆,就变过来了。

这里的A其实就是内参矩阵K,上面两个式子其实不难证明 (以下 A' 为 矩阵A的逆 即上图示的A-1)

由前置知识:A'H = A' · λ · A · [r1 r2 t​] = [r1 r2 t​],λ是常数可暂时忽略

根据线性代数基本规律:(AB)T = BT · AT 即 矩阵A和B相乘之后的转置等于B的转置乘A的转置

那么:(h1)T​ * (A)−T * (A)−1 * h2​ = r1T * ​r2​ = 0    

第一个公式证得r1和r2是正交的关系。

对第二个式子左右两边进行上述变换,得 r1T * ​r1 = r2T * ​r2,由此可知 r1和r2是单位正交。

最后,我们把上述的两个式子中间 (K)-T*(K)-1的部分记作B,其余h部分利用线性基础变换写出另外一部分。即如下表示

这样,我们又可以用SVD奇异值分解的方式,求得b,进而求得K的各个元素。当求得了K之后,就很容易得到这一次拍摄时的外参信息(旋转R和平移t)了。上面讲的方法用于初始化内参矩阵K和每次拍摄的外参R和t,我们假设一共进行n次拍摄,每次拍摄可以获得m个成像点,那么就可以利用非线性最优化方法,来最优化待解参数了。具体表达式如下: 

要点2:在多次拍摄时,需要改变标定板的方向

在张博士的论文中详述了如果两次拍摄时的标定板是平行的,那么实际上并没有提供额外的信息,也因此无法求解出需要的参数。

要点3:最少需要拍摄几幅图?

前面讲到,每一幅拍摄的标定板图像提供了2个对内参矩阵K的约束,而我们内参矩阵K一共有5个未知参数,所以理论上至少需要拍摄3幅图像,才能求得K:

如果我们认为s=0,即传感器像素是规整方形的,那么内参矩阵就只有4个未知参数了,这样就只需要拍摄两幅图像就能进行标定了。

前面讲过,这样的约束关系是为了求得比较好初始化内参矩阵K的。如果你能够事先知道K中元素的大概值,比如你认为s=0, 主点位于图像的中心, 而焦距又是已知的,那么理论上你只需要拍摄一幅平面的标定板一次,就可以通过非线性最小二乘法标定出相机的内外参数。

Reference:

张正友相机标定全解析_定焦相机张正友标定法怎么用-CSDN博客

相机标定(具体过程详解)张正友、单应矩阵、B、R、T_已知内参数下标定r、t-CSDN博客

总结

前文和本文中讲解了相机标定的两大类方法:线性求解方法,以及非线性求解方法。

不管是哪种方法,我都提到了数据归一化的重要性,因为在求解过程中的矩阵元素如果不经过归一化,值差异较大,很容易放大数值误差,需要特别注意这点。经过相机的标定,我们就可以获得了包括畸变参数在内的相机内参,以及每次拍摄时的外参。

博主我的自述:

说实话,之前是知道这一块比较复杂,但没想过是这么复杂。现实接触的情况都是用现成的库或者软件工具一键处理,这次花力气去理解算是 "拨开云雾见天日,守得云开见月明",新的一年祝大家工作顺利,万事如意,大家加油!

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

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

相关文章

Python入门学习——基础语法

一、Python解释器 1. Python解释器的作用是&#xff1a; 将Python代码翻译成计算机认识的O和1并提交计算机执行在解释器环境内可以一行行的执行我们输入的代码也可以使用解释器程序&#xff0c;去执行".py"代码文件 2. Python解释器程序在&#xff1a; <Python…

Jenkins详解

目录 一、Jenkins CI/CD 1、 Jenkins CI/CD 流程图 2、介绍 Jenkins 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 3、安装Jenkins 1、安装JDK 2、安装tomcat 3.安装maven 4安装jenkins 5.启动tomcat&#xff0c;并页面访问 5.添加节点 一、Jenkins CI/…

【Docker】免费使用的腾讯云容器镜像服务

需要云服务器等云产品来学习Linux可以移步/-->腾讯云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 1、设置密码 2、登录实例&#xff08;sudo docker login xxxxxx&#xff09; 3、新建命名空间&#xff08;每个命名空…

【Delphi 基础知识 35】MainMenu控件的详细使用

把TmenuMain放在Form后&#xff0c;右击控件就可以对菜单进行设计 菜单中添加分割线只需加“-”就可以添加一个分割线 级联菜单的设计 单击鼠标右键弹出菜单中选择Create Submenu菜单项 单选功能设计 要在设计的菜单项目中选择RadioItem属性为True&#xff0c;Checked属性…

使用logicflow流程图实例

一.背景 需要使用流程引擎开发项目&#xff0c;没有使用flowable、activiti这类的国外流程引擎&#xff0c;想使用国内的引擎二次开发&#xff0c;缺少单例模式的流程画图程序&#xff0c;都是vue、react、angluer的不适合&#xff0c;从网上找了antx6、logicflow、bpmn.js。感…

了解人工智能计算: 人工智能入门

回顾历史&#xff0c;各种数学仪器在人类进步的历程中发挥了重要作用。从算盘和六分仪到滑尺和计算机&#xff0c;这些工具推动贸易、助力航海&#xff0c;增强理解&#xff0c;并提高了我们的生活质量。然而&#xff0c;在科学和工业领域&#xff0c;推动我们前进的前沿且强大…

Redis 工具类 与 Redis 布隆过滤器

Redis 工具类 1. 核心依赖 <!--redis--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><groupId>com.google.guava…

网卡本质,网络发展(局域网,广域网概念)

目录 引入 网卡的本质 网络的发展 引入 早期 局域网LAN&#xff08;Local Area Network&#xff09; 广域网WAN&#xff08;Wide Area Network&#xff09; 注意 引入 前面我们已经学习了很多关于linux系统的知识,其中文件系统和线程尤为繁杂 而网络其实也算系统的一部…

Vue监听器(上)之组合式watch

1. 定义监听器 //要监视的属性被改变时触发 watch(要监视的属性, (更改后的心值, 更改前的旧值) > {具体操作}, );//监视对象为getter的时候 //表达式内任意响应式属性被改变时触发 watch(() > return表达式, (表达式的新值, 表达式的旧值) > {具体操作} );//数组中任…

如何实现一个规则研究区域内数据的提取(matlab)

在利用经验正交分解&#xff08;EOF&#xff09;进行某一个研究区域分析时&#xff0c;我们需要将研究区域转换成N*M的矩阵&#xff0c;其中N为空间维度&#xff0c;M为时间维度&#xff0c;这意味着我们之前的数据加上时间维度是三维的&#xff0c;即&#xff08;lon,lat,rg&a…

【深入理解设计模式】原型设计模式

原型设计模式 原型设计模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许通过复制已有对象来创建新对象&#xff0c;而无需直接依赖它们的具体类。这种模式通常用于需要频繁创建相似对象的场景&#xff0c;以避免昂贵的创建操作或初始化过…

泛微e-office系统敏感信息泄露漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 1、系统简介 泛微e-office系统是标准、易用、快速部署上线的专业协同OA软…

C++之类作用域

目录 1、全局作用域 2、类作用域 2.1、设计模式之Pimpl 2.2、单例模式的自动释放 2.2.0、检测内存泄漏的工具valgrind 2.2.1、可以使用友元形式进行设计 2.2.2、内部类加静态数据成员形式 2.2.3、atexit方式进行 2.2.4、pthread_once形式 作用域可以分为类作用域、类名…

【MIT-PHP-推荐】imi-ai 是一个 ChatGPT 开源项目

mi-ai 是一个 ChatGPT 开源项目&#xff0c;支持聊天、问答、写代码、写文章、做作业等功能。 项目架构合理&#xff0c;代码编写优雅&#xff0c;简单快速部署。前后端代码完全开源&#xff0c;不管是学习自用还是商用二开都很适合。 本项目现已支持 ChatGPT 聊天 AI 和 Emb…

PyTorch概述(五)---LINEAR

torch.nn.Linear torch.nn.Linear(in_features,out_features,biasTrue,deviceNone,dtypeNone) 对输入的数据应用一个线性变换&#xff1a; 该模块支持TensorFLoat32类型的数据&#xff1b;在某些ROCm设备上&#xff0c;使用float16类型的数据输入时&#xff0c;该模块在反向传…

电路设计(28)——交通灯控制器的multisim仿真

1.功能设定 南北、东西两道的红灯时间、绿灯时间均为24S&#xff0c;数码管显示倒计时。在绿灯的最后5S内&#xff0c;黄灯闪烁。有夜间模式&#xff1a;按下按键进入夜间模式。在夜间模式下&#xff0c;数码管显示计数最大值&#xff0c;两个方向的黄灯不停闪烁。 2.电路设计 …

高通XBL阶段读取分区

【需求】: 在某些场景下,需要在XBL阶段读取分区数据,需要验证xbl阶段方案 这里主要以裸分区为例,比如oem分区。 1、创建一个1MB大小的oem.img,写入内容“test oem partition” 创建方式: dd if=/dev/null of=oem.img bs=1024 count=1oem.img内容: 2、XBL阶段读分区方…

一个更好的IP工具箱MyIP

什么是 MyIP &#xff1f; MyIP 是一个完全开源的 IP 信息查看器&#xff0c;可以轻松检查你的 IP&#xff0c;IP 地理位置&#xff0c;检查 DNS 泄漏&#xff0c;检查 WebRTC 连接&#xff0c;速度测试&#xff0c;ping 测试&#xff0c;MTR 测试&#xff0c;检查网站可用性等…

洛谷C++简单题小练习day20—小狗暴躁,津津的不高兴程度两个小程序(祝大家元宵节happy)

day20--小狗暴躁--2.24 习题概述 题目描述 在一个小村子里&#xff0c;邮递员、送奶工、垃圾清理工每天早晨都面临着同样的难题&#xff1a;18 号房子的门前有两条看门狗。他们所不知道的是&#xff0c;这两条狗的表现是有迹可循的。 当一天开始时&#xff0c;其中一条狗会…

流畅的Python笔记

流畅的Python 第一部分 序幕第 1 章 Python 数据模型 第二部分 数据结构第 2 章 序列构成的数组列表推导生成器表达式元组切片对序列使用和*序列的增量赋值list.sort方法和内置函数sortedbisect数组memoryviewdeque 第 3 章 字典和集合第 4 章 文本和字节序列 第三部分 把函数视…