鱼眼相机投影模型

news/2024/10/22 11:02:23/

1、 成像投影原理

其成像过程分解成两步:
1.归一化平面上(Zc = 1)的三维空间点线性地投影到一个球面上,它是一个虚拟的单位球面,它的球心与相机坐标系的原点重合;
2.单位球面上的点投影到图像平面上,这个过程是非线性的,并产生畸变。

在这里插入图片描述

等距模型:
投影模型描述: 鱼眼图像中的点到畸变中心的距离 r_d 与投影角度 theta 的关系

投影模型与畸变没有关系,即使没有畸变发生,也是按照这种方式进行投影。

等距投影模型:
在这里插入图片描述

r_d 为入射线与虚拟球面的交点到Z轴的距离。由于畸变的影响,r_d 在径向上有所调整,但是不改变三角相似性。即:

在这里插入图片描述

在这里插入图片描述等距投影关系图

2、 成像推导过程

请添加图片描述

2-1、世界坐标到相机坐标系

R、T 变换将空间中一点转换到鱼眼坐标下。
归一化到鱼眼Zc = 1 平面上。得到归一化(x, y,1)

2-2、归一化平面到单位球面

根据映射点(x, y,1)投影到虚拟球面上,求 theta , theta 为入射光线与 Zc 轴夹角。

2-3、theta 畸变

加入畸变系数,求畸变theta_d。

2-4、等比映射

根据 : r_d = f * theta

f 焦距固定之下, r_d 与 theta 成等比关系。
r_d1 / r_d2 = theta1 / theta2

所以 theta 的 畸变角度 为 theta_d 时:
r / r_d = theta / theta_d

在这里插入图片描述
即可重新求得畸变后的相机坐标系下的(xd, yd), 上面的过程始终在3维空间中。

2-5、相机坐标系到成像平面

在这里插入图片描述

3、 单点去畸变

在鱼眼图像上获取像素点 (u,v) , 经过内参反映射到相机三维坐标归一化面上,此时得到的点是经过畸变后的点(x_d, y_d),而我们希望获取的是没有畸变的三维空间坐标点(x_c, y_c)

在这里插入图片描述

在相机坐标系中有:
在这里插入图片描述

所以等距模型中:
在这里插入图片描述

已知 theta_d 和畸变参数k2, k3, k4, k5。就可以通过迭代法求解 theta。

在这里插入图片描述

其中牛顿迭代代码如下:

    def gf(self, k2, k3, k4, k5, theta):theta_2 = theta * thetatheta_4 = theta_2 * theta_2theta_6 = theta_4 * theta_2theta_8 = theta_6 * theta_2gf = 1 + 3 * k2 * theta_2 + 5 * k3 * theta_4 + 7 * k4 * theta_6 + 9 * k5 * theta_8return gfdef distort_theta(self, k2, k3, k4, k5, theta):theta_2 = theta * thetatheta_3 = theta * theta_2theta_5 = theta_3 * theta_2theta_7 = theta_5 * theta_2theta_9 = theta_7 * theta_2theta_d = theta + k2 * theta_3 + k3 * theta_5 + k4 * theta_7 + k5 * theta_9return theta_ddef newton_itor_theta(self, k2, k3, k4, k5, theta_d):theta = theta_dmax_iter = 10for i in range(max_iter):gf_t0 = self.gf(k2, k3, k4, k5, theta)f_t0 = self.distort_theta(k2, k3, k4, k5, theta) - theta_dtheta = theta - f_t0 / gf_t0if abs(f_t0) < 1e-6:breakreturn theta

已知经纬度角度后,映射到球面坐标上: 的到相机坐标系真实三维空间坐标。

在这里插入图片描述
映射到实际成像 Z = R 平面上。

反投影映射代码如下:

    def lift_projective(self, p):xw = self.K_matrix_inv.dot(np.array([p[0], p[1], 1], dtype=float))x_d = xw[0]y_d = xw[1]phi = np.arctan2(y_d, x_d)theta_d = np.sqrt(x_d ** 2 + y_d ** 2)theta = self.newton_itor_theta(self.k2, self.k3, self.k4, self.k5, theta_d)x_c = np.sin(theta) * np.cos(phi)y_c = np.sin(theta) * np.sin(phi)z_c = np.cos(theta)return np.array([x_c, y_c, z_c])

http://www.ppmy.cn/news/545808.html

相关文章

android4.2 小红盒,不插电也能用!网红爆款:天猫精灵妙物“小红盒”投影仪评测...

如今在“线上”买东西俨然成为了生活中的一种常态操作&#xff0c;毕竟有些小伙伴们因忙于工作&#xff0c;没有时间去实体店铺买东西&#xff0c;继而才会选择“线上买”这种方式。但是&#xff0c;在线上买东西虽然快捷、方便&#xff0c;但是也会面临一无法避免的问题&#…

摄像机投射投影模型

转载于&#xff1a;https://blog.csdn.net/shenziheng1/article/details/52890223 1.写在前面的话 摄像机通过成像透镜将三维场景投影到摄像机二维像平面上&#xff0c;这个投影可以用成像变换进行表示&#xff0c;也就是我们平常说的摄像机投影模型。摄像机成像模型有不同的描…

VSCode gdb 调试 qemu u-boot 的方法

前言 最近使用 VS Code GDB 调试 qemu&#xff0c;有了一点收获&#xff0c;u-boot 编译后生成了一个 elf 文件&#xff1a;u-boot&#xff0c;是否也可以调试一下&#xff1f; 为何需要 VS Code GDB 调试&#xff0c;直接 gdb 调试不就可以了吗&#xff1f;答案就是&#xff…

设计模式-工厂方法模式

​ 文章目录 发展&#xff1a;简单实现&#xff1a;命名不规范:可读性差可维护性差可扩展性差团队合作问题 除数不能为0问题&#xff1a;开闭原则问题&#xff1a;想象力创造力&#xff1a;首先是发现力&#xff1a;接下来是想象力&#xff1a;总结 大话设计模式这本书反反复复…

2023年如何选购一部4000元价位的笔记本电脑(附跳坑说明)

2023年如何选购一部4000元价位的笔记本电脑&#xff08;附带坑的说明&#xff09; 本文是一个快速指南&#xff0c;不包含选购中涉及的所有知识点&#xff0c;尤其是大量的具体硬件参数&#xff0c;内容主要关注在如何快速抓住自己真正的需求&#xff0c;快速筛选掉不匹配的型…

你真的会写 HelloWorld 吗?

目录 Hello World 写一个批处理命令行脚本 关于include 关于程序的入口 输出充定向 在内存的存储详情 WinHex工具介绍 初学C语言时&#xff0c;第一个程序一定是Hello World!。但是Hello World的具体实现细节你真的了解吗&#xff1f; Hello World C语言代码如下&#…

java replace会替换吗,java replace replaceAll 替换字符串的用法和区别实例

java replace replaceAll 是替换字符串最常用的方法&#xff0c;但实际上用法是有区别的&#xff0c;replace只能传字符不能传正则表达式&#xff0c;replaceAll 默认传入的就是正则表达式。下面是实例测试代码&#xff1a; public class TestDemo { public static void main(S…

Python学习笔记之常用操作符,条件分支和循环用法示例

本文实例讲述了Python常用操作符,条件分支和循环用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; #Pyhon常用操作符想要学习Python&#xff1f;Python学习交流群&#xff1a;973783996满足你的需求&#xff0c;资料都已经上传群文件&#xff0c;可以自行下载&…