KannalaBrandt8 鱼眼相机模型

发布时间:2026/7/10 13:11:36

KannalaBrandt8 鱼眼相机模型
1. 鱼眼相机鱼眼相机镜头是由十几个不同的透镜组合而成在成像的过程中入射光线经过不同程度的折射投影到尺寸有限的成像平面上使得鱼眼镜头拥有更大的视野范围。下图为鱼眼相机的组成结构与针孔相机原理不同鱼眼镜头采用非相似成像在成像过程中引入畸变通过对直径空间的压缩突破成像视角的局限从而达到广角成像。鱼眼相机是一种焦距小于等于16mm且视角接近或者等于180°的极端广角镜头但是正是因为他极端的短焦和广角导致它因为光学原理而产生的畸变非常剧烈所以针孔模型并不能很好的描述鱼眼相机所以需要一种新的相机模型来对鱼眼相机进行近似模拟。2. 相机畸变鱼眼镜头无论如何它的边缘线条都是要弯曲的即使90度的鱼眼也是这样这种畸变我们在很多广角镜头上都可以看到而这就是明显的桶形畸变。同样的120度的鱼眼看起来弯曲的更加厉害一些了而且被容纳进范围的景物更多150度同样如此而180度的鱼眼则可以把镜头周围180度范围内的所有物体都拍摄进去。众所周知焦距越短视角越大因光学原理产生的变形也就越强烈。为了达到180度的超大视角鱼眼镜头不得不允许这种变形桶形畸变的合理存在。针对原始图像进行畸变校正后带有冗余边界需要做进一步截取。如下图3. KannalaBrandt8模型KB模型能够很好的适用于普通广角以及鱼眼镜头。KB模型假设图像光心到投影点的距离和角度的多项式存在比例关系角度的定义是点所在的投影光纤和主轴之间的夹角。3.1. 投影过程其中3.2. 反投影过程给定图像上一点可以得到归一化坐标可以得到带畸变的入射角去畸变后得到最后得到单位球面坐标4. KannalaBrandt8算法在ORB-SLAM3的实现4.1. 投影/** * brief 投影 * param 3D点 * return 像素坐标 * 注意ORBSLAM3为投影重载了许多方法以接受各种不同的数据类型在此就不一一列举了 * 它们只是进行了数据类型之间的转换然后统一以本方式实现不再赘述 **/ cv::Point2f KannalaBrandt8::project(const cv::Point3f p3D) { // r^2 x^2 y^2 const float x2_plus_y2 p3D.x * p3D.x p3D.y * p3D.y; // θ atan2(r,z) const float theta atan2f(sqrtf(x2_plus_y2), p3D.z); const float psi atan2f(p3D.y, p3D.x); // 计算θ的3579次方 // 计算2次方是为了方便计算3579次 相当于中间变量 const float theta2 theta * theta; const float theta3 theta * theta2; const float theta5 theta3 * theta2; const float theta7 theta5 * theta2; const float theta9 theta7 * theta2; // mvParameters是存放相机参数和畸变系数的数组 // [4] [5] [6] [7] 分别代表k1 k2 k3 k4 // 是不是感觉很熟悉 其实KB模型也常被用于针孔的畸变模型 // 计算获得d(θ) const float r theta mvParameters[4] * theta3 mvParameters[5] * theta5 mvParameters[6] * theta7 mvParameters[7] * theta9; // 注意注释的r和代码的r不是一个东西 代码r 注释d(θ) 注释r 代码x2_plus_y2 // [0] [1] [2] [3] 分别代表 fx fy cx cy // 利用公式 u (fx * d(θ) * xc) / r // v (fy * d(θ) * yc) / r // cos(psi) xc/r sin(psi) yc/r return cv::Point2f(mvParameters[0] * r * cos(psi) mvParameters[2], mvParameters[1] * r * sin(psi) mvParameters[3]); }4.2. 反投影/** * brief 反投影过程 * param 像素坐标 * return 归一化坐标 **/ cv::Point3f KannalaBrandt8::unproject(const cv::Point2f p2D) { //Use Newton method to solve for theta with good precision (err ~ e-6) // 使用Newton法来求解θ获得了很好的效果 // 获取归一化的x,y坐标 // x (u - cx) / fx // y (v - cy) / fy cv::Point2f pw((p2D.x - mvParameters[2]) / mvParameters[0], (p2D.y - mvParameters[3]) / mvParameters[1]); // xd yd // 设置尺度为1 float scale 1.f; // xd θd/r * xc yd θd/r * yc // xd^2 yd^2 (θd^2 / r^2) * (xc^2 yc^2) // xc^2 yc^2 r^2 // θ (xd^2 yd^2)^(1/2) float theta_d sqrtf(pw.x * pw.x pw.y * pw.y); // sin(psi) yc / r //确保θd在[-π,π]的范围内 theta_d fminf(fmaxf(-CV_PI / 2.f, theta_d), CV_PI / 2.f); // 不能超过180度 // 已知θd 求解 θ if (theta_d 1e-8) { //Compensate distortion iteratively float theta theta_d; // θ的初始值定为了θd // 开始迭代 for (int j 0; j 10; j) { float theta2 theta * theta, theta4 theta2 * theta2, theta6 theta4 * theta2, theta8 theta4 * theta4; float k0_theta2 mvParameters[4] * theta2, k1_theta4 mvParameters[5] * theta4; float k2_theta6 mvParameters[6] * theta6, k3_theta8 mvParameters[7] * theta8; // f(θ) θ k1 * θ^3 k2 * θ^5 k3 * θ^7 k4 * θ^9 // e(θ) f(θ) - θd // 直接求解θ很难 所以通过求导优化的方法 // 目标是优化获得e(θ) 0对应的θ // e(θ) 1 3 * k1 * θ^2 5 * k2 * θ^4 7 * k3 * θ^6 9 * k4 * θ^8 // δ(θ) e(θ) / e(θ) 修正量 float theta_fix (theta * (1 k0_theta2 k1_theta4 k2_theta6 k3_theta8) - theta_d) / (1 3 * k0_theta2 5 * k1_theta4 7 * k2_theta6 9 * k3_theta8); // 进行修正 theta theta - theta_fix; // 如果更新量变得很小表示接近最终值 if (fabsf(theta_fix) precision) break; } //scale theta - theta_d; // 求得tan(θ) / θd scale std::tan(theta) / theta_d; } // 获取归一化坐标 return cv::Point3f(pw.x * scale, pw.y * scale, 1.f); }4.3. 求解雅各比矩阵/** * breif 求解像素坐标关于三维点的雅各比矩阵 * param p3D 三维点 * return 雅各比矩阵[一个两行三列的矩阵] **/ cv::Mat KannalaBrandt8::projectJac(const cv::Point3f p3D) { float x2 p3D.x * p3D.x, y2 p3D.y * p3D.y, z2 p3D.z * p3D.z; float r2 x2 y2; float r sqrt(r2); float r3 r2 * r; float theta atan2(r, p3D.z); float theta2 theta * theta, theta3 theta2 * theta; float theta4 theta2 * theta2, theta5 theta4 * theta; float theta6 theta2 * theta4, theta7 theta6 * theta; float theta8 theta4 * theta4, theta9 theta8 * theta; float f theta theta3 * mvParameters[4] theta5 * mvParameters[5] theta7 * mvParameters[6] theta9 * mvParameters[7]; float fd 1 3 * mvParameters[4] * theta2 5 * mvParameters[5] * theta4 7 * mvParameters[6] * theta6 9 * mvParameters[7] * theta8; // u (fx * θd * x) / r cx // v (fy * θd * y) / r cy // θd θ k1 * θ^3 k2 * θ^5 k3 * θ^7 k4 * θ^9 // θ arctan(r,z) // r (x^2 y^2)^(1/2) cv::Mat Jac(2, 3, CV_32F); Jac.atfloat(0, 0) mvParameters[0] * (fd * p3D.z * x2 / (r2 * (r2 z2)) f * y2 / r3); // ∂u/∂x Jac.atfloat(1, 0) mvParameters[1] * (fd * p3D.z * p3D.y * p3D.x / (r2 * (r2 z2)) - f * p3D.y * p3D.x / r3); // ∂v/∂x Jac.atfloat(0, 1) mvParameters[0] * (fd * p3D.z * p3D.y * p3D.x / (r2 * (r2 z2)) - f * p3D.y * p3D.x / r3); // ∂u/∂y Jac.atfloat(1, 1) mvParameters[1] * (fd * p3D.z * y2 / (r2 * (r2 z2)) f * x2 / r3); // ∂v/∂y Jac.atfloat(0, 2) -mvParameters[0] * fd * p3D.x / (r2 z2); // ∂u/∂z Jac.atfloat(1, 2) -mvParameters[1] * fd * p3D.y / (r2 z2); // ∂v/∂z std::cout CV JAC: Jac std::endl; return Jac.clone(); }参考文献ORBSLAM3(六) Kannala_Brandt鱼眼相机模型_Y.Q.Shi的博客-CSDN博客_鱼眼相机slam一文搞懂鱼眼相机模型

相关新闻

Air实现Go程序的热重载(热加载)

Air实现Go程序的热重载(热加载)

2026/7/10 13:11:36

简介: air是Go的热加载工具,它可以监听文件或者目录的变化,自动编译,重启程序,提高开发的工作效率。 场景: 在代码修改后需要通过ctrlc来停止项目,go run的方式来再次重启项目,在…

5分钟掌握网盘直链解析:告别龟速下载的终极解决方案

5分钟掌握网盘直链解析:告别龟速下载的终极解决方案

2026/7/10 13:11:36

5分钟掌握网盘直链解析:告别龟速下载的终极解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云…

OpenCV 中 Mat 的 type 类型介绍

OpenCV 中 Mat 的 type 类型介绍

2026/7/10 13:11:36

OpenCV 中矩阵 cv::Mat 的成员函数 type() 回了矩阵相关的数据类型信息,除元素的数据类型(低3位)外,还包括通道 (channel) 的个数(高3位) cv::Mat test(100, 100, CV_32FC3); int type test.type(); 1.…

bRPC深度架构解析:从C++高性能RPC框架到百万级并发实战优化

bRPC深度架构解析:从C++高性能RPC框架到百万级并发实战优化

2026/7/10 16:31:43

bRPC深度架构解析:从C高性能RPC框架到百万级并发实战优化 【免费下载链接】brpc brpc is an Industrial-grade RPC framework using C Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recom…

newapi签到 - 青龙面板自动签到脚本

newapi签到 - 青龙面板自动签到脚本

2026/7/10 16:31:43

newapi自动签到、获取额度。工具类平台的签到和任务每天都能获取资源和权益,但手动操作效率低。这款自动脚本帮你轻松完成日常任务。功能介绍 「newapi签到」脚本支持以下功能: • 自动签到 • 自动完成任务 • 多账号管理 • 结果通知 使用方法 1. 下载…

gphotos-uploader-cli与官方工具对比:为什么选择命令行解决方案

gphotos-uploader-cli与官方工具对比:为什么选择命令行解决方案

2026/7/10 16:31:43

gphotos-uploader-cli与官方工具对比:为什么选择命令行解决方案 【免费下载链接】gphotos-uploader-cli Command line tool to mass upload media folders to your google photos account(s) (Mac OS / Linux) 项目地址: https://gitcode.com/gh_mirrors/gp/gphot…

为什么你的Notion知识库始终“死气沉沉”?——ChatGPT深度集成后,知识复用率提升317%的底层逻辑

为什么你的Notion知识库始终“死气沉沉”?——ChatGPT深度集成后,知识复用率提升317%的底层逻辑

2026/7/10 16:31:43

更多请点击: https://intelliparadigm.com 第一章:为什么你的Notion知识库始终“死气沉沉”? 你精心搭建的Notion知识库,页面排版精美、数据库结构清晰、图标色彩协调——可半年过去,它却像一座被遗忘的数字博物馆&am…

如何用kill-doc实现一键下载30+文档平台:新手5分钟终极指南

如何用kill-doc实现一键下载30+文档平台:新手5分钟终极指南

2026/7/10 16:31:43

如何用kill-doc实现一键下载30文档平台:新手5分钟终极指南 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为…

sVim黑名单功能详解:如何在特定网站禁用快捷键

sVim黑名单功能详解:如何在特定网站禁用快捷键

2026/7/10 16:21:43

sVim黑名单功能详解:如何在特定网站禁用快捷键 【免费下载链接】sVim Safari extension with shortcuts similar to Vim 项目地址: https://gitcode.com/gh_mirrors/sv/sVim sVim是一款为Safari浏览器设计的Vim风格快捷键扩展,让用户能够在浏览器…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/9 19:40:56

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/10 6:57:56

1. 项目背景与核心价值在计算机视觉领域,YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备(如树莓派、Jetson Nano或手机终端)时,立刻会遇到两个致命问题:模型体积庞大(原始YO…

终极原神FPS解锁器完整指南:轻松突破60帧限制

终极原神FPS解锁器完整指南:轻松突破60帧限制

2026/7/10 0:00:42

终极原神FPS解锁器完整指南:轻松突破60帧限制 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 原神FPS解锁器是一款专为《原神》玩家设计的开源工具,通过先进的Wri…

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

2026/7/10 0:00:42

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?🎵 【免费下载链接】YesPlayMusic 高颜值的第三方网易云播放器,支持 Windows / macOS / Linux :electron: 项目地址: https://gitcode.com/gh_mirrors/ye/YesPlayMusic…

从零实现红黑树:手写C++的set与map容器

从零实现红黑树:手写C++的set与map容器

2026/7/10 0:00:42

1. 项目概述:从STL容器到自研轮子在C的日常开发中,std::set和std::map是我们再熟悉不过的伙伴了。它们一个负责管理不重复的集合,一个负责维护键值对映射,底层都依赖一颗高效的红黑树来保证数据的有序性和操作的性能。但你是否曾想…