Colmap三维重建详解与使用方法

图片捕获过程,请遵循以下指导方针以获得最佳重建结果:

1 捕捉具有良好纹理的图像。避免使用完全没有质感的图片(例如,白色的墙或空桌子)。如果场景本身没有足够的纹理,你可以放置额外的背景对象,如海报等。

2 在相似的照明条件下捕获图像。避免高动态范围的场景(例如,背对太阳有阴影的照片或透过门/窗拍摄的照片)。避免在有光泽的表面上拍摄。

3 捕捉高视觉重叠的图像。确保每个物体至少在3张图片中看到,重叠图片越多越好。

4 围绕同一个物体进行不同的角度捕捉图像,不要只旋转相机从同一位置拍摄图像。同时,尽量从一个相对相似的角度拍摄足够多的图片。注意,更多的图像不一定更好,可能会导致缓慢的重建过程。如果你使用视频作为输入,考虑下采样帧率。

概述

基于图像的三维重建传统上首先使用运动结构(Structure-from-Motion)恢复场景的稀疏表示和输入图像的姿态。这个输出然后作为多视图立体几何(Multi-View Stereo的输入,以恢复场景的密集表示。

SFM是通过一系列有重叠的且不同视角的图片重建出物体的三维结构(稀疏点云),并且输出相机的内外参数,内参指的是将真实空间的三维点通过内参矩阵转换为相机图片上的二维点,外参包含相机在切换不同视角时的平移和旋转信息。

通常情况下,运动结构系统将这一过程分为三个阶段:

1 特征检测与提取

2 特征匹配和几何验证

3 结构与运动重建

多视图立体几何(MVS)采用SfM的输出来计算图像中每个像素的深度和法向信息。在3D点云中融合多幅图像的深度图和法向图,然后生成场景的密集点云。利用融合点云的深度和法向信息,泊松曲面(Poisson),三角剖分(delaunay)重建等算法可以恢复场景的三维曲面几何。

实施:

COLMAP创建一个新项目必须包含存储数据库的位置以及包含输入图像的文件夹。可以将整个项目设置保存到配置文件中,项目配置文件中保存存储数据库和图像文件夹的绝对路径信息。整个项目的目录结构如下:

第一步:特征检测/提取

特征检测/提取在图像中找到稀疏的特征点,并使用数值描述符(128维向量)描述特征点。主要使用SIFT特征提取方法。

jpge图像的头部保存了EXIF信息 里面包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及GPS全球定位系统数据、缩略图等,COLMAP可以从嵌入式EXIF信息中自动提取焦距信息。

提取到的特征信息如下:

NUM_FEATURES代表一张图像提取到多少个特征点,x,y代表特征点的坐标, scale代表尺度(即相机距离物体远近的比例),ORIENTATION代表特征点的梯度方向, D_1…D_128代表特征描述符的128维向量,所有提取的数据都将存储在数据库文件中。

其中X, Y, SCALE, ORIENTATION为浮点数,D_1…D_128为0…255范围内的值。

例如,一张图片有4个特征:

第二步:特征匹配和几何验证。

特征匹配首先匹配图像对,下面列出图像匹配的几种策略。其次再将匹配后的图像上的特征点进行匹配,利用特征点的128维描述符向量的相似性度量进行特征点匹配。

图像对匹配算法:

穷尽匹配(Exhaustive Matching):如果数据集中的图像数量相对较低(最多数百个),那么这种匹配模式应该足够快,并能获得最佳的重构结果。在这里,每个图像都与其他图像进行匹配,而块大小决定同时从磁盘加载到内存中的图像数量。

序列匹配(Sequential Matching):由一个摄像机。在这种情况下,连续的帧具有视觉重叠,不需要用尽全力地匹配所有的图像对。而是将连续捕获的图像相互匹配。

空间匹配(Spatial Matching):这种匹配模式将每个图像与它的空间近邻进行匹配。COLMAP还会从EXIF中提取GPS信息,并使用它进行空间最近邻居搜索。

传递性匹配(Transitive Matching):这种匹配模式利用已有特征匹配的传递关系,生成更完整的匹配图。如果一个图像A匹配到一个图像B,而B匹配到C,那么这个匹配器会尝试直接将A匹配到C。

建立图像对之后,在参考图像中的一个特征点,如何从目标图像中的所有特征点中找出与之相对应的特征点。如果使用暴力计算法,计算每一对特征点的相似距离,如果特征的描述符向量的维度和特征点的数量较多的话,暴力法是不可取的。需要使用KD树算法建立一个搜索树,基于KD树最邻近查找算法,方便特征点进行快速匹配。

由于sift提取的特征点和描述子在匹配过程中可能会存在误匹配的情况,所以需要将错误的匹配点对剔除。几何校验是筛除一些误匹配的特征点。几何校验是指利用对极几何进行约束

对极几何:空间中的一点与两张图片相机的光心,三者围成一个极平面,极平面与两张图片相交形成两条极线,对极几何约束是指,空间点X在摄像机1的成像平面中的像素点x,与之相匹配的摄像机2的成像平面中的像素点 x' 一定落在极线上。

公式约束为: x'的转置 × F × x =0 ;F为基础矩阵,F可以通过8对匹配的特征点联立方程组求得 分解F矩阵可以求得相机的内参矩阵。 

几何约束方法:随机选取图像对的8对匹配点,使用归一化八点算法求解基础矩阵F,然后统计满足对极几何关系的点对数量,在设定的次数内重复上述步骤,选取满足条件的点对数量最多的匹配为精化匹配结果。

第三步:稀疏重构

首先初始化主要是指选取两张匹配的图像,设定其中一张图像的位姿为单位阵,然后通过它们之间的匹配点对估计出E矩阵,将E矩阵分解获得另一张图像的位姿。在估计出两张图像的位姿后,就可以通过三角化(triangulation)来生成三维点。

然后进行增量式重建:

1 获取下一最佳匹配图像(匹配点对数量最多)

2 利用匹配的特征点估计出E矩阵(本质矩阵),估计图像位姿

3 进行三角化生成三维空间点,三角化是利用两个匹配的图像坐标图像位姿以及相机的内参矩阵,求得匹配点的三维点坐标。

4 对所有已生成的三维点和已估计出的位姿,使用ceres库进行ba(bundle adjustment)优化。通过最小化重投影误差实现剔除误差过大的点

5 最后对所有数据进行ba优化 即全局优化

第四步:稠密重建

在重建场景的稀疏表示和输入图像的相机姿势后,MVS现在可以恢复更密集的场景几何。COLMAP有一个集成的密集重建管道,可以为所有的配准图像生成深度和法向图,将深度和法向图融合到一个将稀疏点云融合成密集点云,最后使用泊松(Poisson)或三角剖分(Delaunay)重建方法从融合的点云中估计出一个密集曲面。

稠密重建分为:

1 是还原图像,去除图像的畸变

2 是计算深度图和法向图

3 将深度和法向图融合成到点云里

4 点云网格划分形成曲面

colmap命令行执行过程

初始数据为图像文件和数据库文件

图像文件包含128张jpg图像

1 特征提取 利用特征提取算法提取每一张图片的特征点并获得特征点的描述符

2 穷尽匹配 匹配每一张图片与其他所有图片的特征点,并进行几何校验。

3 稀疏重建

首先使用两张图片,将第一张图片的位姿记为单位阵,通过匹配的特征点利用本质矩阵求得另一张图像位姿,通过估计基础矩阵得到相机的内参矩阵,利用两个匹配的图像坐标和图像位姿以及相机的内参矩阵,进行三角化生成三维空间点。接着使用ba(bundle adjustment)优化生成的三维点,通过最小化重投影误差实现剔除误差过大的点。然后每增加一张图片,重复进行估计图像位姿、三角化、ba优化、全局ba优化等步骤。直至添加完所有图片

稀疏重建效果

4 稠密重建

(1) 图像去畸变,还原未失真的图片

(2)计算深度和法向图

立体匹配后生成的深度图

立体匹配后生成的法向图

(3)在稀疏点云中融合多幅图像的深度图和法向图,然后生成场景的密集点云。

稠密点云效果如下:

(4)使用三角剖分算法进行曲面重建,重建效果如下:

参考网址:

https://www.ctyun.cn/developer/article/416012493463621

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 快速搭建 Gitlab 服务

linux环境: 使用 vim 编辑 hosts 文件: vim /etc/hosts按 I 进入编辑模式,在文件末行追加上虚拟机的 IP 和要设置的域名: 192.168.1.17 gitlab.kunwu.toplwindows环境: Windows 系统的 hosts 文件位于 C:\Windows\S…

如何做一个简单的深度集成学习框架

使用同一个框架,独立在一个数据集上面,分别训练多次,每个单独模型训练超参数可以一样,也可以不一样,最后若干个训练好的独立模型在测试集数据上面做最后集中决策。 实例代码如下: class MyEnsemble(nn.Modu…

linux通过串口传输文件

简介 在嵌入式调试过程中,我们经常会使用调试串口来查看Log或者执行指令,其实,调试串口还有另一种功能,就是传输文件,本文说明使用MobaXterm串口工具来传输文件。 环境要求 嵌入式系统需要安装lsz和lrz,…

【Java】定时器的简单应用

在写代码的过程中,如果我们遇到了隔一段时间就要进行一项任务时,采用定时器会提高我们的效率。下面对定时器的使用进行简单说明 1、应用说明 首先我们要创建一个Timer类 Timer timer new Timer(); 然后在timer中调用schedule()方法添加任务 timer.…

将对象转成URL参数

背景 有的时候前端跳转到其他平台的页面需要携带额外的参数,需要将对象转成用 & 连接的字符串拼接在路径后面。 实现方法

Rust语言入门教程(二) - 变量与作用域

变量与作用域 变量的声明与初始化 Rust的基本语法格式如下: fn main(){let bunnies 2; }语句以分号结尾,用花括号包含语句块。 Rust的语法其实借鉴了很多其他的语言,比如C语言和Python, 所以变量定义的格式看起来也跟很多我们…

Elasticsearch:ES|QL 函数及操作符

如果你对 ES|QL 还不是很熟悉的话,请阅读之前的文章 “Elasticsearch:ES|QL 查询语言简介​​​​​​​”。ES|QL 提供了一整套用于处理数据的函数和运算符。 功能分为以下几类: 目录 ES|QL 聚合函数 AVG COUNT COUNT_DISTINCT 计数为近…

自定义字符-摄氏度汉字一

本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步! > 发布人:日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

Unity UGUI的HorizontalLayoutGroup(水平布局)组件

Horizontal Layout Group | Unity UI | 1.0.0 1. 什么是HorizontalLayoutGroup组件? HorizontalLayoutGroup是Unity UGUI中的一种布局组件,用于在水平方向上对子物体进行排列和布局。它可以根据一定的规则自动调整子物体的位置和大小,使它…

Python基础:生成器(Generators)和生成器表达式(Generator Expressions)详解

生成器(Generators)和 生成器表达式(Generator Expressions)是 Python 中用于处理迭代器和序列数据的强大工具。它们允许你按需生成值,而不是一次性生成所有值,从而节省内存和提高性能。 1. 生成器&#x…

实现自动化构建与集成:Jenkins与SVN整合的指南

Jenkins整合SVN 前言(非必须):配置Jenkins的CSRF1、新建任务2、 配置SVN3、配置Maven:进行编译打包4.1、发布到WEB容器(第一种:将项目放在webapps下)4.2、发布到WEB容器(第二种:将项目名称修改为…

文心一言 VS 讯飞星火 VS chatgpt (141)-- 算法导论12.1 1题

一、用go语言,对于关键字集合(1,4,5,10,16,17,21),分别画出高度为 2、3、4、5和6的二又搜索树。 文心一言: 以下是用Go语言为给定的关键字集合(1, 4, 5, 10, 16, 17, 2…