Code release for NeuS

Related tags

Deep Learning NeuS
Overview

NeuS

We present a novel neural surface reconstruction method, called NeuS, for reconstructing objects and scenes with high fidelity from 2D image inputs.

Project page | Paper | Data

This is the official repo for the implementation of NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction.

Usage

Data Convention

The data is organized as follows:

<case_name>
|-- cameras_xxx.npz    # camera parameters
|-- image
    |-- 000.png        # target image for each view
    |-- 001.png
    ...
|-- mask
    |-- 000.png        # target mask each view (For unmasked setting, set all pixels as 255)
    |-- 001.png
    ...

Here the cameras_xxx.npz follows the data format in IDR, where world_mat_xx denotes the world to image projection matrix, and scale_mat_xx denotes the normalization matrix.

Setup

Clone this repository

git clone https://github.com/Totoro97/NeuS.git
cd NeuS
pip install -r requirements.txt
Dependencies (click to expand)
  • torch==1.8.0
  • opencv_python==4.5.2.52
  • trimesh==3.9.8
  • numpy==1.19.2
  • pyhocon==0.3.57
  • icecream==2.1.0
  • tqdm==4.50.2
  • scipy==1.7.0
  • PyMCubes==0.1.2

Running

  • Training without mask
python exp_runner.py --mode train --conf ./confs/womask.conf --case <case_name>
  • Training with mask
python exp_runner.py --mode train --conf ./confs/wmask.conf --case <case_name>
  • Extract surface from trained model
python exp_runner.py --mode validate_mesh --conf <config_file> --case <case_name> --is_continue # use latest checkpoint

The corresponding mesh can be found in exp/<case_name>/<exp_name>/meshes/<iter_steps>.ply.

  • View interpolation
python exp_runner.py --mode interpolate_<img_idx_0>_<img_idx_1> --conf <config_file> --case <case_name> --is_continue # use latest checkpoint

The corresponding image set of view interpolation can be found in exp/<case_name>/<exp_name>/render/.

Citation

Cite as below if you find this repository is helpful to your project:

@article{wang2021neus,
  title={NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction},
  author={Wang, Peng and Liu, Lingjie and Liu, Yuan and Theobalt, Christian and Komura, Taku and Wang, Wenping},
  journal={arXiv preprint arXiv:2106.10689},
  year={2021}
}

Acknowledgement

Some code snippets are borrowed from IDR and NeRF-pytorch. Thanks for these great projects.

Comments
  • Learning with 360-view data

    Learning with 360-view data

    Hi there,

    I'm trying to learn 3D scene with 360-degree view dataset like lego data in NeRF. It seems that the learning process is suffered from the initial error of SDF estimation. Of course, it is a different scenario with IDR dataset, however, the learning usually converges to local optimum Could you please let me know is there any strategy to learn the 360 view data properly?

    opened by robot0321 14
  • Thin structures reproduction

    Thin structures reproduction

    Hello, I am trying to reproduce your results on the thin structures. I run the images through the COLMAP, calculate the camera_sphere.npz but the scale matrix is wrong. This is the scale matrix I get:

    Scale matrix:
    [[ 1.2317002e+03  0.0000000e+00  0.0000000e+00 -1.7486597e+02]
     [ 0.0000000e+00  1.2317002e+03  0.0000000e+00 -2.5129393e+01]
     [ 0.0000000e+00  0.0000000e+00  1.2317002e+03  1.0682924e+03]
     [ 0.0000000e+00  0.0000000e+00  0.0000000e+00  1.0000000e+00]]
    

    I provide a visualisation of cameras in Unity3D. The cubes represent cameras, the rays from cubes outwards represent the camera direction where the blue rays are original cameras and the red rays are from the COLMAP. The XYZ cross represents world's center (0,0,0).

    Visualisation of not scaled cameras: thin_cube_raw

    Visualisation of scaled cameras: red cameras are scaled down way too much thin_cube_scaled

    However, it works on the DTU and BMVS datasets. Could you please provide any details on how did you get your camera_sphere.npz for the thin structures, or any idea what could be wrong or how to set the preprocess_cameras.py?

    opened by theFilipko 6
  • Psnr reproduction problem with pretrained model

    Psnr reproduction problem with pretrained model

    Hi, I can not reproduce the psnr you@Totoro97 mentioned in the supplementary materials with your pre-trained models.

    image

    Here are the psnr from pre-trained models: image

    Please tell me if I miss something.

    opened by 1612190130 5
  • Cannot reproduce results using COLMAP on data

    Cannot reproduce results using COLMAP on data

    Hello, I have been trying to do the following:

    1. take a data, let's say bmvs_stone
    2. feed images to the COLMAP
    3. generate the cameras_sphere.npz
    4. train NeuS on these data

    To generate the cameras_sphere.npz I used this code from the IDR project. This code has many times resulted in error because it was not able to find points for normalisation, here. After rerunning the COLMAP a few times, I got 2 points and it was able to generate the scale_mat_xx. However, the results after training are blurry, not good.

    I have tried using automatic reconstruction in COLMAP and also this script from the LLFF project.

    To convert the output from the COLMAP to camera_sphere.npz I used this:

    import numpy as np
    import os
    import colmap_read_model as read_model
    from scipy.spatial.transform import Rotation as R
    
    
    DIR = "/home/uriel/Downloads/DTU/dtu_scan24"
    DST = os.path.join(DIR, "cameras_sphere.npz")
    
    
    def load_colmap_data(realdir):
        camerasfile = os.path.join(realdir, 'sparse/0/cameras.bin')
        camdata = read_model.read_cameras_binary(camerasfile)
    
        # cam = camdata[camdata.keys()[0]]
        list_of_keys = list(camdata.keys())
        cam = camdata[list_of_keys[0]]
    
        h, w, f, cx, cy = cam.height, cam.width, cam.params[0], cam.params[1], cam.params[2]
        # w, h, f = factor * w, factor * h, factor * f
        hwf = np.array([h, w, f]).reshape([3, 1])
        k = np.array([[f, 0, cx],
                      [0, f, cy],
                      [0, 0, 1]])
    
        imagesfile = os.path.join(realdir, 'sparse/0/images.bin')
        imdata = read_model.read_images_binary(imagesfile)
    
        w2c_mats = []
        bottom = np.array([0, 0, 0, 1.]).reshape([1, 4])
    
        names = [imdata[k].name for k in imdata]
        print('Images #', len(names))
        perm = np.argsort(names)
        for i in imdata:
            im = imdata[i]
            R = im.qvec2rotmat()
            t = im.tvec.reshape([3, 1])
            m = np.concatenate([np.concatenate([R, t], 1), bottom], 0)
            w2c_mats.append(m)
    
        w2c_mats = np.stack(w2c_mats, 0)
        c2w_mats = np.linalg.inv(w2c_mats)
    
        return k, c2w_mats, perm
    
    
    k, rts, perm = load_colmap_data(DIR)
    cameras = {}
    for i in perm:
        r = rts[i, :3, :3]
        t = rts[i, :3, 3]
        wm = np.eye(4)
        wm[:3,:3] = k @ r
        wm[:3,3] = k @ t
        cameras['world_mat_%d' % i] = wm
        cameras['scale_mat_%d' % i] = np.eye(4)
    
    np.savez(DST, **cameras)
    

    The code is inspired by this script.

    I think the problem is that COLMAP uses a different coordinate system then NeuS and IDR, which I suppose is the same as OpenGL, where COLMAP says: The local camera coordinate system of an image is defined in a way that the X axis points to the right, the Y axis to the bottom, and the Z axis to the front as seen from the image.

    Do you have any ideas how to solve it? Thanks

    opened by theFilipko 5
  • get a sphere noise point around the target

    get a sphere noise point around the target

    i use the default params ,preprocessed data using colmap script by you and train on my data,but get this strenge results:the target is good except the points around. image 000

    opened by Yes-Jumby 4
  • Scene bound estimation

    Scene bound estimation

    Hi. I can see that the scene bounds are calculated in this function: https://github.com/Totoro97/NeuS/blob/9dc9275d3a8c7266994a3b9cf9f36071621987dd/models/dataset.py#L160-L166

    But I am not sure how scene bounds can be estimated just from ray origins and directions. Can you please explain what these different operations are doing conceptually ?

    opened by sanowar-raihan 4
  • would you like to help me to ensure coordinates and params?

    would you like to help me to ensure coordinates and params?

    I want to put texture to ply files produced by pretrained model of bmvs_bear; what I need is: A:ply x y z and face ,the point in ply should in world coordinate. and i get it in this way:(i check the code ,this produce a set of points in world coordinates
    validate_mesh(self, world_space=True, resolution=512, threshold=0.0)) python exp_runner.py --mode validate_mesh --conf <config_file> --case <case_name> --is_continue # use latest checkpoint all is the same with the example not change. B: instinct and extrinct of per pic and i get it from Dataset class by adding a member function def save_cam(self): print("start to save!") intrinsics_ = self.intrinsics_all.cpu().numpy() pose_all_ = self.pose_all.cpu().numpy() max_h_w = max(self.W ,self.H) for index in range(self.n_images): print ('images_path : %s' % self.images_lis[index]) current_cam_path = self.images_lis[index] current_cam_path = current_cam_path.replace('png','cam') print (type(current_cam_path)) print ('cam_path : %s' % current_cam_path) fx = intrinsics_[index][0][0] cx = self.W - intrinsics_[index][0][2] cy = intrinsics_[index][1][2] d0 = 0.0 d1 = 0.0 paspect = self.W * 1.0/self.H ppx = cx/self.W ppy = cy/self.H print ('fx : %f cx : %f cy : %f' % (fx,cx,cy)) print ('intrinsics_ : %s' % intrinsics_[index]) tx = -pose_all_[index][0][3] ty = pose_all_[index][1][3] tz = -pose_all_[index][2][3] R00 = -pose_all_[index][0][0] R01 = -pose_all_[index][0][1] R02 = -pose_all_[index][0][2] R10 = pose_all_[index][1][0] R11 = pose_all_[index][1][1] R12 = pose_all_[index][1][2] R20 = -pose_all_[index][2][0] R21 = -pose_all_[index][2][1] R22 = -pose_all_[index][2][2] file = open(current_cam_path, 'w')#negetive here to trans points in neus to i need file.write('%f %f %f %f %f %f %f %f %f %f %f %f\n'%(tx,ty,tz,R00,R01,R02,R10,R11,R12,R20,R21,R22)) file.write('%f %f %f %f %f %f\n'%(fx/max_h_w,0.0,0.0,paspect,ppx,ppy))

    unfortunately,i got a bad result,so there must be a error in this pipeline.would you like to help me to ensure A and B(),to see where is error? plus:the pic indicates the coordinate In neus and I need image

    opened by Yes-Jumby 3
  • Question about the paper: derivation of equation 6

    Question about the paper: derivation of equation 6

    Hi, I would like to ask the derivation process of equation 6. image Especially moving cosine outside the integration: image As stated in the paper, here we treat cosine as a constant, and I know that the constant factor in integral can be move outside the integral, but why we end up move |cos(theta)|^{-1} out instead of -|cos(theta)| ? TIA.

    opened by murumura 3
  • How to evaluate the MAE of SDF values?

    How to evaluate the MAE of SDF values?

    Hi,

    Thanks for your excellent work. I'm curious about the MAE of SDF values mentioned in sec 4.3. How do you get the GT SDF? Do you calculate it by querying the nearest point with the provided mesh or pointcloud in DTU? Could you please share the evaluation code for this metric in convenience?

    opened by fzy139 2
  • how to evaluate the meshes ?

    how to evaluate the meshes ?

    after trained without mask, I found some extra meshes such as white planes, how can I evaluate the chamfer distance between the pred mesh and gt point cloud. If I sample many points in the surface of mesh, there will be many points in white planes in the same time. image

    opened by MaybeOjbk 2
  • Visualization of signed distance fields

    Visualization of signed distance fields

    Thanks for the great work!

    I want to draw the SDF contour lines on the cutting plane. How do you draw the pictures like Figure 13. in your paper?

    Thanks a lot!

    opened by tmpss93172 2
  • Bad generated mesh for lego

    Bad generated mesh for lego

    Dear authors,

    Thanks a lot for your great work! I have tried to use the lego data to train and the results seems really bad as the attached image shows, do you have any idea to debug it? The training data and conf file is downloaded from issue #9 .

    Screenshot_20230108_095548

    Thank you very much!

    Best, Yuchen

    opened by yuchenrao 0
  • Forward-facing scene implementation

    Forward-facing scene implementation

    Hi, I appreciate to your awesome work!

    I have three questions.

    1. How to train NeuS on forward-facing scene(e.g. fern scene in NeRF dataset) using dataloader for llff formatted scene? I used dataloader in official implementation of NeRF to load the offered dataset from them. In their dataset,poses_bounded.npz, which is already colmap-preprocessed data, are exists and I used it. Hence, near and far bound are set following the npz file and they are not estimated as unit-sphere as you implemented for NeuS. In addition, we use the camera poses of the scene from poses_bounded.npz as it is and not rescale as you did in your code following original NeRF setting. Is there any problem for this setting to train the NeuS on real forward-facing scene? I wonder that we have to rescale the forward-facing scene to be in unit-sphere scale and rescale the camera pose for training NeuS.

    2. How to set the object bounding box parameters(object_bbox_min, object_bbox_max in dataset.py) for forward-facing scene? I guess it would not necessary for forward-facing scene since they are scene-level NeRF framework and not object-centric scene. However, I'm confused how to set the above values to generate mesh from trained NeuS for forward-facing scene.

    3. Related to question 2. Unlike the dataset used to train NeuS on this repo, forward-facing scene usually include sky-like part which are regarded as infinite depth. Hence I wonder it is necessary to use the NDC coordinate to train the NeuS on forward-facing scene. In addition, if it is necessary to set the object bounding box parameters to exclude the sky-like part when we generate mesh from trained NeuS on forward-facing scene, how to set the values?

    Thank you for your work again and I will wait for your reply!

    opened by dogyoonlee 0
  • Can not get any meshes after training

    Can not get any meshes after training

    I haved trained the model using my pictures and womask.conf but can not get any result. A part of the output text:

    [export.py:72 -          export_mesh() ] Exporting 0 faces as PLY
    [exp_runner.py:342 -        validate_mesh() ] End
    

    When validating meshes,there is always nothing to export . I don't know what happends The exported .ply files are also empty

    opened by Lumine7 0
  • confused about the code impletation to plot normal map

    confused about the code impletation to plot normal map

    Dear authors, thank you for the amazing work! I am a little confused about the code implementation about how to plot the normal map in exp_runner.py

    normal_img = np.concatenate(out_normal_fine, axis=0)
    rot = np.linalg.inv(self.dataset.pose_all[idx, :3, :3].detach().cpu().numpy())
    normal_img = (np.matmul(rot[None, :, :], normal_img[:, :, None])
                  .reshape([H, W, 3, -1]) * 128 + 128).clip(0, 255)
    

    why do we need to put the c2w rotation matrix upon the normal map? Sorry, I am a freshman in this field and have little understanding of the graphics, and I didn't see the code in VolSDF or other works, they just multiply 255 and save it in images. could you tell me what's the difference between these methods concerning how to plot normal maps? Thanks again

    opened by xubaixinxbx 0
  • IndexError: index 3678 is out of bounds for dimension 1 with size 3024

    IndexError: index 3678 is out of bounds for dimension 1 with size 3024

    I keep getting IndexError: index 3678 is out of bounds for dimension 1 with size 3024 when training my models. May I know what I am doing wrong?

    Hello Wooden Load data: Begin Load data: End 0%| | 0/300000 [00:00<?, ?it/s] Traceback (most recent call last): File "exp_runner.py", line 392, in runner.train() File "exp_runner.py", line 105, in train data = self.dataset.gen_random_rays_at(image_perm[self.iter_step % len(image_perm)], self.batch_size) File "/home/user/NeuS/models/dataset.py", line 119, in gen_random_rays_at mask = self.masks[img_idx][(pixels_y, pixels_x)] # batch_size, 3 IndexError: index 3678 is out of bounds for dimension 1 with size 3024

    opened by raw5 1
Owner
Peng Wang
PhD student @ HKU
Peng Wang
Code release for NeX: Real-time View Synthesis with Neural Basis Expansion

NeX: Real-time View Synthesis with Neural Basis Expansion Project Page | Video | Paper | COLAB | Shiny Dataset We present NeX, a new approach to novel

null 536 Dec 20, 2022
The code release of paper 'Domain Generalization for Medical Imaging Classification with Linear-Dependency Regularization' NIPS 2020.

Domain Generalization for Medical Imaging Classification with Linear Dependency Regularization The code release of paper 'Domain Generalization for Me

Yufei Wang 56 Dec 28, 2022
Code release for "Transferable Semantic Augmentation for Domain Adaptation" (CVPR 2021)

Transferable Semantic Augmentation for Domain Adaptation Code release for "Transferable Semantic Augmentation for Domain Adaptation" (CVPR 2021) Paper

null 66 Dec 16, 2022
This is the official code release for the paper Shape and Material Capture at Home

This is the official code release for the paper Shape and Material Capture at Home. The code enables you to reconstruct a 3D mesh and Cook-Torrance BRDF from one or more images captured with a flashlight or camera with flash.

null 89 Dec 10, 2022
Code release for "COTR: Correspondence Transformer for Matching Across Images"

COTR: Correspondence Transformer for Matching Across Images This repository contains the inference code for COTR. We plan to release the training code

UBC Computer Vision Group 360 Jan 6, 2023
Code release for paper: The Boombox: Visual Reconstruction from Acoustic Vibrations

The Boombox: Visual Reconstruction from Acoustic Vibrations Boyuan Chen, Mia Chiquier, Hod Lipson, Carl Vondrick Columbia University Project Website |

Boyuan Chen 12 Nov 30, 2022
We will release the code of "ConTNet: Why not use convolution and transformer at the same time?" in this repo

ConTNet Introduction ConTNet (Convlution-Tranformer Network) is proposed mainly in response to the following two issues: (1) ConvNets lack a large rec

null 93 Nov 8, 2022
Code release to accompany paper "Geometry-Aware Gradient Algorithms for Neural Architecture Search."

Geometry-Aware Gradient Algorithms for Neural Architecture Search This repository contains the code required to run the experiments for the DARTS sear

null 18 May 27, 2022
This is the dataset and code release of the OpenRooms Dataset.

This is the dataset and code release of the OpenRooms Dataset.

Visual Intelligence Lab of UCSD 95 Jan 8, 2023
Code release of paper "Deep Multi-View Stereo gone wild"

Deep MVS gone wild Pytorch implementation of "Deep MVS gone wild" (Paper | website) This repository provides the code to reproduce the experiments of

François Darmon 53 Dec 24, 2022
Code release for DS-NeRF (Depth-supervised Neural Radiance Fields)

Depth-supervised NeRF: Fewer Views and Faster Training for Free Project | Paper | YouTube Pytorch implementation of our method for learning neural rad

null 524 Jan 8, 2023
Code release for BlockGAN: Learning 3D Object-aware Scene Representations from Unlabelled Images

BlockGAN Code release for BlockGAN: Learning 3D Object-aware Scene Representations from Unlabelled Images BlockGAN: Learning 3D Object-aware Scene Rep

null 41 May 18, 2022
Code Release for Learning to Adapt to Evolving Domains

EAML Code release for "Learning to Adapt to Evolving Domains" (NeurIPS 2020) Prerequisites PyTorch >= 0.4.0 (with suitable CUDA and CuDNN version) tor

null 23 Dec 7, 2022
Code release for "Self-Tuning for Data-Efficient Deep Learning" (ICML 2021)

Self-Tuning for Data-Efficient Deep Learning This repository contains the implementation code for paper: Self-Tuning for Data-Efficient Deep Learning

THUML @ Tsinghua University 101 Dec 11, 2022
Code release for our paper, "SimNet: Enabling Robust Unknown Object Manipulation from Pure Synthetic Data via Stereo"

SimNet: Enabling Robust Unknown Object Manipulation from Pure Synthetic Data via Stereo Thomas Kollar, Michael Laskey, Kevin Stone, Brijen Thananjeyan

null 68 Dec 14, 2022
Code release for The Devil is in the Channels: Mutual-Channel Loss for Fine-Grained Image Classification (TIP 2020)

The Devil is in the Channels: Mutual-Channel Loss for Fine-Grained Image Classification Code release for The Devil is in the Channels: Mutual-Channel

PRIS-CV: Computer Vision Group 230 Dec 31, 2022
Code release for NeurIPS 2020 paper "Co-Tuning for Transfer Learning"

CoTuning Official implementation for NeurIPS 2020 paper Co-Tuning for Transfer Learning. [News] 2021/01/13 The COCO 70 dataset used in the paper is av

THUML @ Tsinghua University 35 Sep 23, 2022
Code Release for ICCV 2021 (oral), "AdaFit: Rethinking Learning-based Normal Estimation on Point Clouds"

AdaFit: Rethinking Learning-based Normal Estimation on Point Clouds (ICCV 2021 oral) **Project Page | Arxiv ** Runsong Zhu¹, Yuan Liu², Zhen Dong¹, Te

null 40 Dec 30, 2022
Code release for the ICML 2021 paper "PixelTransformer: Sample Conditioned Signal Generation".

PixelTransformer Code release for the ICML 2021 paper "PixelTransformer: Sample Conditioned Signal Generation". Project Page Installation Please insta

Shubham Tulsiani 24 Dec 17, 2022