三维重建基础

软件

COLMAP的下载和使用
Ubuntu20.04安装colmap从零开始全过程记录(包括CUDA/CUDNN/ceres/anaconda)

colmap

COLMAP是一个开源的三维重建工具,用于从多视图图像生成3D模型。它主要包括两个阶段:稀疏重建(Sparse Reconstruction)密集重建(Dense Reconstruction)。下面是这两个重建过程的具体解释:

1. 稀疏重建(Sparse Reconstruction)

  • 目标:从输入的图像集合中估计出相机的姿态(位置和方向)以及三维点云。
  • 过程
    • 特征提取(Feature Extraction):对输入图像进行特征点检测(通常是SIFT特征),提取图像中的关键点。
    • 特征匹配(Feature Matching):在多张图像之间进行特征匹配,找到相同场景中不同视角下的对应点。
    • 结构从运动(Structure-from-Motion, SfM):根据匹配的特征点估计相机的内外参,同时重建出稀疏的三维点云。
  • 输出:经过稀疏重建,可以得到初步的相机参数和场景的稀疏3D点云。
  • 特点:稀疏重建得到的点云较为稀疏,仅由图像中的关键特征点组成,计算效率高,但重建的细节较少。

使用 Sparse 重建获取相机信息
在sparse/0文件夹下

1. cameras.bin 或 cameras.txt

  • 包含重建过程中计算得到的相机内参(焦距、主点坐标、畸变系数等)。
  • .bin 文件是二进制格式,而 .txt 文件是文本格式,具体格式取决于你在COLMAP中选择的输出选项。

2. images.bin 或 images.txt

  • 存储每张输入图像的外参(即相机的位姿),包括相机的旋转矩阵和平移向量。
  • 同样,有二进制(.bin)和文本(.txt)两种格式。

3. points3D.bin 或 points3D.txt

  • 包含稀疏点云的三维点坐标及其附加信息,例如RGB颜色、可见度(被多少个图像观测到)等。
  • 这是稀疏重建的主要结果,展示了场景中被重建的稀疏3D点云。

文件夹内容概述

  • 这些文件的组合描述了COLMAP重建出的场景的相机位姿、相机参数和三维点云。
  • 如果需要进一步进行密集重建(Dense Reconstruction),这些文件将作为输入数据被使用。

总结

sparse/0 文件夹包含的是稀疏重建的结果,包括相机参数、图像位姿和稀疏的三维点云。这些结果是从输入图像通过COLMAP的SfM(Structure-from-Motion)算法推导而来的。

安装colmap

git clone https://github.com/colmap/colmap.git

cd colmap
mkdir build
cd build

apt update && apt install -y
libeigen3-dev
libflann-dev
libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev
libceres-dev
qt5-default qtbase5-dev
libcgal-dev
libqt5opengl5-dev
libmetis-dev
libfreeimage-dev
libglew-dev

cmake ..
make -j
make install

安装成功,检查colmap:
colmap -h

查询colmap.exe路径:
which colmap

显示:
/usr/local/bin/colmap

cd ../
cd ../
cd NeRO
python run_colmap.py --project_dir data/custom/turtle_self_rotation_50 --colmap /usr/local/bin/colmap --same_camera

注意必须放在data/custom/这个文件夹下面

E:\miniconda3\envs\cv\python.exe "D:\specular_test\colmap_preprocess\sparse_npz.py" --root_dir "C:\Users\ZJL\Desktop\demo" --radius 3 --match_type exhaustive_matcher

python sparse_npz.py --root_dir ./demo --radius 3

2. 密集重建(Dense Reconstruction)

  • 目标:在稀疏重建的基础上,生成高密度的三维点云或表面模型,提升模型的细节和精度。
  • 过程
    • 深度估计(Depth Estimation):通过对每个图像进行深度图估计,生成较为密集的深度信息。
    • 深度融合(Depth Fusion):将多视图的深度图融合,生成密集的三维点云或网格。
  • 输出:高密度的三维点云、表面网格或多视图的深度图。
  • 特点:密集重建得到的点云密度较高,可以捕捉场景中的更多细节。相对于稀疏重建,计算量更大,需要更多的内存和计算时间。

总结

  • 稀疏重建:用于估计相机位置和初步三维点云,快速且适合初步结果验证。
  • 密集重建:在稀疏重建的基础上生成细节丰富的三维模型,适合后续的3D重建和可视化。

一般来说,COLMAP的工作流程是先进行稀疏重建,再进行密集重建。

metashape

metashape导出相机位姿流程

选择偏好设置,改为中文
工作流程→添加照片→对齐照片(默认的即可,若对齐错误选择中精度)
工具→优化相机→只勾选拟合f、拟合cx、cy→优化
点击文件→导出→导出相机(选择Colmap格式,勾选连接点和二进制编码)
导出的文件:文件夹结构txt、images、sparse

相机模型

相机模型、参数和各个坐标系(世界坐标系、相机坐标系、归一化坐标系、图像坐标系、像素坐标系之间变换)
相机的小孔成像模型及鱼眼畸变模型
通俗易懂:带你探索相机成像模型的奥秘!【重制版】

光线

相机中的一个像素点和真实世界中点的连线

mesh

在三维建模和计算机图形学中,"mesh"(网格)是指用于表示三维对象几何形状的数字框架。这个框架由顶点(vertices)、边(edges)和面(faces)组成,通常用于构建曲面和体积。
顶点(Vertices)是网格的基本构建块,它们定义了三维空间中的点。边(Edges)是连接两个顶点的直线,而面(Faces)则是由至少三个边组成的闭合图形,它们可以是三角形、四边形或其他多边形。在许多情况下,特别是实时渲染和游戏开发中,三角形是最常用的面类型,因为它们易于处理且不会产生渲染错误。
网格可以是以下几种类型:

  1. 三角形网格(Triangle Mesh):由三角形面组成,是最常见的网格类型,因为它们易于处理且能够适应复杂的形状。
  2. 四边形网格(Quadrilateral Mesh):由四边形面组成,常用于需要平滑表面的建模。
  3. 多边形网格(Polygon Mesh):由多边形面组成,多边形的边数可以大于四,但过多的边可能会增加计算的复杂性。
    网格的质量和密度对于三维模型的视觉质量和性能有着直接的影响。高密度的网格(更多的顶点、边和面)可以更精确地表示对象的细节,但同时也需要更多的计算资源来处理。因此,在创建网格时,艺术家和工程师需要在细节、平滑度和性能之间找到平衡。

SDF

代码参考NeRO中field.py文件
输入三维点坐标(x,y,z)
输出该点的SDF值和梯度(gradient)
一个点的SDF的gradient表示该点的normal

三维空间中的点 xx 是通过在相机射线 o+tvo + t \cdot v 上进行采样得到的,其中 oo 是相机中心,vv 是射线方向,tt 是从相机中心到点的距离。通过对射线进行多个采样,可以获得一系列点 pjp_j,这些点用于计算 SDF 值。

monocular depth estimation
Monocular depth estimation是一种计算机视觉技术,它旨在从单个图像中恢复场景的深度信息。在现实世界中,我们通过两只眼睛的视差来感知深度,这是因为我们的两只眼睛从略微不同的角度观察同一个场景,从而产生了深度感知。然而,计算机和大多数相机只有一个“眼睛”(即一个镜头),因此它们无法直接获得这种视差信息。
Monocular depth estimation的目标是利用图像中的线索来推断深度信息,这些线索可能包括物体的大小、遮挡、光照、纹理变化等。这种技术对于增强现实、机器人导航、三维重建等领域非常重要,因为在这些应用中,获取深度信息可以帮助更好地理解和解释场景。
Monocular depth estimation通常依赖于深度学习模型,特别是卷积神经网络(CNNs),这些模型可以从大量的成对图像和深度图中学习,其中成对图像包含相同的场景但视角略有不同,深度图则提供了每个像素的深度信息。通过训练,模型可以学习如何从单个图像中预测深度信息。
尽管monocular depth estimation是一个病态问题(因为多个不同的深度场景可以产生相同的二维图像),但现代深度学习模型已经能够以相当高的准确性估计深度,尤其是在合成数据集或特定场景类型上训练时。然而,这些模型通常在处理极端遮挡、缺乏纹理或非朗伯反射表面的场景时仍然面临挑战。

normal

normal通过SDF求梯度得到

获得 normal 的方式:使用 SDM 生成
https://github.com/satoshi-ikehata/SDM-UniPS-CVPR2023

使用supernormal生成

mask

对特定区域遮盖,使得关注有用区域
自动扣mask:segment-anything,但是对于镜面反射的物体效果很差
pip install segment-anything 来使用

labelme需手动选择区域,mask不是很准确

手动用 photoshop 扣 mask
用对象选择工具选择物体,它会自动吸附在物体表面
选择→选择并遮住,修改边界,点击确定
单击图层面板底部的 “添加图层蒙版” 按钮,创建蒙版
图层 > 新建填充图层 > 纯色;直接点确定,选择背景为黑色
在图层区域,将纯色移到图片下层
按住ctrl,点击蒙版缩略图,选中物体
图层 > 新建填充图层 > 纯色;直接点确定,选择物体为白色
得到的结果导出即可

赞赏