【【三维重建】【深度学习】windows10下NeuS官方代码Pytorch实现
提示:最近开始在【三维重建】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。
前言
NeuS是由香港大学的Wang, P等人在《NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction【NeurIPS 2021】》【论文地址】一文中提出了一种新的神经表面重建方法,用于从2D图像输入中高保真地重建对象和场景。简单来说,提出了一种新的一阶近似无偏差的公式,从而即使没有掩模监督,也能进行更精确的表面重建。
在详细解析NeuS网络之前,首要任务是搭建NeuS【Pytorch-demo地址】所需的运行环境,并完成模型训练和测试工作,展开后续工作才有意义。
【NeuS总览】
【参考:基于COLMAP制作DTU格式数据集】
【NeuS代码Pytorch实现–训练阶段代码解析(上)】
【NeuS代码Pytorch实现–训练阶段代码解析(中)】
【NeuS代码Pytorch实现–训练阶段代码解析(下)】
【NeuS代码Pytorch实现–测试阶段代码解析(上)】
【NeuS代码Pytorch实现–测试阶段代码解析(下)】
NeuS模型运行
下载源码并安装环境
在win10环境下装anaconda环境,方便搭建专用于NeuS模型的虚拟环境。
【pytorch代码推荐参考教程】
安装GPU版本的pytorch教程,pytorch-gpu版本需要根据个人计算机去安装相应版本。
# 创建虚拟环境
conda create -n neus python=3.8
# 查看新环境是否安装成功
conda env list
# 激活环境
activate neus
# 下载githup源代码到合适文件夹,并cd到代码文件夹内(科学上网)
git clone https://github.com/Totoro97/NeuS.git
cd NeuS
# 安装pytorch包
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorboard
# 通过清华源,安装其他包(需要删除关于pytorch的部分,原版本是1.8.0)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
# 查看所有安装的包
pip list
conda list
最终的安装的所有包。
检查torch版,已经安装torch-gpu版本。
# 查看pytorch版本
import torch
print(torch.__version__)
# 查看cuda版本
print(torch.version.cuda)
# 查看cuda是否可用
print(torch.cuda.is_available())
# 查看可用cuda数量
print(torch.cuda.device_count())
训练NeuS
需要小改一下models/dataset.py中的源代码,否则不能正常运行
- self.device = torch.device(‘cuda’)
换成
self.device =torch.device(“cuda” if torch.cuda.is_available() else “cpu”)
- 将所有.cpu()都规范成.to(self.device)
- self.pose_all[idx_0].detach().to(self.device).numpy()
换成
self.pose_all[idx_0].detach().to(self.device).cpu().numpy()
1.安装mashlab: 下载meshlab软件,安装方式和常规软件一样,后续用于打开展示生成的mesh模型文件。
2.下载数据集:【谷歌云盘(官方下载地址)】【百度云盘(提取码:mz8w) 】
根据配置文件中数据指定的存放路径,在NeuS工程内创建public_data文件夹,把下载的开源数据解压放到public_data文件夹下。
3.不带mask的模式训练: 在执行指令时,数据的路径一定要到具体到包含cameras_sphere.npz文件的目录下。
# 训练bmvs_clock数据集
python exp_runner.py --mode train --conf ./confs/womask.conf --case data_BlendedMVS\bmvs_bear
显存不足导致的报错,在./confs/womask.conf中可以调整batch_size的大小:
训练生成的结果保存在NeuS工程目录下的exp文件夹下:
在womask_sphere/meshes目录下保存了训练过程中生成的mesh模型:
用meshlab查看模型,可以发现面片较少,需要精细mesh模型:
从训练好的模型(默认对最后一个模型)中提取曲面,并用新模型覆盖原模型。
python exp_runner.py --mode validate_mesh --conf ./confs/womask.conf --case data_BlendedMVS\bmvs_bear --is_continue
用meshlab查看新模型:
多视角的渲染效果,000,001是图片编号,可以自己调整。
python exp_runner.py --mode interpolate_000_001 --conf ./confs/womask.conf --case data_BlendedMVS\bmvs_bear --is_continue
在womask_sphere/render目录下保存了渲染的视频:
博主将视频转为了GIF方便展示:
生成以000图片为起点和以001图片为终点的多帧图片,并合成视频
4.带mask的模式训练
# 训练bmvs_clock数据集
python exp_runner.py --mode train --conf ./confs/wmask.conf --case data_BlendedMVS\bmvs_bear
在wmask/meshes目录下保存了训练过程中生成的mesh模型:
用meshlab查看模型,需要精细mesh模型:
从训练好的模型(默认对最后一个模型)中提取曲面。
python exp_runner.py --mode validate_mesh --conf ./confs/wmask.conf --case data_BlendedMVS\bmvs_bear --is_continue
用meshlab查看新模型:
多视角的渲染效果。
python exp_runner.py --mode interpolate_000_001 --conf ./confs/wmask.conf --case data_BlendedMVS\bmvs_bear --is_continue
在wmask/render目录下保存了渲染的视频(GIF展示):
带不带mask训练的区别目前主要感觉是在是否去除背景上
训练个人数据集
个人数据集的制作流程,可以参考博主的另一篇博文【基于COLMAP制作自己的NeRF(LLFF格式)数据集】,只需要看到“转成llff数据的格式”小节前。
制作数据集所需要的图片是用手机拍摄视频后抽帧获取的,完成的数据集放置在public_data\目录下
# 制作个人数据集所需的cameras_sphere.npz文件的工具包(neus工程目录下自带的)
# 包括了相机的属性和图像的位姿信息
cd preprocess_custom_data/colmap_preprocess
# 缺失相应的包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple imageio scikit-image
python imgs2poses.py ../../public_data/giraffe
在/public_data/giraffe路径下生成sparse_points.ply文件
用meshlab查看模型,可以发现是稀疏点云模型。
根据需要去除噪声点:
新模型保存为sparse_points_interest.ply:
python gen_cameras.py ../../public_data/giraffe
在public_data/giraffe/preprocessed会生成cameras_sphere.npz文件
此时按照开源数据的方法训练是会报错的,此时无论带不带mask的模式训练,image文件夹下的图像必须要在mask文件夹下也找到与其文件名和大小一致的mask图像。
这里mask的获取推荐查看博主的之前的博文【Windows10下MiVOS官方代码Pytorch实现与源码解析】,它能批量为一组数据集生成对应的mask,但其实空白图片作为mask也可以。
MiVOS执行后获得的mask图片。
目前这一步为止,mask文件中图像的尺寸和文件名与image中图像不一致,因此需要进一步处理使其保持一致,并且需要将mask从三通道彩色图变为单通道的黑白图。
import cv2
import os
from PIL import Image
import numpy as np
# 个人数据所在目录
dir_data = r'public_data/giraffe'
# mask的目录
dir_mask = os.path.join(dir_data, 'mask')
# image的目录
dir_img = os.path.join(dir_data, 'image')
# 所有mask文件名
mask_list = os.listdir(dir_mask)
# 所有image文件名
img_list = os.listdir(dir_img)
for mask_file, img_file in zip(mask_list, img_list):
# 获得图片的文件名
(img_filename, img_extension) = os.path.splitext(img_file)
# 修改图片的格式为png
img_file_png = img_filename + '.png'
img_file_png = os.path.join(dir_img, img_file_png)
# 读取图片
img = cv2.imread(os.path.join(dir_img, img_file))
# 删除旧格式图片
os.remove(os.path.join(dir_img, img_file))
# 保存新格式的图片
cv2.imwrite(img_file_png, img)
# 获取图片的尺寸,使mask的尺寸与原图保持一致
h, w = img.shape[0], img.shape[1]
# 读取mask,并将其转为黑白的mask,只有0和255
mask = cv2.imread(os.path.join(dir_mask, mask_file), 0) > 0
mask = mask*255
# resize mask的尺寸
mask = cv2.resize(mask.astype("uint8"), (w, h), interpolation=cv2.INTER_AREA)
# 单通道变为三通道
# image_mask = np.zeros_like(img)
# image_mask [:,:,0] = mask
# image_mask [:,:,1] = mask
# image_mask [:,:,2] = mask
# 使mask的文件名与原图保持一致
img_file_mask = img_filename + '.png'
img_file_mask = os.path.join(dir_mask, img_file_mask)
#删除旧的mask
os.remove(os.path.join(dir_mask, mask_file))
# 保持新的mask
# cv2.imwrite(img_file_mask, image_mask)
cv2.imwrite(img_file_mask, mask)
官方数据集的mask位深度是24(即channel通道数是3),但是博主在读了源码发现只用了mask一个通道,因此这里只需要保留位深度是8的mask也是可以的。
1.用不带mask的模式训练
# 训练bmvs_clock数据集
python exp_runner.py --mode train --conf ./confs/womask.conf --case giraffe
# 从训练好的模型中提取曲面
python exp_runner.py --mode validate_mesh --conf ./confs/womask.conf --case giraffe --is_continue
# 多视角的渲染效果。
python exp_runner.py --mode interpolate_000_004 --conf ./confs/womask.conf --case giraffe --is_continue
2.不带mask的模式训练
# 训练bmvs_clock数据集
python exp_runner.py --mode train --conf ./confs/wmask.conf --case giraffe
# 从训练好的模型中提取曲面
python exp_runner.py --mode validate_mesh --conf ./confs/wmask.conf --case giraffe --is_continue
# 多视角的渲染效果。
python exp_runner.py --mode interpolate_000_004 --conf ./confs/wmask.conf --case giraffe --is_continue
总结
尽可能简单、详细的介绍NeuS的安装流程以及解决了安装过程中可能存在的问题。后续会根据自己学到的知识结合个人理解讲解NeuS的原理和代码。