Official Implementation of Neural Splines

Overview

Neural Splines: Fitting 3D Surfaces with Inifinitely-Wide Neural Networks

Neural Splines Teaser This repository contains the official implementation of the CVPR 2021 (Oral) paper Neural Splines: Fitting 3D Surfaces with Infinitely-Wide Neural Networks.

Setup Instructions

System Requirements

Neural Splines uses FALKON, a state-of-the-art kernel ridge regression solver to fit surfaces on one or more GPUs. We thus require at least one GPU to run Neural Splines. We additionally require a working version of the CUDA compiler nvcc. We recommend running this code on a machine with a lot of memory if you want to reconstruct large point clouds since Neural Splines stores an MxM preconditioner matrix in CPU memory (where M is the number of Nystrom samples).

Installing Dependencies

Neural splines has several dependencies which must be installed before it can be used. Some of these dependencies must be built and take time to install. There are three ways to install dependencies:

Installing Dependencies with conda

Simply run

conda env create -f environment.yml

and then go grab a coffee . When you get back, you will have a conda environment called neural-splines with the right dependencies installed.

Installing Dependencies with pip

We include several requirement-*.txt files in the requirements directory depending on your version of cuda. Choose the right file for your installation then run

pip install -r requirements/requirements-cuda<VERSION>.txt

and then go grab a coffee .

Installing Dependencies Manually (Not Recommended)

You will need to install the following dependencies manually to use this repository:

You will also need to build the following dependencies from source. The easiest way to do this is with pip (see commands below), but you can also clone the linked repositories and run setup.py install:

Testing Your Installation

⚠️ WARNING ⚠️ Due to a bug in KeOps, the first time you use any code in this repository will throw a ModuleNotFoundError. All subsequent invocations of Neural Splines should work.

  1. Download and unzip the example point clouds here
  2. Unzip the file, in the directory of this repository, which should produce a directory named demo_data
  3. Run python fit.py demo_data/bunny.ply 10_000 128 On the first run this will fail (see above, just rerun it). On the second run it will compile some kernels and then produce a file called recon.ply which should be a reconstructed Stanford Bunny. The image below shows the input points and reconstruction for the bunny,
  4. Run python fit-grid.py demo_data/living_room_33_500_per_m2.ply 10_000 512 8 which will produce another recon.ply mesh, this time of a full room as shown below.

A reconstructed Stanford Bunny A reconstruced living room

Using Neural Splines from the Command Line

There are two scripts in this repository to fit surfaces from the command line:

  • fit.py fits an input point cloud using a single Neural Spline. This method is good for smaller inputs without too much geometric complexity.
  • fit_grid.py fits an input point cloud in chunks using a different Neural Spline per chunk. This method is better for very large scenes with a lot of geometric complexity.

Reconstructing a point cloud with fit.py

fit.py fits an input point cloud using a single Neural Spline. This approach works best for relatively small inputs which don't have too much geometric complexity. fit.py takes least the following arguments

fit.py <INPUT_POINT_CLOUD> <NUM_NYSTROM_SAMPLES> <GRID_SIZE>

where

  • <INPUT_POINT_CLOUD> is a path to a PLY file containing 3D points and corresponding normals
  • <EPS> is a spacing parameter used for finite difference approximation of the gradient term in the kernel. To capture all surface details this should be less than half the smallest distance between two points. Generally setting this to values smalelr than 0.5/grid_size is reasonable for this parameter
  • <NUM_NYSTROM_SAMPLES> is the number of points to use as basis centers. A larger number of Nystrom samples will yield a more accurate reconstruction but increase runtime and CPU memory usage. Generally good values for this are between 10*sqrt(N) and 100*sqrt(N) where N is the number of input points.
  • <GRID_SIZE> is the number of voxel cells along the longest axis of the bounding box on which the reconstructed function gets sampled. For example if <grid_size> is 128 and the bounding box of the input pointcloud has dimensions [1, 0.5, 0.5], then we will sample the function on a 128x64x64 voxel grid before extracting a mesh.

Reconstructing very large point clouds with fit-grid.py

fit-grid.py fits an input point cloud in chunks using a different Neural Spline per chunk. This approach works well when the input point cloud is large or has a lot of geometric complexity. fit-grid.py takes the following required arguments

fit-grid.py <INPUT_POINT_CLOUD> <NUM_NYSTROM_SAMPLES> <GRID_SIZE> <CELLS_PER_AXIS>

where

  • <INPUT_POINT_CLOUD> is a path to a PLY file containing 3D points and corresponding normals
  • <NUM_NYSTROM_SAMPLES> is the number of points to use as basis centers within each chunk. A larger number of Nystrom samples will yield a more accurate reconstruction but increase runtime and CPU memory usage.
  • <GRID_SIZE> is the number of voxel cells along the longest axis of the bounding box on which the reconstructed function gets sampled. For example if <GRID_SIZE> is 128 and the bounding box of the input pointcloud has dimensions [1, 0.5, 0.5], then we will sample the function on a 128x64x64 voxel grid before extracting a mesh.
  • <CELLS_PER_AXIS> is an integer specifying the number of chunks to use along each axis. E.g. if <cells-per-axis> is 8, we will reconstruct the surface using 8x8x8 chunks.

Furthermore, fit-grid.py accepts the following optional arguments:

  • --overlap <OVERLAP> optionally specify the fraction by which cells overlap. The default value is 0.25. If this value is too small, there may be artifacts in the output at the boundary of cells.
  • --weight-type <WEIGHT_TYPE> How to interpolate predictions in overlapping cells. Must be one of 'trilinear' or 'none', where 'trilinear' interpolates using a partition of unity defined using a bicubic spline and 'none' does not interpolate overlapping cells. Default is 'trilinear'.
  • --min-pts-per-cell <MIN_PTS_PER_CELL> Ignore cells with fewer points than this value. Default is 0.

Additional arguments to fit.py and fit-grid.py

Additionally, both fit.py and fit-grid.py accept the following optional arguments which can alter the behavior and performance of the fitting process:

  • --scale <SCALE>: Reconstruct the surface in a bounding box whose diameter is --scale times bigger than the diameter of the bounding box of the input points. Defaults is 1.1.
  • --regularization <REGULARIZATION>: Regularization penalty for kernel ridge regression. Default is 1e-10.
  • --nystrom-mode <NYSTROM_MODE>: How to generate nystrom samples. Default is 'blue-noise'. Must be one of
    • 'random': choose Nyström samples at random from the input
    • 'blue-noise': downsample the input with blue noise to get Nyström samples
    • 'k-means': use k-means clustering to generate Nyström samples
  • --trim <TRIM>: If set to a positive value, trim vertices of the reconstructed mesh whose nearest point in the input is greater than this value. The units of this argument are voxels (where the grid_size determines the size of a voxel) Default is -1.0.
  • --eps <EPS>: Perturbation amount for finite differencing in voxel units. i.e. we perturb points by eps times the diagonal length of a voxel (where the grid_size determines the size of a voxel). To approximate the gradient of the function, we sample points +/- eps along the normal direction.
  • --voxel-downsample-threshold <VOXEL_DOWNSAMPLE_THRESHOLD>: If the number of input points is greater than this value, downsample it by averaging points and normals within voxels on a grid. The size of the voxel grid is determined via the --grid-size argument. Default is 150_000.NOTE: This can massively speed up reconstruction for very large point clouds and generally won't throw away any details.
  • --kernel <KERNEL>: Which kernel to use. Must be one of 'neural-spline', 'spherical-laplace', or 'linear-angle'. Default is 'neural-spline'.NOTE: The spherical laplace is a good approximation to the neural tangent kernel (see this paper for details)
  • --seed <SEED>: Random number generator seed to use.
  • --out <OUT>: Path to file to save reconstructed mesh in.
  • --save-grid: If set, save the function evaluated on a voxel grid to {out}.grid.npy where out is the value of the --out argument.
  • --save-points: If set, save the tripled input points, their occupancies, and the Nyström samples to an npz file named {out}.pts.npz where out is the value of the --out argument.
  • --cg-max-iters <CG_MAX_ITERS>: Maximum number of conjugate gradient iterations. Default is 20.
  • --cg-stop-thresh <CG_STOP_THRESH>: Stop threshold for the conjugate gradient algorithm. Default is 1e-5.
  • --dtype DTYPE: Scalar type of the data. Must be one of 'float32' or 'float64'. Warning: float32 only works for very simple inputs.
  • --outer-layer-variance <OUTER_LAYER_VARIANCE>: Variance of the outer layer of the neural network from which the neural spline kernel arises from. Default is 0.001.
  • --verbose: If set, spam your terminal with debug information

Trimming Reconstructed Meshes

Neural Splines can sometimes add surface sheets far away from input points, to remove these, we include a surface trimming script (similar to Poisson Surface Reconstruction), which trims mesh faces away from the input points. To trim a surface, simply run:

python trim-surface.py <INPUT_POINT_CLOUD> <RECONSTRUCTED_MESH> <GRID_SIZE> <DISTANCE_THRESHOLD> --out <OUT_FILE>

where:

  • <INPUT_POINT_CLOUD> is a path to the input point cloud to the reconstruction algorithm
  • <RECONSTRUCTED_MESH> is a path to the mesh reconstructed by neural splines
  • <GRID_SIZE> is the size of the voxel grid used to reconstruct the mesh (the same value as the <GRID_SIZE> argument to fit.py or fit-grid.py)
  • <DISTANCE_THRESHOLD> is the distance (in voxels) above which faces should be discarded (e.g. passing 2.5 will discard any surface which is greater than 3 voxels away from an input point.
  • --out <OUT_FILE> is an optional path to save the trimmed mesh to. By default it is trimmed.ply.

Using Neural Splines in Python

Neural Splines can be used directly from within python by importing the neural_splines module in this repository.

To reconstruct a surface using Neural Splines, use the function neural_splines.fit_model_to_pointcloud. It returns a model object with the same API as Skikit-Learn. NOTE: neural_splines.fit_model_to_pointcloud can additionally accept other optional arguments. Run help(neural_splines.fit_model_to_pointcloud) for details.

from neural_splines import fit_model_to_point_cloud

# x is a point cloud stored in a torch tensor of shape [N, 3]
# n is a tensor of unit normals (one per point) of shape [N, 3]
# num_ny is the number of Nystrom samples to use 
# eps is the finite differencing coefficient (see documentation above)
model = fit_model_to_pointcloud(x, n, num_ny, eps)

# Evaluate the neural spline at a point p
p = torch.tensor([[0.5, 0.5, 0.5]]).to(x)
f_p = model.predict(p)

To evaluate a fitted Neural Spline on a grid of points, you can use the function neural_splines.eval_model_on_grid. NOTE: neural_splines.eval_model_on_grid can also accept other optional arguments, run help(neural_splines.eval_model_on_grid) for details.

from neural_splines import eval_model_on_grid

# Assume model is a Neural Spline fitted with fit_model_to_point_cloud

# Bounding box of the point cloud x represented as a tuple (origin, size)
bbox = x.min(0)[0], x.max(0)[0] - x.min(0)[0]
grid_res = torch.tensor([128, 128, 128]).to(torch.int32)

recon = eval_model_on_grid(model, bbox, voxel_grid_size)  # a [128, 128, 128] shaped tensor representing the neural spline evaluated on a grid.
Owner
Francis Williams
I am a PhD student in the Math and Data Group and the Geometric Computing Lab at NYU advised by Joan Bruna and Denis Zorin.
Francis Williams
[NeurIPS 2020] This project provides a strong single-stage baseline for Long-Tailed Classification, Detection, and Instance Segmentation (LVIS).

A Strong Single-Stage Baseline for Long-Tailed Problems This project provides a strong single-stage baseline for Long-Tailed Classification (under Ima

Kaihua Tang 514 Dec 23, 2022
Official Pytorch implementation of MixMo framework

MixMo: Mixing Multiple Inputs for Multiple Outputs via Deep Subnetworks Official PyTorch implementation of the MixMo framework | paper | docs Alexandr

79 Nov 07, 2022
Deep deconfounded recommender (Deep-Deconf) for paper "Deep causal reasoning for recommendations"

Deep Causal Reasoning for Recommender Systems The codes are associated with the following paper: Deep Causal Reasoning for Recommendations, Yaochen Zh

Yaochen Zhu 22 Oct 15, 2022
Real-time face detection and emotion/gender classification using fer2013/imdb datasets with a keras CNN model and openCV.

Real-time face detection and emotion/gender classification using fer2013/imdb datasets with a keras CNN model and openCV.

Octavio Arriaga 5.3k Dec 30, 2022
Project Tugas Besar pertama Pengenalan Komputasi Institut Teknologi Bandung

Vending_Machine_(Mesin_Penjual_Minuman) Project Tugas Besar pertama Pengenalan Komputasi Institut Teknologi Bandung Raw Sketch untuk Essay Ringkasan P

QueenLy 1 Nov 08, 2021
Catalyst.Detection

Accelerated DL R&D PyTorch framework for Deep Learning research and development. It was developed with a focus on reproducibility, fast experimentatio

Catalyst-Team 12 Oct 25, 2021
MiniSom is a minimalistic implementation of the Self Organizing Maps

MiniSom Self Organizing Maps MiniSom is a minimalistic and Numpy based implementation of the Self Organizing Maps (SOM). SOM is a type of Artificial N

Giuseppe Vettigli 1.2k Jan 03, 2023
The code uses SegFormer for Semantic Segmentation on Drone Dataset.

SegFormer_Segmentation The code uses SegFormer for Semantic Segmentation on Drone Dataset. The details for the SegFormer can be obtained from the foll

Dr. Sander Ali Khowaja 1 May 08, 2022
TSP: Temporally-Sensitive Pretraining of Video Encoders for Localization Tasks

TSP: Temporally-Sensitive Pretraining of Video Encoders for Localization Tasks [Paper] [Project Website] This repository holds the source code, pretra

Humam Alwassel 83 Dec 21, 2022
It is an open dataset for object detection in remote sensing images.

RSOD-Dataset It is an open dataset for object detection in remote sensing images. The dataset includes aircraft, oiltank, playground and overpass. The

136 Dec 08, 2022
Official page of Struct-MDC (RA-L'22 with IROS'22 option); Depth completion from Visual-SLAM using point & line features

Struct-MDC (click the above buttons for redirection!) Official page of "Struct-MDC: Mesh-Refined Unsupervised Depth Completion Leveraging Structural R

Urban Robotics Lab. @ KAIST 37 Dec 22, 2022
Pytorch implementation of Each Part Matters: Local Patterns Facilitate Cross-view Geo-localization https://arxiv.org/abs/2008.11646

[TCSVT] Each Part Matters: Local Patterns Facilitate Cross-view Geo-localization LPN [Paper] NEWs Prerequisites Python 3.6 GPU Memory = 8G Numpy 1.

46 Dec 14, 2022
CVPR2021: Temporal Context Aggregation Network for Temporal Action Proposal Refinement

Temporal Context Aggregation Network - Pytorch This repo holds the pytorch-version codes of paper: "Temporal Context Aggregation Network for Temporal

Zhiwu Qing 63 Sep 27, 2022
PyTorch implementation of Octave Convolution with pre-trained Oct-ResNet and Oct-MobileNet models

octconv.pytorch PyTorch implementation of Octave Convolution in Drop an Octave: Reducing Spatial Redundancy in Convolutional Neural Networks with Octa

Duo Li 273 Dec 18, 2022
PrimitiveNet: Primitive Instance Segmentation with Local Primitive Embedding under Adversarial Metric (ICCV 2021)

PrimitiveNet Source code for the paper: Jingwei Huang, Yanfeng Zhang, Mingwei Sun. [PrimitiveNet: Primitive Instance Segmentation with Local Primitive

Jingwei Huang 47 Dec 06, 2022
LeetCode Solutions https://t.me/tenvlad

leetcode LeetCode Solutions groupped by common patterns YouTube: https://www.youtube.com/c/vladten Telegram: https://t.me/nilinterface Problems source

Vlad Ten 158 Dec 29, 2022
Adversarial Framework for (non-) Parametric Image Stylisation Mosaics

Fully Adversarial Mosaics (FAMOS) Pytorch implementation of the paper "Copy the Old or Paint Anew? An Adversarial Framework for (non-) Parametric Imag

Zalando Research 120 Dec 24, 2022
Implementation of Multistream Transformers in Pytorch

Multistream Transformers Implementation of Multistream Transformers in Pytorch. This repository deviates slightly from the paper, where instead of usi

Phil Wang 47 Jul 26, 2022
Torchlight2 lan game server tool - A message forwarding tool for Torchlight 2 lan game

Torchlight 2 Lan Game Server Tool A message forwarding tool for Torchlight 2 lan

Huaijun Jiang 3 Nov 01, 2022
An official source code for "Augmentation-Free Self-Supervised Learning on Graphs"

Augmentation-Free Self-Supervised Learning on Graphs An official source code for Augmentation-Free Self-Supervised Learning on Graphs paper, accepted

Namkyeong Lee 59 Dec 01, 2022