Instant-ngp重建
1、环境配置:
Cmake:3.26.0_rc4
CUDA:11.8
Visual Studio:VS2019
COLMAP
2、代码下载(有可能下载不全,一定要检查)
3、编译:首先打开cmake gui,选择根目录地址并在根目录下创建build文件夹作为输出目录。(路径中不要出现中文!!!我尝试使用CUDA11.3和11.6都会报错,算力太高的错误,最后使用的是11.8,可能是因为显卡是40系列的)之后从Cmake中使用VS2019打开项目,进行build
4、测试:首先对原作者使用的fox图片进行测试,fox的图像文件在data/nerf/fox下,其中images是图片数据,transforms.json是图片对应的位置信息。
这里使用的脚本为:
D:\\DeepLearn\\NeRF\\instant-ngp-master\\build\\testbed.exe --mode nerf --scene D:\\DeepLearn\\NeRF\\instant-ngp-master\\data\\nerf\\fox\\transforms.json
5、使用自己的数据集:
-
创建一个conda环境,安装项目的requirement.txt
-
使用官方的代码可以进行视频剪裁
-
python .\scripts\convert_video.py --input {Video PATH} --output {data\nerf\YOUR_file\images} --show_image 1 --scale 2
这里我使用的是自己写的一个脚本,比较灵活,可选择输出的图片帧数数量:
import cv2
def extract_frames(video_path, output_path, num_frames):
# 打开视频文件
video = cv2.VideoCapture(video_path)
# 获取视频的总帧数
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
# 计算每一帧的步长
step = total_frames // num_frames
# 初始化计数器和帧索引
count = 1
count2 = 20
frame_index = 0
while count < num_frames and frame_index < total_frames:
# 设置帧索引
video.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
# 读取当前帧
ret, frame = video.read()
if ret:
# 保存当前帧为图像文件
image_path = f"{output_path}/image_{count*count2}.jpg"
cv2.imwrite(image_path, frame)
# 增加计数器
count += 1
# 更新帧索引
frame_index += step
else:
break
# 释放视频对象
video.release()
print(f"{count} frames extracted successfully.")
# 调用函数进行视频截取
video_path = "D:\\DeepLearn\\NeRF\\instant-ngp-master\\data\\nerf\\2.mp4" # 视频文件的路径
output_path = "D:\\DeepLearn\\NeRF\\instant-ngp-master\\data\\nerf\\my_workshop\\images" # 图像文件输出的文件夹路径
num_frames = 120 # 指定的图像帧数量
extract_frames(video_path, output_path, num_frames)
得到图片之后,使用Colmap进行重建,分别进行特征提取、匹配、稀疏重建,导出稀疏模型文件。
在自定义数据集文件夹下新建sparse\0文件夹(注意!一定要按照这个命名,否则后边会出错),点击File—export model as text,将重建数据放到sparse\0文件夹中。
最后一步,生成json文件,最终的exe文件运行的就是transform.json文件。使用官网的脚本生成的json文件会造成json内的路径问题。
python ./scripts/colmap2nerf.py --aabb_scale 16 --images ./data/nerf/my_workshop/images --text ./data/nerf/my_workshop/sparse/0 --out ./data/nerf/my_workshop/transforms.json
解决办法一:
这里我自己写脚本来将这个路径进行剪裁:
import json
def trim_json_value(data, key, max_length):
if isinstance(data, dict):
if key in data:
value = data[key]
if isinstance(value, str):
# 对字符串值进行裁剪
trimmed_value = value[max_length:]
data[key] = trimmed_value
print(f"键 '{key}' 的值已裁剪为 '{trimmed_value}'")
else:
print(f"键 '{key}' 的值不是字符串类型,无法进行裁剪")
else:
for sub_data in data.values():
trim_json_value(sub_data, key, max_length)
elif isinstance(data, list):
for sub_data in data:
trim_json_value(sub_data, key, max_length)
def modify_json(file_path, key, max_length):
# 读取JSON文件
with open(file_path, 'r') as json_file:
data = json.load(json_file)
# 修改指定键的值
trim_json_value(data, key, max_length)
# 将修改后的数据写回JSON文件
with open(file_path, 'w') as json_file:
json.dump(data, json_file, indent=4)
# 调用函数进行值裁剪
file_path = "D:\\DeepLearn\\NeRF\\instant-ngp-master\\data\\nerf\\my_workshop\\transforms.json" # JSON文件的路径
key = "file_path" # 要裁剪的键
max_length = 24 # 限制的最大长度
modify_json(file_path, key, max_length)
解决办法二:
再使用生成json文件脚本的时候,将–images这个参数设置为images!!!
但是前提是一定要cd进images的同级目录,并且其他所有参数的路径都要写成绝对路径!!!
python ./scripts/colmap2nerf.py(此处应为绝对路径,需修改) --aabb_scale 16 --images images --text ./data/nerf/my_workshop/sparse/0(此处应为绝对路径,需修改) --out ./data/nerf/my_workshop/transforms.json(此处应为绝对路径,需修改)
然后使用下面的脚本启动exe程序:
D:\\DeepLearn\\NeRF\\instant-ngp-master\\build\\testbed.exe --mode nerf --scene D:\\DeepLearn\\NeRF\\instant-ngp-master\\data\\nerf\\my_workshop\\transforms.json
\NeRF\instant-ngp-master\build\testbed.exe --mode nerf --scene D:\DeepLearn\NeRF\instant-ngp-master\data\nerf\my_workshop\transforms.json