基于Nerf的三维重建算法Neus初探

文章介绍了NeuS,一种用于从2D图像重建高保真对象和场景的神经网络方法。通过训练神经SDF表示和改进的体绘制技术,NeuS能实现更精确的表面重建。文章提供了代码链接、安装教程,以及训练开源数据和自定义数据的步骤,包括使用Colmap进行相机位姿估计和mask生成。
摘要由CSDN通过智能技术生成

目录

介绍

安装

训练开源数据

训练自己的数据


介绍

作者提出了一种新的神经表面重建方法,称为NeuS,用于从2D图像输入中以高保真度重建对象和场景。在NeuS中,我们建议将曲面表示为有符号距离函数(SDF)的零级集,并开发一种新的体绘制方法来训练神经SDF表示。我们观察到,传统的体绘制方法会导致表面重建的固有几何误差(即偏差),因此提出了一种在一阶近似中没有偏差的新公式,从而即使在没有掩模监督的情况下也能实现更准确的表面重建。在DTU数据集和BlendedMVS数据集上的实验表明,NeuS在高质量表面重建方面优于现有技术,尤其是对于具有复杂结构和自遮挡的对象和场景。

算法已开源,先把代码扔这了。

github:GitHub - Totoro97/NeuS: Code release for NeuS

安装

git clone https://github.com/Totoro97/NeuS.git
cd NeuS
pip install -r requirements.txt

这是readme中给出的,如果顺利的话说明你安装的很顺利,如果不顺利的话,可以参考我的方法。(顺利的安装千篇一律,不顺的安装各有各的不顺,我的不顺是cuda和pytorch的版本不匹配)

首先还是推荐用conda搭建虚拟环境。

conda create -n neus python=3.8

激活虚拟环境

conda activate neus

然后安装pytorch,requirements.txt给出的版本是1.8.0,这里为了体现出个性,我选择装1.9.0。(其实是1.8.0版本不匹配报错了,不得已换了1.9.0,我用的cuda版本是11.1)

pip --default-timeout=1000 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

然后用pip install 把requirements.txt中的包都装一下,还有个tensorboard没写,也一并装一下。

环境搭建完成。

训练开源数据

在NeuS文件夹下创建public_data用于存放数据,把下载的开源数据解压放到这个文件夹下。

用不带mask的模式训练

python exp_runner.py --mode train --conf ./confs/womask.conf --case bmvs_clock

带mask的模式训练

python exp_runner.py --mode train --conf ./confs/wmask.conf --case bmvs_clock

这里显存不足的话可能会报错,把./confs/wmask.conf中的batch_size调小一点即可。

训练生成的结果会保存在根目录下exp文件夹下,可以看到meshes文件夹中保存了训练过程中的mesh模型,但面片较少。需要比较精细的mesh模型需要运行

python exp_runner.py --mode validate_mesh --conf ./confs/womask.conf --case bmvs_clock--is_continue 

还可以生成多视角的渲染效果,可运行:

python exp_runner.py --mode interpolate_000_001 --conf ./confs/womask.conf --case bmvs_clock --is_continue 

000,001是图片编号,根据自己需要调整。

用meshlab打开ply文件,没有纹理,只有白模。

训练自己的数据

首先用手机对着重建模型咔咔一顿拍,尽量多拍一些不同角度的,然后我们获得了一堆图像文件。

先来看一下之前训练的开源数据,包含了两个文件夹和一个文件。

image文件夹就是rgb图片数据,算法默认支持png格式。

mask文件夹包含的是模型的前景图像,前景和后景以黑色和白色区分,如果配置文件选择withou mask,其实这个文件夹的数据是没有意义的。但必须有文件,且名称、图像像素要和image的图像一一对应。

最后是cameras_sphere.npz文件,它包括了相机的属性和图像的位姿信息等,这个是需要我们自己计算的。官方给出了两种计算方案,这里只介绍第二种,用colmap计算npz文件。colmap的使用可参考:colmap简介及入门级使用 - 知乎。这里就不详述了。

新建一个文件夹test1和一个子文件夹test1/image,并将图片数据都放在image文件夹下。使用colmap计算得到data.db文件,File->Export model将计算结果导出到/sparse/0文件夹下。

运行

cd colmap_preprocess
python imgs2poses.py ../../public_data/test1

会在/public_data/test1路径下生成sparse_points.ply文件。这是重建的稀疏点云模型。根据需要分割要建模的区域保存为sparse_points_interest.ply。

运行

python gen_cameras.py ../../public_data/test1

在test1/preprocessed会生成cameras_sphere.npz文件。

此时按照开源数据的方法训练是会报错的,还差mask数据,即使运行without mask模式也不行,必须要在mask文件夹下找到对应image文件夹的数据,图像的文件名和大小也要一致,空白图片也可以。这里把我的生成mask数据的代码放到这里,供大家参考。

# coding:utf-8

import cv2
import os
import numpy as np

dir = '/home/user/nerf/NeuS/public_data/test1'
dir_mask = os.path.join(dir,'mask')
if not os.path.exists(dir_mask):
    os.mkdir(dir_mask)
img_dir = os.path.join(dir,'image')
img_list = os.listdir(img_dir)
for img_file in img_list:
    (filename, extension) = os.path.splitext(img_file)
    if extension == '.JPG' :
        img_file_png = filename + '.png'
        img_file_png = os.path.join(img_dir, img_file_png)
        img_file_mask = dir + '/mask/' + filename + '.png'
        img = cv2.imread(os.path.join(img_dir,img_file))
        img_mask = np.zeros(img.shape, np.uint8)
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                 img_mask[i,j,:] = [255,255,255]
        cv2.imwrite(img_file_png, img)  
        cv2.imwrite(img_file_mask, img_mask)  
        os.remove(os.path.join(img_dir,img_file))  # 删除原文件

然后和开源数据用相同的方法训练即可。

  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
NERF(Neural Radiance Fields)是一种基于神经网络的三维重建算法,可以从多个二维图像中恢复出一个高质量的三维场景。以下是一个简单的 PyTorch 实现,只包含核心代码: ```python import torch import torch.nn as nn import torch.nn.functional as F class NeRF(nn.Module): def __init__(self, in_features, hidden_features, out_features): super(NeRF, self).__init__() self.fc1 = nn.Linear(in_features, hidden_features) self.fc2 = nn.Linear(hidden_features, hidden_features) self.fc3 = nn.Linear(hidden_features, out_features) def forward(self, x): x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x class NeRFRenderer(nn.Module): def __init__(self, net, near, far, num_samples): super(NeRFRenderer, self).__init__() self.net = net self.near = near self.far = far self.num_samples = num_samples def forward(self, ray_origins, ray_directions): t_vals = torch.linspace(self.near, self.far, self.num_samples, device=ray_origins.device) sample_points = ray_origins[...,None,:] + ray_directions[...,None,:] * t_vals[None,None,:,None] rgb = 0.0 alpha = 0.0 for i in range(self.num_samples): rgb_alpha = self.net(sample_points[...,i,:]) rgb += (1 - alpha) * rgb_alpha[...,0:3] * rgb_alpha[...,3:6] alpha += (1 - alpha) * rgb_alpha[...,6] return rgb, alpha ``` 这里定义了一个 `NeRF` 类,用于构建神经网络,以及一个 `NeRFRenderer` 类,用于实现渲染操作。在 `NeRFRenderer` 中,根据给定的相机位置和方向,通过对多个采样点进行神经网络计算,得到 RGB 颜色和透明度,最终生成渲染图像。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值