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

2023-11-12

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,避免访问不存在的像素。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map 的相关文章

  • Java/LWJGL:OpenGL 中的 Z 轴表现得像左手坐标系

    最近 我寻求帮助 https stackoverflow com q 18836484 1530508关于 OpenGL 中的 3D 相机旋转 这个答案 https stackoverflow com a 18836618 1530508接
  • 在python opengl中使用图像中的2d点获取空间中的3d点

    我正在尝试模拟房间中的深度相机 我的相机能够在世界中移动和旋转 并且房间被模拟为围绕 0 0 0 的 3d 立方体 单击按钮时 我想对图像中的 N 个随机点进行采样 并获取这些点与相机的距离 现实世界 中的距离 到目前为止 我已经成功创建了
  • 准确测量一组基准点之间的相对距离(增强现实应用)

    假设我有一组 5 个标记 我正在尝试使用增强现实框架找到每个标记之间的相对距离 例如AR工具包 http www hitl washington edu artoolkit 在我的相机中 前 20 帧仅向我显示前 2 个标记 以便我可以计算
  • 使用 Scenform 将 SceneView 加载到片段中后出现黑屏

    我正在开发一个项目 该项目将在一个片段中包含 3D 模型查看器 为了做到这一点 我决定使用 sceneform 在尝试在我的选项卡片段中显示 SceneView 后 我遇到了 SceneView 的问题 一切都是根据示例和 scenefor
  • Python openAL 3D 声音

    我刚刚开始使用 python 正在制作音频操作程序 我正在尝试在我的 python 应用程序中使用 openAL 实现 3D 声音 但我只能让它工作 这是我的 3D 声音代码 from openal loaders import load
  • 给定一个 4x4 齐次矩阵,我如何获得 3D 世界坐标?

    所以我有一个正在旋转然后再次平移和旋转的对象 我将这些翻译的矩阵存储为对象成员 现在 当我进行对象拾取时 我需要知道该对象的 3D 世界坐标 目前我已经能够像这样获得物体的位置 coords 0 finalMatrix 12 坐标 1 最终
  • 使用 glFrustum 进行离轴投影

    我正在尝试使用 OpenGL 对场景进行离轴投影 并且我阅读了该文档罗伯特 库伊马的离轴投影 http csc lsu edu kooima pdfs gen perspective pdf现在对实际需要做什么有了更好的了解 但仍然有一些部
  • SceneKit 修改 3D 对象并导出文件

    在我的应用程序中 我使用 SceneKit Framework 在 SCNView 中显示 3D 对象 并导出修改后的文件 并进行一些小的更改 如颜色 温度等 但在将其导出到文档文件夹后 我得到了原始文件 在这里我可以显示 3D 对象并对其
  • 在 Unity 3D 中使用触摸输入在地形上移动相机

    我是 Unity 新手 我正在尝试弄清楚如何使用触摸输入在地图 地形上移动相机 摄像机将以 90 0 0 的旋转角度俯视地形 地形位于第 8 层 我用键盘移动它没有问题 现在我尝试移动到触摸 如果你想在 iOS 上保持预期的使用情况 那就非
  • 给定 3D 空间中的一条线,如何找到从它到一点的角度?

    我在 3D 空间中有两组点 我想画一条穿过两组点的中心的线 然后找到从该线到每个点的角度 从那里开始 我将根据两个角度的接近程度来确定两组中的匹配点 我知道如何找到每组点的中心 只需将它们平均在一起 并且我知道如何将它们匹配 甚至考虑到它们
  • 如何使用更少的包绘制二元正态分布的表面和轮廓

    我将绘制二元正态分布的 3D 曲面及其轮廓 可以是任何二元正态分布 我想用persp and contour在我的画中 我在网上搜索了一下 但发现了很多方法 大多数人都使用过一些软件包 但我想以使用更少的软件包甚至不安装任何软件包的方式来执
  • 对一系列点重新采样

    我有一个 3d 点数组 想象一下球的轨迹 有 X 个样本 现在 我想对这些点重新采样 以便我有一个新数组 其中包含 y 个样本的位置 y 可以大于或小于 x 但不能小于 1 始终至少有 1 个样本 将原始数组重新采样为新数组的算法会是什么样
  • 如何在 Three.js 中从三角面获取多边形?

    我在网上查了一下是否有人遇到同样的问题 我正在使用 Three js 我有一个 3DObject 其中可能包含孔 面是三角形的 假设我想从上面看到它 我的目标是获得一个代表顶面周长的多边形 这对我来说意味着不再有三角面 而只有 1 个多边形
  • WPF 3D 旋转球体 GUI

    我一直在尝试在 WPF 中为我的课堂作业制作 3D 用户界面 但遇到了一个问题 现在 2 3 天都无法解决 我尝试用谷歌搜索答案 我查看了一些 stackoverflow 帖子 但还没有一个可以帮助我解决问题 情况是这样的 我有一个 3D
  • 如何在plotly 3D曲面图中标记区域?

    我使用plotly从xyz数据创建3D高程剖面图 它与以下代码配合得很好 import plotly graph objects as go import pandas as pd import numpy as np Read data
  • 如何将 3D 图像输出到 3D 电视?

    我有一台 3D 电视 如果我不至少尝试让它显示我自己创作的漂亮 3D 图像 我就会逃避我的责任 作为一个极客 我之前已经完成了非常基本的 OpenGL 编程 因此我了解所涉及的概念 假设我可以为自己渲染一个简单的四面体或立方体并使其旋转一点
  • 光线追踪三角形

    我正在用java编写一个光线追踪器 并且我能够追踪球体 但我相信我追踪三角形的方式有问题 据我了解 这是基本算法 首先确定射线是否与plane三角形已打开 剪裁所有点 使它们与三角形位于同一平面上 因此xy以平面为例 根据沿着新平面向任意方
  • 颜色重新映射 - 使用 3D 网格匹配目标调色板?

    假设我有颜色 FOO 它以 RGB 格式存储 我需要重新着色 FOO 以便它与颜色列表中最接近的颜色匹配 即时执行此操作 我是否无法将每种颜色的 RGB 值视为 3D 网格上的点 r x g y b z 并计算点 FOO 与每个颜色点之间的
  • 使用 Scipy/Numpy 在浊点的二维插值中仅获取“有效”点

    我有一个通过人的背部摄影测量获得的浊点 我正在尝试对其进行插值以获得规则网格 为此我正在使用scipy interpolate到目前为止取得了良好的成果 问题是 我正在使用的函数 scipy interpolate griddata 使用平
  • 更改 3D 图形颜色 (matplotlib)

    我使用以下代码在 matplotlib 中绘制了 3D 图形 Previously defines lists of data to plot fig plt figure ax fig add subplot 111 projection

随机推荐