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

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

上一章节介绍学习了(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.rhkb.cn/news/262973.html

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

相关文章

测试环境搭建整套大数据系统(六:搭建sqoop)

一:下载安装包 https://archive.apache.org/dist/sqoop/ 二:解压修改配置。 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /opt cd /opt mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop-1.4.7修改环境变量 vi /etc/profile#SQOOP_HOME export SQOOP_…

Python 在Word中创建表格并填入数据、图片

在Word中,表格是一个强大的工具,它可以帮助你更好地组织、呈现和分析信息。本文将介绍如何使用Python在Word中创建表格并填入数据、图片,以及设置表格样式等。 Python Word库: 要使用Python在Word中创建或操作表格,需…

Atcoder ABC340 A-D题解

比赛链接:ABC340 话不多说&#xff0c;看题。 Problem A: 签到。 #include <bits/stdc.h> using namespace std; int main(){int a,b,d;cin>>a>>b>>d;for(int ia;i<b;id)cout<<i<<endl;return 0; } Problem B: 还是签到题。一个v…

Neo4j导入数据之JAVA JDBC

目录结构 前言设置neo4j外部访问代码整理maven 依赖java 代码 参考链接 前言 公司需要获取neo4j数据库内容进行数据筛查&#xff0c;neo4j数据库咱也是头一次基础&#xff0c;辛辛苦苦安装好整理了安装neo4j的步骤&#xff0c;如今又遇到数据不知道怎么创建&#xff0c;关关难…

石头剪刀布游戏(C语言)

题目描述 石头剪刀布游戏有 3 种出拳形状&#xff1a;石头、剪刀、布。分别用字母 A , B , C 表示。 游戏规则: 出拳形状之间的胜负规则如下&#xff1a; A > B&#xff1b;B > C&#xff1b;C > A&#xff1b;">"左边一个字母&#xff0c;表示相对优…

STM32F4XX - CAN设置

can协议部分 - 逻辑信号和电平信号 先贴上CAN信号在物理信号线上的查分信号表示形式 显性电平&#xff1a; 电压差范围为1.5-2.5v。 对应的逻辑电平是0 隐性电平&#xff1a; 其他 对应的逻辑电平是1 为什么显性电平对应的逻辑电平值为0&#xff0c;而隐性电平对应的逻辑电平…

Spring基础之AOP和代理模式

文章目录 理解AOPAOP的实现原理 AOP代理模式静态代理动态代理1-JDK动态代理2-CGLIB动态代理 总结 理解AOP OOP - - Object Oriented Programming 面向对象编程 AOP - - Aspect Oriented Programming 面向切面编程 AOP是Spring提供的关键特性之一。AOP即面向切面编程&#xff0…

年关将至送大礼 社区适时献爱心

在这个快节奏的时代&#xff0c;社区作为人们生活的重要组成部分&#xff0c;其凝聚力和互助精神显得尤为重要。2024年2月7日&#xff0c;实践队员李若钰有幸参与了社区礼盒分装的活动&#xff0c;这不仅仅是一次简单的劳动&#xff0c;更是一次心灵的洗礼和感悟。 礼盒分装&am…

10.CSS3的calc函数

CSS3 的 calc 函数 经典真题 CSS 的计算属性知道吗&#xff1f; CSS3 中的 calc 函数 calc 是英文单词 calculate&#xff08;计算&#xff09;的缩写&#xff0c;是 CSS3 的一个新增的功能。 MDN 的解释为可以用在任何长度、数值、时间、角度、频率等处&#xff0c;语法如…

Git基本操作(2)

Git基本操作&#xff08;2&#xff09; 上交文件之后&#xff0c;git文件的变化git cat-file HEAD指针里面有啥文件被修改git statusgit diff 文件名 版本回退&#xff08;git reset&#xff09;撤销回退git reflog 撤销的三种情况还没有addgit checkout -- [file] 已经add还没…

week04day03(爬虫 beautifulsoup4、)

一. 使用bs4解析网页 下载bs4 - pip install beautifulsoup4 使用的时候 import bs4专门用于解析网页的第三方库 在使用bs4的时候往往会依赖另一个库lxml pip install lxml 网页代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><…

js谐音梗创意小游戏《望子成龙》

&#x1f33b; 前言 龙年到来&#xff0c;祥瑞满天。愿您如龙般矫健&#xff0c;事业腾飞&#xff1b;如龙鳞闪耀&#xff0c;生活美满。祝您龙年大吉&#xff0c;万事如意&#xff01; 龙年伊始&#xff0c;我给各位设计了一款原创的小游戏&#xff0c;话不多说&#xff0c;直…

vue3前端项目开发,具备纯天然的防止爬虫采集的特征

vue3前端项目开发,具备纯天然的防止爬虫采集的特征&#xff01;众所周知&#xff0c;网络爬虫可以在网上爬取到一些数据&#xff0c;很多公司&#xff0c;为了自己公司的数据安全&#xff0c; 尤其是web端项目&#xff0c;不希望被爬虫采集。那么&#xff0c;您可以使用vue技术…

redis GEO 类型原理及命令详解

目录 前言 一、GeoHash 的编码方法 二、Redis 操作GEO类型 前言 我们有一个需求是用户搜索附近的店铺&#xff0c;就是所谓的位置信息服务&#xff08;Location-Based Service&#xff0c;LBS&#xff09;的应用。这样的相关服务我们每天都在接触&#xff0c;用滴滴打车&am…

离散数学(一) 集合

属于关系 表示 枚举法&#xff1b; 叙述法&#xff1b; 文氏图法 基数 空集 全集 全集是相对唯一的 相等关系 有相同元素看作一个元素 包含关系 幂集 集合运算 并集 交集 补集 差集 对称差集 定理 可数集合与不可数集合 自然数集 等势 如果存在集合A到集合B的双射(又称一一…

【Oracle】玩转Oracle数据库(三):数据库的创建和管理

前言 嘿&#xff0c;各位数据库小能手们&#xff01;今天我们要进入数据库的创世纪&#xff0c;探索Oracle数据库的创建和管理&#xff01;&#x1f527;&#x1f4bb; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;三&#xff09;&#xff1a;数据库的创建和管理中&#…

Flutter常用命令,持续更新

目录 前言 Flutter 常用命令 Dart 常用命令 adb 常用命令&#xff08;用于 Android 开发&#xff09; 前言 当在开发Flutter项目时&#xff0c;熟悉一些常用的命令是非常重要的。这些命令可以帮助你执行各种任务&#xff0c;从构建应用程序到调试和测试。以下是一些Flutte…

Unity中URP实现水体效果(水的深度)

文章目录 前言一、搭建预备场景1、新建一个面片&#xff0c;使其倾斜一个角度&#xff0c;来模拟水底和岸边的效果2、随便创建几个物体&#xff0c;作为与水面接触的物体3、再新建一个面片&#xff0c;作为水面 二、开始编写水体的Shader效果1、新建一个URP基础Shader2、把水体…

Redis篇之Redis持久化的实现

持久化即把数据保存到可以永久保存的存储设备当中&#xff08;磁盘&#xff09;。因为Redis是基于内存存储数据的&#xff0c;一旦redis实例当即数据将会全部丢失&#xff0c;所以需要有某些机制将内存中的数据持久化到磁盘以备发生宕机时能够进行恢复&#xff0c;这一过程就称…

TreeData 数据查找

TreeData 数据查找 最近做需求的时候遇到了这样的一个需求&#xff0c;Tree组件数据支持查找&#xff0c;而且TreeData的数据层级是无限级的 开始想的事借助UI组件库&#xff08;Ant-design-vue&#xff09;中的Tree组件的相关方法直接实现,看了下api 发现没法实现&#xff0c;…