当前位置: 首页 > news >正文

相机内参标定理论篇------张正友标定法

一、为什么做相机标定?

标定是为了得到相机坐标系下的点和图像像素点的映射关系,为摄影几何、计算机视觉等应用做准备。

二、为什么需要张正友标定法?

张正友标定法使手工标定相机成为可能,使相机标定不再需要精密的设备帮助。但内参标定的精度却需要依赖采集数据的质量。精度不如专业设备的结果,不过在日常科研等对精度要求不是非常高的领域足够满足。

三、为什么张正友使手工标定相机成为可能?

我们先思考一个问题,以针孔模型为例相机标定需要那些参数:

内参:fx fy cx cy k1 k2 p1 p2;

外参:R t。

假如我们用n张图像来标定相机的话,我们需要求解8 +(3 + 3)x n = 6n + 8个参数。求解这么多参数需要使用最优化。构建目标函数:

\sum_{1}^{n}\sum_{1}^{m}\left \| m_{ij} - m\hat{}(A, k_{1}, k_{2}, p_{1}, p_{2},R_{i}, t_{i}, M_{j})\right \|^{2}

其中m_{ij}为图像上角点,m\hat{}为投影点。

我们知道优化问题最害怕的就是遇到局部最优,导致优化后的结果和真实值相差较大。为了解决局部最优,最好的方法是提供较为准确的初值这就是张正友标定法最重要的作用。通过正交矩阵性质计算出不考虑畸变的相机内参和外参初值,然后利用最优化的方法,便可以得到精确的内参。

四、如何推导?

已知相机成像过程:世界坐标系->相机坐标系->相机坐标系->像素坐标系。可以用下面公式描述:

其中M为世界坐标系点,R t为世界坐标系到相机坐标系的旋转矩阵和平移量,A为相机内参矩阵,s为比例系数。

将具体数值代入公式可以获得:

其中r为R矩阵的列向量。已知世界坐标系在实际中选取为标定板坐标系,因此世界坐标系下点的Z值为零,因此可以进一步化简。

由于相机图像和标定板都是平面,两个平面上坐标的对应关系就可以利用单应矩阵。因此可以引入单应矩阵H:

用列向量表示H得:

由旋转矩阵是正交矩阵可以得到两条性质:列向量两两正交,且列向量是单位向量,因此可以得到:

因此可以用B表示A^{-T}A^{-1}:

将B代入上式并展开得到:

其中:

最后得到:

到现在,需要先求解H矩阵,然后利用H矩阵求解B矩阵。已知H矩阵有八个未知数(约去比例系数,使矩阵最后一项为1),利用下面公式,一对对应点可以提供两个约束,因此需要四个点可以求出单应矩阵H;

\begin{bmatrix} u\\ v\\ 1 \end{bmatrix} = H\begin{bmatrix} X\\ Y\\ 1 \end{bmatrix}

有了H矩阵值后可以得到V_{ij}值,已知B是对称矩阵因此有六个未知数,每个单应矩阵H可以提供两个约束,所以求解B最少需要三个不同的单应矩阵,也就是三个不同视角的标定图像。

求出B后便可以求解内参矩阵A,再得到A后利用下面公司便可以求出外参矩阵R和t:

至此便得到了相机内参的初值和不同标定图像外参的初值,然后再利用上面提到的目标函数进行最优化得到最后标定的内参。

总结:

1.张正友标定法最重要的地方是计算出了相机内参和外参的数值解,然后作为初始值代入的优化函数,解决了局部最优化的问题,使手工标定相机内参成为可能。

2.由于相机标定数据是手工采集,因此相机内参标定的精度取决于数据质量。涉及标定板选取和采集图像的注意事项,后续文章会介绍如何采集图像。

3.由于相机内外参在投影过程具有耦合关系,所以在优化时外参结果不准确也会影响内参结果,导致重投影误差很小但是得到的相机内参误差较大。

4.在需要精确内参标定结果时推荐使用相机厂商标定结果,在专业相机内参标定时,利用机械臂抓住相机在特定位置进行采图。相机外参有非常准确的初值,在优化时可以得到非常高的内参精度。

相关文章:

  • gem5学习(7):内存系统中创建 SimObjects--Creating SimObjects in the memory system
  • Docker六 | Docker Compose容器编排
  • 【Java中序列化的原理是什么(解析)】
  • [每周一更]-(第40期):GIT更换远程仓库地址
  • 八股文打卡day15——计算机网络(15)
  • Spring AOP—深入动态代理 万字详解(通俗易懂)
  • 组合[中等]
  • 医院绩效考核系统源码,java源码,商业级医院绩效核算系统源码
  • docker-compose部署kafka
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • 嵌入式开发网络配置——windows连热点,开发板和电脑网线直连
  • 从a类到b类理解原型链
  • Python开发GUI常用库PyQt6和PySide6介绍之三:交互和通信方式讲解
  • 第八章 创建Callout Library - ZFentry 链接选项
  • Spring DefaultListableBeanFactory源码分析
  • [译]CSS 居中(Center)方法大合集
  • 2017-09-12 前端日报
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • iOS | NSProxy
  • javascript 哈希表
  • Koa2 之文件上传下载
  • Netty源码解析1-Buffer
  • PHP面试之三:MySQL数据库
  • Quartz初级教程
  • vue总结
  • webpack入门学习手记(二)
  • 初识 beanstalkd
  • 从输入URL到页面加载发生了什么
  • 大数据与云计算学习:数据分析(二)
  • 电商搜索引擎的架构设计和性能优化
  • 工程优化暨babel升级小记
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 如何使用 JavaScript 解析 URL
  • 时间复杂度与空间复杂度分析
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • linux 淘宝开源监控工具tsar
  • raise 与 raise ... from 的区别
  • 阿里云服务器购买完整流程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #define 用法
  • (+4)2.2UML建模图
  • (3)选择元素——(17)练习(Exercises)
  • (7)STL算法之交换赋值
  • (Note)C++中的继承方式
  • (八)Spring源码解析:Spring MVC
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (强烈推荐)移动端音视频从零到上手(下)
  • (一)Dubbo快速入门、介绍、使用
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .dwp和.webpart的区别
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递