关于colmap+nerf对数据集进行预处理的使用总结

前言

零零碎碎的东西太多,有必要统一记录一下,因为是回忆步骤,所以可能有不准确的地方

Colmap的使用

1. 下载

下载链接:colmap,下载之后直接解压就能使用,点击COLMAP.bat
在这里插入图片描述

2. colmap

这里到处都是很详细的操作步骤,可以自行搜索,顺序是:
File→New project:选择一个路径存放数据库,生成database.db
Processing→Feature extraction:提取图像特征。提取特征后,可以选择要不要修改相机内参,如果你的相机内参已知,可以使用如下链接修改相机内参,此处记录方法名为blender_camera2colmap.py,修改之后选择Processing→Database management→camera看到内参修改成功。
在这里插入图片描述

Processing→Feature matching:匹配图像特征
Reconstraction→Start reconstruction(这里不要选Auto):稀疏重建
重建后 File→Export model得到文件,参考链接,此处我与他的命名方式保持一致,获得的目录如下:

+── E:\test\scene78-3+── images			#用于重建的图像
│   +── sparse
	|	+── 0
		|	+── cameras.bin
		|	+── images.bin
		|	+── points3Ds.bin
		|	+── project.ini
│   +── dataset.db

此处用于nerf预处理的colmap已经结束,但是如果想用于稠密重建或者其他问题的还需额外的步骤,以下放出我的一些应用:

应用1 稠密重建

经历完上述步骤后:
Reconstraction→Dense reconstruction

  1. 选择路径
  2. 去畸变
    在这里插入图片描述
  3. 立体匹配
  4. 融合,融合后可以获得fused.ply,应该是点云可视化文件
  5. Poisson后获得mesh文件meshed-poisson.ply
  6. 最后一个Delaunay应该是几何模型?反正不太好看meshed-delaunay.ply

在这里插入图片描述
在这里插入图片描述

从左到右依次是fusion, poission, delaunay
在这里插入图片描述在这里插入图片描述在这里插入图片描述
此处再列一下最终获得的目录,可能不完全准确,但大概是这样

+── images # 对应重建图片数据集
│   +── image1.jpg
│   +── image2.jpg
│   +── ...
+── sparse # 稀疏重建结果
│   +── 0
│   │   +── cameras.bin
│   │   +── images.bin
│   │   +── points3D.bin
│   │   +── 对应的.txt  #如果保存了的话
│   +── ...
+── dense # 稠密重建结果
│   +── 0
│   │   +── images # 去畸变图像
│   │   +── sparse
│   │   +── stereo
│   │   +── fused.ply # 稠密点云
│   │   +── meshed-poisson.ply
│   │   +── meshed-delaunay.ply
│   +── ...
+── database.db # 图像提取的特征相关信息
+── project.ini # 项目信息文件

应用2:获得外参文件和深度图

外参文件: File→txt,这时就可以获取一些参数文件,这一步在稠密重建前就可以用
使用的时候要注意两点:这里的外参是w2c,坐标轴的转换

cameras.txt 内参
images.txt 外参(轨迹数据)
Points3D.txt

每幅图像对应的外参有两行,但是我只需要用到第一行的七元组,所以使用如下代码提取外参,文件名storetxt2othertxt.py

# 从一个.txt文件读取并保存到另一个.txt文件中
import os
import numpy as np

path1 = 'E:/test/dense_pc/images.txt'
path2 = 'E:/test/dense_pc/output_file.txt'

# 读取相机外参文件
with open(path1, 'r') as f_in, open(path2, 'w') as f_out:
    for num,line in enumerate(f_in):
        if num<4:
            f_out.write(line)
        else:
            if num%2!=0:
                continue
            else:
                f_out.write(line)

深度图: 在稠密重建后(stereo)获得深度图,这时在stereo文件夹下有两种深度图(我也不知道哪种好),任选一种放在目标文件夹F:/code1/nice-slam-master/Datasets/dist3.6-2/depth_colmap下的代码。

import shutil
import os
import re
from ntpath import join


def sorted_alphanum(file_list_ordered):
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
    return sorted(file_list_ordered, key=alphanum_key)

def get_file_list(path, extension=None,a=None):
    if extension is None:
        file_list = [path + f for f in os.listdir(path) if os.path.isfile(join(path, f))]
    else:
        file_list = [
            path + f
            for f in os.listdir(path)
            if os.path.isfile(os.path.join(path, f)) and os.path.splitext(f)[1] == extension and a in os.path.splitext(f)[0]
        ]

    file_list = sorted_alphanum(file_list)
    return file_list


depth_image_path = get_file_list(os.path.join('E:/test/dense_pc_78/stereo/depth_maps/'),
                                     extension=".bin",a='geometric')  # geometric  photometric

print(depth_image_path)

for i in range(len(depth_image_path)):
    c = '%s'%(depth_image_path[i][38:])

    shutil.copyfile(depth_image_path[i],
                    'F:/code1/nice-slam-master/Datasets/dist3.6-2/depth_colmap/%s'%c)

应用3:验证colmap的外参到底是什么,有多准确

很庆幸无意间发现colmap生成的外参是w2c,此处本来也想用来验证自己的深度图有多大误差,使用show_cube_with_extrinsic.py文件选择几张位姿差距较大的图像,重建场景,用到open3d包

使用LLFF处理为NeRF能用的格式

依旧参考链接 下载LLFF代码并配置环境,这里不要听他的使用python3.8,因为没有tensorflow1.*版本,我使用的python3.6。接着把你刚刚生成的文件copy到llff文件夹下(图方便),激活环境后就运行如下命令,其中cube就是scene78-3,下面包含了images和sparse等。

python imgs2poses.py cube

获得如下结果:
在这里插入图片描述
于是就能在该路径下看到:poses_bounds.npy文件,把它移动到nerf目录下并修改nerf配置文件,还是参考那个链接。

在这里插入图片描述
最后放一个colmap文档网址

更新:poses_bounds.npy读取和处理流程

更新:metashape获得位姿

因为要用metashape代替colmap估计位姿(究竟是谁想出来的馊主意,哦是我敬爱的老师,那没事了),所以就要清楚两者之间怎么转换。先放两个找到的链接:metashape导入3DGaussianmetashape导入instantNGP,是我暂时找到所有metashape与NeRF相关的资料了,此外作者还讲了:当位姿超出了NeRF原本的boundingbox该怎么办?
在这里插入图片描述
这里对应到nerf-pytorch当中就是设置sc的大小。据我的观察,物体级的重建设成1,场景级的重建设成0.1。
metashape点击工作流程->对齐照片,把照片直接拖到下面,最后点文件导出,此时导出的是.xml文件,然后使用gIthub链接下载代码,这里我存在/media/yangtongyu/T9/code1/nerf-pytorch目录下,agi2nerf.py文件,生成transform.json位姿。
在这里插入图片描述

由于位姿instant-ngp格式,直接设置nerf参数文件里的数据集类型为’blender’,然后调整sc值。

poses[:,:3,3] *= sc     # 平移变换

除了缩放之外其他好像没什么改的必要。
总结一下,步骤就是:

  1. 在获得metashape相机位姿后用agi2nerf.py获得transforms.json
  2. 修改nerf参数文件和sc参数

在此之前又去看了一下由COLMAP转为llff的过程:主要是pose和点云的读取
3. w2c转为c2w
4. 坐标系的转换

# must switch to [-u, r, -t] from [r, -u, t], NOT [r, u, -t]
poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1)

关于nerf读取的到底是个什么文件有必要详细说明一下,以下是load_data()函数中的内容。
首先,从.npy中读出两个array,

poses_arr = np.load(os.path.join(basedir, 'poses_bounds.npy'))
# pose 中的15维=12维+3维 12是相机位姿,3是图像长宽及f
poses = poses_arr[:, :-2].reshape([-1, 3, 5]).transpose([1,2,0])	# [3,15,n]
bds = poses_arr[:, -2:].transpose([1,0])	# [2,n]

此处的长宽用真实图像的长宽代替,如果图像需要resize则对f也进行相应变化

poses[:2, 4, :] = np.array(sh[:2]).reshape([2, 1])
poses[2, 4, :] = poses[2, 4, :] * 1./factor     # fx/fy

再次记录,metashape的相机坐标系有可能是w2c和COLMAP一样。

  • 32
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值