Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map

news2024/12/25 1:08:04

文章目录

  • Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map
    • 1. 相似源码
      • choose_solution.py
      • eight_point.py
      • epipolar_match.py

Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map

1. 相似源码

由于paper并没有给出源码,我们找到了相似的源码:https://github.com/nadiawangberg/structure-based-visual-localization。

这是一个相机内部参数的文本文件,其中包含了一个内部参数矩阵K。该矩阵的元素用于将3D世界坐标系中的点转换为2D图像坐标系中的点。这个文件中的矩阵表示相机的内部参数,该矩阵的值在相机制造时被测量得到。

具体来说,这个文件中的每一行包含一个3×3的矩阵K。这个矩阵包含了相机的内部参数,它包括焦距、图像中心的偏移量和一个缩放因子。该矩阵用于将3D世界坐标系中的点投影到2D图像平面上。K矩阵中的值可以通过对相机进行标定(即在多个位置和朝向下拍摄一些图像,然后测量相机的参数)得到。

这里的K矩阵如下:

1520.4  0       302.32
0       1525.9  246.87
0       0       1

其中,第一行表示相机在水平方向上的焦距和图像中心的偏移量,第二行表示相机在竖直方向上的焦距和图像中心的偏移量,最后一行表示一个缩放因子和一个平移因子

打印:
K1:相机1的内参矩阵
K2:相机2的内参矩阵
R: 从相机1到相机2的旋转矩阵,是一个3x3的矩阵。
t: 从相机1到相机2的平移向量,是一个3x1的列向量。

函数返回相机1和相机2的投影矩阵P1和P2,分别是3x4的矩阵。

P1和P2分别是相机1和相机2的投影矩阵,是一个3x4的矩阵。

在计算机视觉中,我们通常使用投影矩阵将三维空间中的点投影到相机坐标系下的二维图像平面上。对于一个三维点 X = ( X , Y , Z ) X=(X,Y,Z) X=(X,Y,Z),它在相机坐标系下的表示为 X c = ( X c , Y c , Z c ) X_c=(X_c,Y_c,Z_c) Xc=(Xc,Yc,Zc)。那么,它在相机图像平面上的投影点 p = ( u , v ) p=(u,v) p=(u,v),可以通过以下方式计算:
在这里插入图片描述

其中, P P P是投影矩阵,是一个3x4的矩阵。因此,对于相机1和相机2,它们的投影矩阵分别是 P 1 P_1 P1 P 2 P_2 P2

在这个函数中,我们根据相机1和相机2的内参矩阵 K 1 K_1 K1 K 2 K_2 K2以及从相机1到相机2的旋转矩阵 R R R和平移向量 t t t,计算得到它们的投影矩阵 P 1 P_1 P1 P 2 P_2 P2。这些投影矩阵可以用来将三维空间中的点投影到相应的二维图像平面上。

这是一个 Python 函数,它接受两个相机的内参矩阵(K1 和 K2),以及它们之间的旋转和平移(R 和 t),并计算出它们的投影矩阵 P1 和 P2。

第一个相机的投影矩阵 P1 是通过将内参矩阵 K1 与一个 3x4 的矩阵相乘得出的,这个 3x4 的矩阵的前三列是单位矩阵,第四列是零向量。这个 3x4 的矩阵表示从相机的 3D 坐标系到世界坐标系的转换。

第二个相机的投影矩阵 P2 是通过将内参矩阵 K2 与一个 3x4 的矩阵相乘得出的,这个 3x4 的矩阵的前三列是旋转矩阵 R,第四列是平移向量 t。这个 3x4 的矩阵表示从世界坐标系到第二个相机的 3D 坐标系的转换。

该函数返回投影矩阵 P1 和 P2,它们的形状都是 3x4。

第一个相机和第二个相机的坐标系通常是不同的,因为它们位于不同的位置和方向上。在三维空间中,我们通常使用世界坐标系来表示场景中的点和物体,而每个相机都有它自己的相机坐标系。

相机坐标系通常是相机的成像平面上的一个二维坐标系和相机光轴所构成的三维坐标系的结合。

在相机坐标系中,成像平面通常被定义为 z = f z=f z=f 的平面,其中 f f f 是相机的焦距。相机坐标系的 x x x 轴通常指向成像平面的右侧, y y y 轴通常指向成像平面的下方, z z z 轴通常指向相机的光轴方向。

因此,第一个相机和第二个相机的坐标系通常是不同的,因为它们位于不同的位置、方向和距离上,因此需要使用不同的相机矩阵来表示它们的投影矩阵。

choose_solution.py

这段代码的作用是从一组旋转和平移矩阵 R t s Rts Rts中选择一个最优解。这些矩阵用于将一个点从相机1的坐标系转换到相机2的坐标系。

具体地,这个函数计算每个旋转和平移矩阵 R R R t t t对应的相机1和相机2的投影矩阵 P 1 P_1 P1 P 2 P_2 P2,并使用这些矩阵对一组匹配的图像点进行三角化,得到三维点云。然后,对于每个旋转和平移矩阵,计算哪些点在两个相机都能看到(即在两个相机前面),并计算它们的数量。最终选择能够看到最多点的旋转和平移矩阵作为最优解,并返回该矩阵。

函数的输入参数包括:

  • u v 1 uv1 uv1:一个 n × 2 n\times 2 n×2的矩阵,表示第一张图像中的 n n n个匹配点的像素坐标。
  • u v 2 uv2 uv2:一个 n × 2 n\times 2 n×2的矩阵,表示第二张图像中的 n n n个匹配点的像素坐标。
  • K 1 K1 K1 K 2 K2 K2:分别表示相机1和相机2的内参矩阵。
  • R t s Rts Rts:一个包含多个旋转和平移矩阵的列表。

函数的输出参数包括:

  • R R R t t t:被选择为最优解的旋转和平移矩阵。

eight_point.py

这段代码实现了从给定的图像点对中计算基础矩阵的过程。基础矩阵是一个 3x3 的矩阵,用于将图像1中的点映射到图像2中的极线。具体来说,基础矩阵可以用于计算两个图像上的点对之间的对极几何关系。

该函数使用的方法是标准化8点算法(normalized 8-point algorithm),该算法通过最小二乘法来估计基础矩阵。具体来说,它使用归一化坐标来构造一个 9 × 9 9 \times 9 9×9 的矩阵 A A A,然后使用奇异值分解(SVD)来计算基础矩阵 F F F。然后,通过强制基础矩阵满足 F ⊤ F = I F^\top F = I FF=I 的条件来获得最终的基础矩阵。

函数 normalize_points 用于对输入的点进行归一化,使得它们的坐标具有零均值和单位方差。函数 closest_fundamental_matrix 用于计算最接近给定基础矩阵的基础矩阵,满足 Frobenius 范数最小。

  • 第13行:计算 n × 9 n \times 9 n×9 的矩阵 A A A,矩阵每一行都是两个点 ( u 1 , v 1 ) (u_1, v_1) (u1,v1) ( u 2 , v 2 ) (u_2, v_2) (u2,v2) 通过 Kronecker product 生成的 2 × 2 2\times 2 2×2 的矩阵 [ u 1 u 2 u 1 v 2 u 1 v 1 u 2 v 1 v 2 v 1 u 2 v 2 1 ] \begin{bmatrix} u_1u_2 & u_1v_2 & u_1 & v_1u_2 & v_1v_2 & v_1 & u_2 & v_2 & 1 \end{bmatrix} [u1u2u1v2u1v1u2v1v2v1u2v21],这里是将一个矩阵分割成单个的部分(Kronecker product),然后每一行是对应的点生成的向量。

  • 第17行:对 A A A 进行 SVD,返回 U , s , V T U, s, VT U,s,VT,其中 s s s 是奇异值的向量。

  • 第19行:将 V T VT VT 的最后一行向量作为 F F F 的向量表示,并将其形状转换为 3 × 3 3\times 3 3×3 的矩阵。

  • 第21行:使用函数 closest_fundamental_matrix F F F 转换为最接近它的奇异值矩阵,该矩阵具有形式 [ s 1 0 0 0 s 2 0 0 0 0 ] \begin{bmatrix} s_1 & 0 & 0 \\ 0 & s_2 & 0 \\ 0 & 0 & 0 \end{bmatrix} s1000s20000 ,其中 s 1 s_1 s1 s 2 s_2 s2 F F F 的奇异值。

  • 第24行:使用 T 1 T1 T1 T 2 T2 T2 通过它们的转置来“去规范化” F F F,得到从像素坐标到基础矩阵的映射。 最后返回 F F F

epipolar_match.py

这段代码实现了对极线搜索,根据已知的基础矩阵 F F F 和图像1中的点 u v 1 uv1 uv1,在图像2中找到与之对应的点 u v 2 uv2 uv2

具体来说,该函数遍历所有的点 u v 1 uv1 uv1,计算出该点在图像2中的对极线,然后在该对极线上进行搜索,找到与该点最佳匹配的点。这里的“最佳匹配”是指在搜索过程中误差最小的点。

在搜索过程中,对于每个 u v 1 uv1 uv1,首先取出以该点为中心,宽度为 2 w + 1 2w+1 2w+1 的方形窗口 W 1 W1 W1。然后,沿着该点的对极线,从左往右依次取出图像2中的窗口 W 2 W2 W2,计算 W 1 W1 W1 W 2 W2 W2 之间的绝对差,以此作为误差衡量标准,寻找误差最小的 W 2 W2 W2,然后将其对应的点 u 2 u2 u2 作为该点在图像2中的匹配点 u v 2 uv2 uv2

需要注意的是,由于像素坐标必须为整数,因此在计算 u v 2 uv2 uv2 时,需要对计算结果进行四舍五入取整操作。此外,还需要判断 u v 1 uv1 uv1 u v 2 uv2 uv2 是否超出图像范围,避免访问不存在的像素,同时也需要设置窗口大小 w w w,避免访问不存在的像素。

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

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

相关文章

ChatGPT带火的提示工程师,构造自己的提示语

ChatGPT是一个大语言模型,学过全球几乎公开的大部分有效知识库,它什么都懂。 ChatGPT的风靡,爆火了一个年薪百万的提示工程师这个新就业岗位。 提示工程师,也就是AI训练师,即通过与AI交互写出相关提示,以帮…

Spring Boot进阶(48):SpringBoot之集成WebSocket及使用说明 | 超级详细,建议收藏

1. 前言🔥 对于很多小伙伴来说,项目现在都普遍前后端分离,各干各的事儿,在前后端进行服务调用才会有大面积的碰头,后端接口数据格式发生变更要通知前端,相反,前端有变化要告诉后端,这…

【这小文章绝了!】一文看穿,MATLAB | 数组与矩阵超详细入门进阶必须看

目录 介绍 一、数组的创建和操作 通过 : 创建一维数组 通过logspace函数创建一维数组 通过linspace函数创建一维数组 二、数组的运算 数组的关系运算 数组的逻辑运算 三、矩阵 矩阵的构造 矩阵的下标引用 矩阵大小 四、矩阵元素的运算 矩阵的差分 矩阵运算 矩阵…

Spring Boot进阶(50):Spring Boot如何全局统一处理异常?| 超级详细,建议收藏

1. 前言🔥 今天和大家讨论的是Spring Boot如何统一处理异常。这里先说一下我们为什么需要全局统一处理异常?其实理由很简单,因为程序在运行的过程中,不可避免会产生各种各样的错误。比如说用户传过来的参数不正确,无法…

4端到端协议-4.2【实验】【计算机网络】

4端到端协议-4.2【实验】【计算机网络】 前言推荐4端到端协议4.2 TCP协议流捕获与TCP协议分析实验目的实验内容及实验环境实验原理实验过程实验过程演示 4.2.1实验章节测验一.单选题(共5题,25.0分)二.阅读理解(共1题,70.0分)三.填…

xxl-job核心源码解析

xxl-job源码解析 如何自研一个xxljob 注册服务调度服务RPC组件(基建,底层严重依赖)日志服务告警服务 系统架构 执行流程 各大调度中心对比 1)服务端启动流程 首先找到配置类 XxlJobAdminConfig 可以发现该类实现 InitializingBean接口,…

openpose保姆级教程代码详细解析——训练部分

一:前言 OpenPose是一个基于深度学习的人体姿势估计库,它可以从图像或视频中准确地检测和估计人体的关键点和姿势信息。OpenPose的目标是将人体姿势估计变成一个实时、多人、准确的任务。它的原理部分已经在上一篇非常详细的讲解了——本节介绍训…

Dynamic .NET TWAIN 8.3.3 for NetCore Crack

用于 WinForms 和 WPF 应用程序的扫描仪和网络摄像头捕获 SDK 适用于 .NET 应用程序的简单高效的扫描和网络摄像头 SDK Dynamsoft 的 Dynamic .NET TWAIN 是一个基于 TWAIN 和 DirectShow 标准的 .NET 文档成像 SDK。它为扫描仪和网络摄像头软件开发提供了丰富、高效且…

修改依赖包下的子依赖版本,前端项目安全扫描出来的漏洞——解决过程

为什么要升级,如图云桌面(相当于堡垒机-远程桌面)的项目审查是大概基于node16版本进行扫描的,本来我方是通过降版本从14到12绕过大范围更新,但现在躲得过初一躲不过十五,如何更新 package-lock.json 中的一…

DAY24:二叉树(十四)二叉搜索树中的插入操作+删除二叉搜索树中的节点(二叉树结构修改难点)

文章目录 701.二叉搜索树中的插入操作思路递归法如何保证连接的节点就是空节点的父节点? 迭代法迭代法注意debug测试 450.删除二叉搜索树中的节点(坑较多,注意复盘)思路最开始的写法debug测试1.使用了释放后的空间ERROR: AddressS…

通知!2023年湖北住建厅七大员新考和继续教育要求有变化了?启程别

通知!2023年湖北住建厅七大员新考和继续教育要求有变化了?启程别 湖北住建厅七大员新考以及继续教育的相关要求都即将有一些变化了目前在征集意见的阶段,具体实施等后续具体通知 对于新考的变化主要是: 1.由原先报名之后只需要完成…

Vue中如何进行颜色选择与调色板

Vue中如何进行颜色选择与调色板 颜色选择和调色板是Web开发中常用的功能,它们可以帮助用户选择或调整颜色。Vue作为一个流行的JavaScript框架,提供了一些工具和库,可以方便地实现颜色选择和调色板功能。本文将介绍如何在Vue中进行颜色选择和…

【aspose-words】Aspose.Words for Java模板语法详细剖析

文章目录 前言🍊缘由aspose-words模板语法再了解 🎯主要目标实现3大重点 🎁快速链接🍈猜你想问如何与狗哥联系进行探讨1.关注公众号【JavaDog程序狗】2.踩踩狗哥博客 🍯猜你喜欢文章推荐 正文🍋aspose-word…

mfc140.dll丢失的解决方法,解析mfc140.dll这个文件

其实大部分人在使用计算机过程中,您可能会遇到mfc140.dll丢失的错误提示。这个错误会导致一些应用程序无法正常运行,那么要如何解决这个问题呢?今天小编就来给大家详细的解析mfc140.dll这个文件以及教大家 mfc140.dll丢失的解决方法。 目录 …

【算法与数据结构】349、LeetCode两个数组的交集

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:使用了一个哈希数组记录nums1出现的数字,然后遍历nums2,找到hash数组为1的值就…

Vue-Element-Admin项目学习笔记(6)Vuex状态管理

前情回顾: vue-element-admin项目学习笔记(1)安装、配置、启动项目 vue-element-admin项目学习笔记(2)main.js 文件分析 vue-element-admin项目学习笔记(3)路由分析一:静态路由 vue-element-adm…

yoloV5目标识别以及跟踪,功能识别动物(大象,犀牛,水牛,斑马)

yolo目标识别以及跟踪还是很强的嘞! 一. YOLO V5我来啦 1. 前期准备 yolo V5项目下载 项目的github地址项目的gitee地址 使用git 克隆下来到项目目录下面就好 环境配置 在yolov5的文件下面有一个 requirements.txt文件,这里就是环境依赖的说明。 这里我以 vs…

DP学习之解码方法

DP学习第二篇之解码方法 91. 解码方法 - 力扣(LeetCode) 一. 题目解析 二. 题解 算法原理及代码 状态表示 tips: 经验题目要求。以i位置为结尾,。。。 dp[i]: 以i位置为结尾时,解码方法的总数 状态转移方程 tips: 用之前或…

5.3.2 因特网的路由协议(二)基于距离向量算法的RIP协议

5.3.2 因特网的路由协议(二)基于距离向量算法的RIP协议 一、RIP协议概念 RIP是Routing Information Protocol缩写,又称为路由信息协议,是最先得到应用的内部网关协议,RIP作为一个常在小型互联网中使用的路由信息协议…

【mmcls】mmdet中使用mmcls的网络及预训练模型

mmcls现在叫mmpretrain,以前叫mmclassification,这里为了统一称为mmcls。在基于MM框架的下游任务,例如检测(mmdetection)中可以使用mmcls中的backbone进行特征提取,但这就需要知道网络的参数以及输出特征的维度。本文简单介绍了在…