Neural Point-Based Graphics

Overview

Neural Point-Based Graphics

Project Video Paper

Neural Point-Based Graphics
Kara-Ali Aliev1   Artem Sevastopolsky1,2   Maria Kolos1,2   Dmitry Ulyanov3   Victor Lempitsky1,2
1Samsung AI Center   1Skolkovo Institute of Science and Technology   3in3d.io

UPD (09.02.2021): added a Docker container which can be executed on a headless node. See Docker Readme.

About

This is PyTorch implementation of Neural Point-Based Graphics (NPBG), a new method for realtime photo-realistic rendering of real scenes. NPBG uses a raw point cloud as the geometric representation of a scene, and augments each point with a learnable neural descriptor that encodes local geometry and appearance. A deep rendering network is learned in parallel with the descriptors, so that new views of the scene can be obtained by passing the rasterizations of a point cloud from new viewpoints through this network.

Setup

The following instructions describe installation of conda environment. If you wish to setup the Docker environment, see the Readme in the docker folder. This way is also recommended for headless machines (without X server enabled).

Run this command to install python environment using conda:

source scripts/install_deps.sh

Run

You can render one of the fitted scenes we provide right away in the real-time viewer or fit your own scene.

Download fitted scenes and universal rendering network weights from here and unpack in the sources root directory.

We suppose that you have at least one GeForce GTX 1080 Ti for fitting and inference.

Viewer navigation:

  • Rotation: press left mouse button and drag
  • Move: press rigth mouse button and drug / scroll middle mouse botton
  • Pan: press middle mouse button and drug

Use fitted scene

Here we show a couple of examples how to run fitted scenes in the viewer.

Person 1

python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view

Since this scene was fitted on 4k images, we crop image size with --viewport argument to fit the scene into memory of a modest GPU.

Studio

python viewer.py --config downloads/studio.yaml --rmode fly

Check downloads directory for more examples.

Fit your scene

Fitting a new scene consists of two steps:

  1. Point cloud reconstruction
  2. Fitting descriptors

There is a bunch of software for point cloud reconstruction. While it is possible to adopt different software packages for our pipeline, we will choose Agisoft Metashape for this demonstration.

Point cloud reconstruction (Agisoft Metashape)

If you don't have a license for Agisoft Metashape Pro, start a trial version by filling in the form. On the first start, enter you license key.

Download and install Agisoft Metashape:

wget http://download.agisoft.com/metashape-pro_1_6_2_amd64.tar.gz
tar xvf metashape-pro_1_6_2_amd64.tar.gz
cd metashape-pro
LD_LIBRARY_PATH="python/lib:$LD_LIBRARY_PATH" ./python/bin/python3.5 -m pip install pillow
bash metashape.sh

Optionally, enable GPU acceleration by checking Tools -> Preferences -> GPU.

Depending on the specs of your PC you may need to downscale your images to proper size. We recommend using 4k images or less. For example, if you want to downscale images by a factor of two, run this command:

# convert comes with imagemagick package
# sudo apt install imagemagick

# in images directory
for fn in *jpg; do convert $fn -resize 50% $fn; done

Build point cloud:

bash metashape.sh -r <npbg>/scripts/metashape_build_cloud.py <my_scene>

where <npbg> is the path to NPBG sources, <my_scene> is directory with images subdirectory with your scene images.

The script will produce:

  • point_cloud.ply: dense point cloud
  • cameras.xml: camera registration data
  • images_undistorted: undistorted images for descriptor fitting
  • project.psz: Metashape project
  • scene.yaml: scene configuration for the NPBG viewer

Make sure the point cloud has no severe misalignments and crop out unnecessary geometry to optimize memory consumption. To edit a scene, open project.psz in Metashape GUI and export modified point cloud (File -> Export -> Export Points). See Issues section for further recommendations.

Now we can fit descriptors for this scene.

Fitting descriptors

Modify configs/paths_example.yaml by setting absolute paths to scene configuration file, target images and, optionally, masks. Add other scenes to this file if needed.

Fit the scene:

python train.py --config configs/train_example.yaml --pipeline npbg.pipelines.ogl.TexturePipeline --dataset_names <scene_name>

where <scene_name> is the name of the scene in paths_example.yaml. Model checkpoints and Tensorboard logs will be stored in data/logs.

The command above will finetune weights of the rendering network. This regime usually produces more appealing results. To freeze the rendering network, use option --freeze_net. We provide pretrained weights for the rendering network on ScanNet and People dataset located in downloads/weights. Set pretrained network using net_ckpt option in train_example.yaml.

If you have masks for target images, use option '--use_masks'. Make sure masks align with target images.

When the model converge (usually 10 epochs is enough), run the scene in the viewer:

python viewer.py --config <my_scene>.yaml --checkpoint data/logs/<experiment>/checkpoints/<PointTexture>.pth --origin-view

where <my_scene>.yaml is the scene configuration file created in the point cloud reconstruction stage, --checkpoint is the path to descriptors checkpoint and --origin-view option automatically moves geometry origin to the world origin for convenient navigation. You can manually assign model3d_origin field in <my_scene>.yaml for arbitrary origin transformation (see downloads/person_1.yaml for example).

Guidelines for fitting novel scenes

Fitting novel scenes can sometimes be tricky, most often due to the preparation of camera poses that are provided in different ways by different sources, or sometimes because of the reconstruction issues (see below). We recommend checking out this and this issues for detailed explanations.

The most important insight is related to the configs structure. There is a system of 3 configs used in NPBG:

(there is another optional config -- inference config, which is essentially a scene config with net_ckpt and texture_ckpt parameters: paths to the network weights checkpoint and a descriptors checkpoint, respectively)

To fit a new scene, one should a scene config configs/my_scene_name.yaml and a path config configs/my_scene_paths.yaml by setting absolute paths to scene configuration file, target images, and other optional parameters, such as masks. Path config can contain paths to images of either 1 scene or several scenes, if needed. Examples of all configs of all types can be found in the repository.

Code logic and structure

Since our repository is based on a custom, specific framework, we leave the following diagram with the basic code logic. For those who wish to extend our code with additional features or try out related ideas (which we would highly appreciate), this diagram should help finding where the changes should be applied in the code. At the same time, various technical intricacies are not shown here for the sake of clarity.

Issues

  • Reconstruction failure and geometry misalignment. Taking photos for photogrammetry is the most critical part in the whole pipeline. Follow these recommendations to have a good reconstruction:

    • Set the highest quality in the camera settings;
    • Keep the object in focus, don't set f-stop too low;
    • Fix shutter speed, the faster the better, but don't underexpose the photo;
    • Photos must be bright enough, but don't overexpose the photo;
    • Keep ISO low enough as it may introduce noise;
    • Keep the objects still, remove moving parts from the scene;
    • Take photos with at least 70% overlap;
    • If possible, use soft diffused light;
    • Avoid dark shadows;

    If you are using a smarthone with Android, OpenCamera may come handy. A good starting point for settings is f/8, ISO 300, shutter speed 1/125s. iPhone users are recommended to fix exposure in the Camera. Follow this guide for more recommendations.

  • Viewer performance. If Pytorch and X server run on different GPUs there will be extra data transfer overhead between two GPUs. If higher framerate is desirable, make sure they run on the same GPU (use CUDA_VISIBLE_DEVICES).

  • Pytorch crash on train. there is a known issue when Pytorch crashes on backward pass if there are different GPUs, f.e. GeForce GTX 1080 Ti and GeForce RTX 2080 Ti. Use CUDA_VISIBLE_DEVICES to mask GPU.

TODOs

This is what we want to implement as well. We would also highly appreciate the help from the community.

  • Point cloud reconstruction with COLMAP. As Agisoft Metashape is a proprietary software, the community would most benefit from an open source package like COLMAP which has almost the same functionality as Metashape, so the goal is to have colmap_build_cloud.py script working in the same manner as metashape_build_cloud.py.
  • Convenient viewer navigation. Interactively choosing rotation center would make navigation much more conveniet. At the moment the viewer either explicitly imports the model's origin matrix or sets the origin automatically based on point cloud density.

Citation

@article{Аliev2020,
    title={Neural Point-Based Graphics},
    author={Kara-Ali Aliev and Artem Sevastopolsky and Maria Kolos and Dmitry Ulyanov and Victor Lempitsky},
    year={2020},
    eprint={1906.08240v3},
    archivePrefix={arXiv},
    primaryClass={cs.CV}
}
Comments
  • How to fit scenes from other datasets

    How to fit scenes from other datasets

    Hi guys,

    I would be interested to know whether it is possible to fit different scenes based on other existing datasets. For example I would like to understand and get an idea how to fit the redwood dataset (http://redwood-data.org/). I have read the README regarding how to fit our own scenes but it is not clear to me how to do the same with the e.g. the redwood data.

    Thus, would be easy to give some feedback here how to do that.

    Thanks.

    good first issue 
    opened by ttsesm 20
  • The result doesn't show any color

    The result doesn't show any color

    Hi I printed a trained data of epoch 20 by using viewer.py, but there's an issue As shown in the image below, it doesn't have any color I think there should be something wrong with the process of fitting descriptor Is there any solution for this? Thanks.

    그림1 그림2 그림3

    opened by KimMingyeol 5
  • problem running the example

    problem running the example

    Hi,

    I am trying to run the example code from the readme file but I am getting the following error:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    loading pointcloud...
    Traceback (most recent call last):
      File "viewer.py", line 434, in <module>
        my_app = MyApp(args)
      File "viewer.py", line 112, in __init__
        self.scene_data = load_scene_data(args.config)
      File "/home/ttsesm/Development/npbg/npbg/gl/utils.py", line 263, in load_scene_data
        pointcloud = import_model3d(fix_relative_path(config['pointcloud'], path))
      File "/home/ttsesm/Development/npbg/npbg/gl/utils.py", line 431, in import_model3d
        model['rgb'] = data.colors[0][:, :3] / 255.
    IndexError: too many indices for array
    

    any idea what could be the cause?

    opened by ttsesm 5
  • The viewer's results were not as good as the training

    The viewer's results were not as good as the training

    Hi, thanks for the good work. When I trained the scene, the PSNR was up to 25, which was clear to see on the Tensorboard. Why is it not as good as the one seen in the viewer during training, and the PSNR obtained is less than 20? (the same pose and point cloud) Does the viewer have any tricks to save the image and reduce distortion?

    opened by JOP-Lee 4
  • Scene.program is None

    Scene.program is None

    Hi, I am trying to fit a scene and I have a problem with the dataloader. At the second epoch, even though the dataset is loaded, the scene.program seems to be None. Do you have an idea on where could the problem ?

    Here is error message :

    EPOCH 1

    TRAIN EVAL MODE IN TRAIN model parameters: 1928771 running on datasets [0] proj_matrix was not set total parameters: 76715531 Traceback (most recent call last): File "train.py", line 517, in train_loss = run_train(epoch, pipeline, args, iter_cb) File "train.py", line 253, in run_train return run_epoch(pipeline, 'train', epoch, args, iter_cb=iter_cb) File "train.py", line 228, in run_epoch run_sub(dl, extra_optimizer) File "train.py", line 118, in run_sub for it, data in enumerate(dl): File "C:\Users\user.conda\envs\npbg\lib\site-packages\torch\utils\data\dataloader.py", line 517, in next data = self._next_data() File "C:\Users\user.conda\envs\npbg\lib\site-packages\torch\utils\data\dataloader.py", line 557, in _next_data data = self.dataset_fetcher.fetch(index) # may raise StopIteration File "C:\Users\user.conda\envs\npbg\lib\site-packages\torch\utils\data_utils\fetch.py", line 44, in fetch data = [self.dataset[idx] for idx in possibly_batched_index] File "C:\Users\user.conda\envs\npbg\lib\site-packages\torch\utils\data_utils\fetch.py", line 44, in data = [self.dataset[idx] for idx in possibly_batched_index] File "C:\Users\user.conda\envs\npbg\lib\site-packages\torch\utils\data\dataset.py", line 219, in getitem return self.datasets[dataset_idx][sample_idx] File "C:\Users\user\Documents\npbg\npbg\datasets\dynamic.py", line 246, in getitem input = self.renderer.render(view_matrix=view_matrix, proj_matrix=proj_matrix) File "C:\Users\user\Documents\npbg\npbg\datasets\dynamic.py", line 68, in render self.scene.set_camera_view(view_matrix) File "C:\Users\user\Documents\npbg\npbg\gl\programs.py", line 366, in set_camera_view self.program['m_view'] = inv(m).T

    opened by chekirou 4
  • About inference

    About inference

    Hello, thank you for your excellent work and the open-source code! I have finetuned your pre-trained model, however, I can not find the way about inference. I saw inference related settings in your config files, but I can’t use them correctly. Thank you for your reply!

    opened by Sylvia6 4
  • Why can't directly use .ply file provided by Scannet Dataset

    Why can't directly use .ply file provided by Scannet Dataset

    Hello, thank you for your excellent work and the open source code! Following the guild in readme, I can successfully fit a new scene by building the reconstruction with Agisoft Metashape Pro and then fitting descriptors. However, when I directly use the reconstructions (eg. http://kaldir.vc.in.tum.de/scannet/v2/scans/scene0001_01/scene0000_00_vh_clean.ply) provided in ScanNet dataset, I found that I can not fitting descriptors correctlly then. Are there some differences between the pointcloud built by Agisoft Metashape Pro and the pointcloud provided by ScanNet dataset? And how can I fit a scene in Scannet dataset such as scene0000_00 with the pointcloud provided by ScanNet dataset? Thank you for your reply!

    opened by ousuixin 4
  • unable to load numpy_formathandler accelerator from OpenGL_accelerate

    unable to load numpy_formathandler accelerator from OpenGL_accelerate

    Hi, currently testing the code with sample data but there seems to be an error loading numpy_formathandler accelerator. After calling python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view, the view.py window freezes with above error. I can't figure out what's wrong here. Any idea? Thanks!

    Screenshot from 2020-12-31 04-22-42

    opened by alex4727 3
  • How to fit on a ScanNet scene?

    How to fit on a ScanNet scene?

    Each ScanNet scene contains RGB-D images, so I can project 2D pixels to 3D point cloud and save them to a .ply file. But how to modify path_example.yaml and train_example.yaml to fit the descriptors on this ply file?

    Any guidelines or suggestions?

    good first issue 
    opened by BostonLobster 3
  • Multi-GPU support for training?

    Multi-GPU support for training?

    I try to train a large-scale scene with large number of point clouds. But I received a CUDA out of memory error at the start of training.

    Is there any way to train the model on Multi-GPUs?

    opened by Yurri-hub 2
  • Viewer renders only a triangular half of the texture

    Viewer renders only a triangular half of the texture

    Because I possess an AMD GPU rather than an NVIDIA, CUDA-supporting one, I've replaced pytorch with pytorch-directml and offloaded unsupported function calls to the CPU while doing most of the work on the GPU. However, despite having modified no viewer code, it seems to render half of the image in a skewed triangle transposed across the diagonal.

    Does anyone know why this is?

    NOTE: I used the numpy-based viewer pasted here and my own fork here.

    image

    opened by jadenPete 2
  • How to render one of the fitted scenes on Ubuntu 22.04 LTS: A comprehensive guide.

    How to render one of the fitted scenes on Ubuntu 22.04 LTS: A comprehensive guide.

    I've managed to render several of the fitted scenes on Ubuntu 22.04 LTS, with an NVIDIA GeForce 940MX GPU (2 GB RAM). However, I faced several challenges while doing so. Therefore, I am going to document these challenges with their solutions here in case someone finds them helpful.

    Note: this guide was written based on commit 5bc6f8d18e61978f167f7dbb21787771fbd59bf6.

    Step 0

    Before starting, make sure you have gcc and OpenGL tools installed. Installing these will save you from dealing with a lot of problems later. This can be done by running:

    $ sudo apt update
    $ sudo apt install build-essential # gcc
    $ sudo apt-get install libglu1-mesa-dev freeglut3-dev mesa-common-dev libglfw3-dev # OpenGL
    

    More details on how to install OpenGL can be found here.

    Next, make sure you have an appropriate NVIDIA driver installed, and that you have CUDA installed. These can be installed via a quick google search.

    Finally, make sure you have Anaconda installed.

    Step 1

    Clone the repository

    git clone https://github.com/alievk/npbg.git
    

    then run install_deps.sh

    cd npbg
    source scripts/install_deps.sh
    

    Step 2

    Download the fitted scenes and the rendering network weights as described here. Place the downloads folder in the root directory (where the README.md file is located).

    Step 3

    As described in the README.md file, try running the Person 1 fitted scene:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    

    This will likely not work, and you will observe an AttributeError:

    Traceback (most recent call last):
      File "viewer.py", line 9, in <module>
        from npbg.gl.render import OffscreenRender, create_shared_texture, cpy_tensor_to_buffer, cpy_tensor_to_texture
      File "/home/mhdadk/Documents/npbg2/npbg/gl/render.py", line 14, in <module>
        import torch
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/__init__.py", line 280, in <module>
        from .functional import *
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/functional.py", line 2, in <module>
        import torch.nn.functional as F
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/__init__.py", line 1, in <module>
        from .modules import *  # noqa: F401
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/__init__.py", line 2, in <module>
        from .linear import Identity, Linear, Bilinear
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/linear.py", line 5, in <module>
        from .. import functional as F
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/functional.py", line 14, in <module>
        from .._jit_internal import boolean_dispatch, List
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/_jit_internal.py", line 595, in <module>
        import typing_extensions
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/typing_extensions-4.2.0-py3.6.egg/typing_extensions.py", line 159, in <module>
        class _FinalForm(typing._SpecialForm, _root=True):
    AttributeError: module 'typing' has no attribute '_SpecialForm'
    

    To fix this AttributeError, run

    $ pip uninstall typing-extensions
    $ pip install typing-extensions
    

    Try to run the Person 1 fitted scene again:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    

    However, this will not work again, and you will observe the following error:

    Traceback (most recent call last):
      File "viewer.py", line 434, in <module>
        my_app = MyApp(args)
      File "viewer.py", line 103, in __init__
        _config = yaml.load(f)
    TypeError: load() missing 1 required positional argument: 'Loader'
    

    The solution to this error can be found here. To fix this error, run

    $ pip install pyyaml==5.4.1
    

    Again, try to run the Person 1 fitted scene:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    

    Unfortunately, this will still throw an error:

    loading pointcloud...
    === 3D model ===
    VERTICES:  3072078
    EXTENT:  [-16.5258255  -14.02860832 -30.76384926] [ 10.81384468   2.03398347 -20.07631493]
    ================
    new viewport size  (2000, 1328)
    libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: cannot open shared object file: No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
    libGL error: failed to load driver: iris
    libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: cannot open shared object file: No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
    libGL error: failed to load driver: iris
    libGL error: MESA-LOADER: failed to open swrast: /usr/lib/dri/swrast_dri.so: cannot open shared object file: No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
    libGL error: failed to load driver: swrast
    [w] b'GLX: Failed to create context: GLXBadFBConfig'
    [x] Window creation failed
    

    The solution to this error can be found in this answer. To fix this error, run

    $ export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6
    

    One more time: try to run the Person 1 fitted scene:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    

    Still not quite there yet. You will observe the following error:

    loading pointcloud...
    === 3D model ===
    VERTICES:  3072078
    EXTENT:  [-16.5258255  -14.02860832 -30.76384926] [ 10.81384468   2.03398347 -20.07631493]
    ================
    new viewport size  (2000, 1328)
    [i] HiDPI detected, fixing window size
    [w] Cannot read STENCIL size from the framebuffer
    Unable to load numpy_formathandler accelerator from OpenGL_accelerate
    [i] Using GLFW (GL 4.6)
    Traceback (most recent call last):
      File "/home/mhdadk/Documents/npbg2/npbg/gl/render.py", line 29, in _init_buffers
        import pycuda.gl.autoinit  # this may fails in headless mode
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/pycuda-2021.1-py3.6-linux-x86_64.egg/pycuda/gl/autoinit.py", line 10, in <module>
        context = make_default_context(lambda dev: cudagl.make_context(dev))
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/pycuda-2021.1-py3.6-linux-x86_64.egg/pycuda/tools.py", line 228, in make_default_context
        "on any of the %d detected devices" % ndevices
    RuntimeError: make_default_context() wasn't able to create a context on any of the 1 detected devices
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "viewer.py", line 434, in <module>
        my_app = MyApp(args)
      File "viewer.py", line 177, in __init__
        clear_color=args.clear_color)
      File "/home/mhdadk/Documents/npbg2/npbg/gl/render.py", line 19, in __init__
        self._init_buffers(viewport_size, out_buffer_location)
      File "/home/mhdadk/Documents/npbg2/npbg/gl/render.py", line 31, in _init_buffers
        raise RuntimeError('PyCUDA init failed, cannot use torch buffer')
    RuntimeError: PyCUDA init failed, cannot use torch buffer
    

    The solution to this RuntimeError can be found in issue #12. To fix this error, replace the code in viewer.py with the code given in the gist in this reply. In other words, here is the code to put into viewer.py:

    import argparse
    import threading
    import yaml
    import re
    
    from glumpy import app, gloo, glm, gl, transforms
    from glumpy.ext import glfw
    
    from npbg.gl.render import OffscreenRender, create_shared_texture, cpy_tensor_to_buffer, cpy_tensor_to_texture
    from npbg.gl.programs import NNScene
    from npbg.gl.utils import load_scene_data, get_proj_matrix, crop_intrinsic_matrix, crop_proj_matrix, \
        setup_scene, rescale_K, FastRand, nearest_train, pca_color, extrinsics_from_view_matrix, extrinsics_from_xml
    from npbg.gl.nn import OGL
    from npbg.gl.camera import Trackball
    
    import os, sys
    import time
    import numpy as np
    import torch
    import cv2
    
    
    def get_args():
        parser = argparse.ArgumentParser(description='')
        parser.add_argument('-c', '--config', type=str, default=None, required=True, help='config path')
        parser.add_argument('--viewport', type=str, default='', help='width,height')
        parser.add_argument('--keep-fov', action='store_true', help='keep field of view when resizing viewport')
        parser.add_argument('--init-view', type=str, help='camera label for initial view or path to 4x4 matrix')
        parser.add_argument('--use-mesh', action='store_true')
        parser.add_argument('--use-texture', action='store_true')
        parser.add_argument('--rmode', choices=['trackball', 'fly'], default='trackball')
        parser.add_argument('--fps', action='store_true', help='show fps')
        parser.add_argument('--light-position', type=str, default='', help='x,y,z')
        parser.add_argument('--replay-camera', type=str, default='', help='path to view_matrix to replay at given fps')
        parser.add_argument('--replay-fps', type=float, default=25., help='view_matrix replay fps')
        parser.add_argument('--supersampling', type=int, default=1, choices=[1, 2])
        parser.add_argument('--clear-color', type=str)
        parser.add_argument('--nearest-train', action='store_true')
        parser.add_argument('--gt', help='like /path/to/images/*.JPG. * will be replaced with nearest camera label.')
        parser.add_argument('--pca', action='store_true')
        parser.add_argument('--origin-view', action='store_true')
        parser.add_argument('--temp-avg', action='store_true')
        parser.add_argument('--checkpoint')
        args = parser.parse_args()
    
        args.viewport = tuple([int(x) for x in args.viewport.split(',')]) if args.viewport else None
        args.light_position = [float(x) for x in args.light_position.split(',')] if args.light_position else None
        args.clear_color = [float(x) for x in args.clear_color.split(',')] if args.clear_color else None
    
        return args
    
    
    def get_screen_program(texture):
        vertex = '''
        attribute vec2 position;
        attribute vec2 texcoord;
        varying vec2 v_texcoord;
        void main()
        {
            gl_Position = <transform>;
            v_texcoord = texcoord;
        } '''
        fragment = '''
        uniform sampler2D texture;
        varying vec2 v_texcoord;
        void main()
        {
            gl_FragColor = texture2D(texture, v_texcoord);
        } '''
    
        quad = gloo.Program(vertex, fragment, count=4)
        quad["transform"] = transforms.OrthographicProjection(transforms.Position("position"))
        quad['texcoord'] = [( 0, 0), ( 0, 1), ( 1, 0), ( 1, 1)]
        quad['texture'] = texture
    
        return quad
    
    
    def start_fps_job():
        def job():
            print(f'FPS {app.clock.get_fps():.1f}')
    
        threading.Timer(1.0, job).start()
    
    
    def load_camera_trajectory(path):
        if path[-3:] == 'xml':
            view_matrix, camera_labels = extrinsics_from_xml(path)
        else:
            view_matrix, camera_labels = extrinsics_from_view_matrix(path)
        return view_matrix
    
    
    def fix_viewport_size(viewport_size, factor=16):
        viewport_w = factor * (viewport_size[0] // factor)
        viewport_h = factor * (viewport_size[1] // factor)
        return viewport_w, viewport_h
    
    
    class MyApp():
        def __init__(self, args):
            with open(args.config) as f:
                _config = yaml.load(f)
                # support two types of configs
                # 1 type - config with scene data
                # 2 type - config with model checkpoints and path to scene data config
                if 'scene' in _config: # 1 type
                    self.scene_data = load_scene_data(_config['scene'])
                    net_ckpt = _config.get('net_ckpt')
                    texture_ckpt = _config.get('texture_ckpt') 
                else:
                    self.scene_data = load_scene_data(args.config)
                    net_ckpt = self.scene_data['config'].get('net_ckpt')
                    texture_ckpt = self.scene_data['config'].get('texture_ckpt')
    
            self.viewport_size = args.viewport if args.viewport else self.scene_data['config']['viewport_size']
            self.viewport_size = fix_viewport_size(self.viewport_size)
            print('new viewport size ', self.viewport_size)
    
            # crop/resize viewport
            if self.scene_data['intrinsic_matrix'] is not None:
                K_src = self.scene_data['intrinsic_matrix']
                old_size = self.scene_data['config']['viewport_size']
                sx = self.viewport_size[0] / old_size[0]
                sy = self.viewport_size[1] / old_size[1]
                K_crop = rescale_K(K_src, sx, sy, keep_fov=args.keep_fov)
                self.scene_data['proj_matrix'] = get_proj_matrix(K_crop, self.viewport_size)
            elif self.scene_data['proj_matrix'] is not None:
                new_proj_matrix = crop_proj_matrix(self.scene_data['proj_matrix'], *self.scene_data['config']['viewport_size'], *self.viewport_size)
                self.scene_data['proj_matrix'] = new_proj_matrix
            else:
                raise Exception('no intrinsics are provided')
    
            if args.init_view:
                if args.init_view in self.scene_data['view_matrix']:
                    idx = self.scene_data['camera_labels'].index(args.init_view)
                    init_view = self.scene_data['view_matrix'][idx]
                elif os.path.exists(args.init_view):
                    init_view = np.loadtxt(args.init_view)
            else:
                init_view = self.scene_data['view_matrix'][0]
    
            if args.origin_view:
                top_view = np.eye(4)
                top_view[2, 3] = 20.
                init_view = top_view
    
                if np.allclose(self.scene_data['model3d_origin'], np.eye(4)):
                    print('Setting origin as mass center')
                    origin = np.eye(4)
                    origin[:3, 3] = -np.percentile(self.scene_data['pointcloud']['xyz'], 90, 0)
                    self.scene_data['model3d_origin'] = origin
            else:
                # force identity origin
                self.scene_data['model3d_origin'] = np.eye(4)
    
            self.trackball = Trackball(init_view, self.viewport_size, 1, rotation_mode=args.rmode)
    
            args.use_mesh = args.use_mesh or _config.get('use_mesh') or args.use_texture
    
            # this also creates GL context necessary for setting up shaders
            self.window = app.Window(width=self.viewport_size[0], height=self.viewport_size[1], visible=True, fullscreen=False)
            self.window.set_size(*self.viewport_size)
    
            if args.checkpoint:
                assert 'Texture' in args.checkpoint, 'Set path to descriptors checkpoint'
                ep = re.search('epoch_[0-9]+', args.checkpoint).group().split('_')[-1]
                net_name = f'UNet_stage_0_epoch_{ep}_net.pth'
                net_ckpt = os.path.join(*args.checkpoint.split('/')[:-1], net_name)
                texture_ckpt = args.checkpoint
    
            need_neural_render = net_ckpt is not None
    
            # self.out_buffer_location = 'torch' if need_neural_render else 'opengl'
            self.out_buffer_location = 'numpy' if need_neural_render else 'opengl'
    
            # setup screen image plane
            self.off_render = OffscreenRender(viewport_size=self.viewport_size, out_buffer_location=self.out_buffer_location,
                                              clear_color=args.clear_color)
            if self.out_buffer_location == 'torch':
                screen_tex, self.screen_tex_cuda = create_shared_texture(
                    np.zeros((self.viewport_size[1], self.viewport_size[0], 4), np.float32)
                )
            else:
                screen_tex, self.screen_tex_cuda = self.off_render.color_buf, None
    
                gl_view = screen_tex.view(gloo.TextureFloat2D)
                gl_view.activate() # force gloo to create on GPU
                gl_view.deactivate()
                screen_tex = gl_view
            
            self.screen_program = get_screen_program(screen_tex)
    
            self.scene = NNScene()
    
            if need_neural_render:
                print(f'Net checkpoint: {net_ckpt}')
                print(f'Texture checkpoint: {texture_ckpt}')
                self.model = OGL(self.scene, self.scene_data, self.viewport_size, net_ckpt, 
                    texture_ckpt, out_buffer_location=self.out_buffer_location, supersampling=args.supersampling, temporal_average=args.temp_avg)
            else:
                self.model = None
    
            if args.pca:
                assert texture_ckpt
                tex = torch.load(texture_ckpt, map_location='cpu')['state_dict']['texture_']
                print('PCA...')
                pca = pca_color(tex)
                pca = (pca - np.percentile(pca, 10)) / (np.percentile(pca, 90) - np.percentile(pca, 10))
                pca = np.clip(pca, 0, 1)
                self.scene_data['pointcloud']['rgb'] = np.clip(pca, 0, 1)
    
            setup_scene(self.scene, self.scene_data, args.use_mesh, args.use_texture)
            if args.light_position is not None:
                self.scene.set_light_position(args.light_position)
    
            if args.replay_camera:
                self.camera_trajectory = load_camera_trajectory(args.replay_camera)
            else:
                self.camera_trajectory = None
    
            self.window.attach(self.screen_program['transform'])
            self.window.push_handlers(on_init=self.on_init)
            self.window.push_handlers(on_close=self.on_close)
            self.window.push_handlers(on_draw=self.on_draw)
            self.window.push_handlers(on_resize=self.on_resize)
            self.window.push_handlers(on_key_press=self.on_key_press)
            self.window.push_handlers(on_mouse_press=self.on_mouse_press)
            self.window.push_handlers(on_mouse_drag=self.on_mouse_drag)
            self.window.push_handlers(on_mouse_release=self.on_mouse_release)
            self.window.push_handlers(on_mouse_scroll=self.on_mouse_scroll)
    
            self.mode0 = NNScene.MODE_COLOR
            self.mode1 = 0
            self.point_size = 1
            self.point_mode = False
            self.draw_points = not args.use_mesh
            self.flat_color = True
            self.neural_render = need_neural_render
            self.show_pca = False
    
            self.n_frame = 0
            self.t_elapsed = 0
            self.last_frame = None
            self.last_view_matrix = None
            self.last_gt_image = None
    
            self.mouse_pressed = False
    
            self.args = args
    
        def run(self):
            if self.args.fps:
                start_fps_job()
    
            app.run()
    
        def render_frame(self, view_matrix):
            self.scene.set_camera_view(view_matrix)
    
            if self.neural_render:
                frame = self.model.infer()['output'].flip([0])
            else:
                self.scene.set_mode(self.mode0, self.mode1)
                if self.point_mode == 0:
                    self.scene.set_splat_mode(False)
                    self.scene.program['splat_mode'] = int(0)
                elif self.point_mode == 1:
                    self.scene.set_splat_mode(True)
                    self.scene.program['splat_mode'] = int(0)
                elif self.point_mode == 2:
                    self.scene.set_splat_mode(False)
                    self.scene.program['splat_mode'] = int(1)
                if not self.scene.use_point_sizes:
                    self.scene.set_point_size(self.point_size)
                self.scene.set_draw_points(self.draw_points)
                self.scene.set_flat_color(self.flat_color)
                frame = self.off_render.render(self.scene)
    
            return frame
    
        def print_info(self):
            print('-- start info')
    
            mode = [m[0] for m in NNScene.__dict__.items() if m[0].startswith('MODE_') and self.mode0 == m[1]][0]
            print(mode)
    
            n_mode = [m[0] for m in NNScene.__dict__.items() if m[0].startswith('NORMALS_MODE_') and self.mode1 == m[1]][0]
            print(n_mode)
    
            print(f'point size {self.point_size}')
            print(f'splat mode: {self.point_mode}')
    
            print('-- end info')
    
        def save_screen(self, out_dir='./data/screenshots'):
            os.makedirs(out_dir, exist_ok=True)
    
            get_name = lambda s: time.strftime(f"%m-%d_%H-%M-%S___{s}")
            
            img = self.last_frame.cpu().numpy()[..., :3][::-1, :, ::-1] * 255
            cv2.imwrite(os.path.join(out_dir, get_name('screenshot') + '.png'), img)
            
            np.savetxt(os.path.join(out_dir, get_name('pose') + '.txt'), self.last_view_matrix)
    
        def get_next_view_matrix(self, frame_num, elapsed_time):
            if self.camera_trajectory is None:
                return self.trackball.pose
    
            n = int(elapsed_time * args.replay_fps) % len(self.camera_trajectory)
            return self.camera_trajectory[n]
    
        # ===== Window events =====
    
        def on_init(self):
            pass
    
        def on_key_press(self, symbol, modifiers):
            KEY_PLUS = 61
            if symbol == glfw.GLFW_KEY_X:
                self.mode0 = NNScene.MODE_XYZ
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_N:
                self.mode0 = NNScene.MODE_NORMALS
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_C:
                self.mode0 = NNScene.MODE_COLOR
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_U:
                self.mode0 = NNScene.MODE_UV
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_D:
                self.mode0 = NNScene.MODE_DEPTH
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_L:
                self.mode0 = NNScene.MODE_LABEL
                self.neural_render = False
            elif symbol == glfw.GLFW_KEY_Y:
                self.neural_render = True
                self.show_pca = False
            elif symbol == glfw.GLFW_KEY_T:
                self.neural_render = True
                self.show_pca = True
            elif symbol == glfw.GLFW_KEY_Z:
                self.mode1 = (self.mode1 + 1) % 5
            elif symbol == KEY_PLUS:
                self.point_size = self.point_size + 1
            elif symbol == glfw.GLFW_KEY_MINUS:
                self.point_size = max(0, self.point_size - 1)
            elif symbol == glfw.GLFW_KEY_P:
                self.point_mode = (self.point_mode + 1) % 3
            elif symbol == glfw.GLFW_KEY_Q:
                self.draw_points = not self.draw_points
            elif symbol == glfw.GLFW_KEY_F:
                self.flat_color = not self.flat_color
            elif symbol == glfw.GLFW_KEY_I:
                self.print_info()
            elif symbol == glfw.GLFW_KEY_S:
                self.save_screen()
            else:
                print(symbol, modifiers)
    
        def on_draw(self, dt):
            self.last_view_matrix = self.get_next_view_matrix(self.n_frame, self.t_elapsed)
    
            self.last_frame = self.render_frame(self.last_view_matrix)
    
            if self.out_buffer_location == 'torch':
                cpy_tensor_to_texture(self.last_frame, self.screen_tex_cuda)
            elif self.out_buffer_location == 'numpy':
                if isinstance(self.last_frame, torch.Tensor):
                    rendered = self.last_frame.cpu().numpy()
                elif isinstance(self.last_frame, np.ndarray):
                    rendered = self.last_frame
                
                if rendered.shape[2] == 3:
                    rendered = np.concatenate([rendered, np.ones_like(rendered[..., [0]])], axis=2)
                self.screen_program['texture'] = rendered
    
            self.window.clear()
    
            gl.glDisable(gl.GL_CULL_FACE)
    
            # ensure viewport size is correct (offline renderer could change it)
            gl.glViewport(0, 0, self.viewport_size[0], self.viewport_size[1])
    
            self.screen_program.draw(gl.GL_TRIANGLE_STRIP)
    
            self.n_frame += 1
            self.t_elapsed += dt
    
            if self.args.nearest_train:
                ni = nearest_train(self.scene_data['view_matrix'], np.linalg.inv(self.scene_data['model3d_origin']) @ self.last_view_matrix)
                label = self.scene_data['camera_labels'][ni]
                assert self.args.gt, 'you must define path to gt images'
                path = self.args.gt.replace('*', str(label))
                if not os.path.exists(path):
                    print(f'{path} NOT FOUND!')
                elif self.last_gt_image != path:
                    self.last_gt_image = path
                    img = cv2.imread(path)
                    max_side = max(img.shape[:2])
                    s = 1024 / max_side
                    img = cv2.resize(img, None, None, s, s)
                    cv2.imshow('nearest train', img)
                cv2.waitKey(1)
    
        def on_resize(self, w, h):
            print(f'on_resize {w}x{h}')
            self.trackball.resize((w, h))
            self.screen_program['position'] = [(0, 0), (0, h), (w, 0), (w, h)]
    
        def on_close(self):
            pass
    
        def on_mouse_press(self, x, y, buttons, modifiers):
            # print(buttons, modifiers)
            self.trackball.set_state(Trackball.STATE_ROTATE)
            if (buttons == app.window.mouse.LEFT):
                ctrl = (modifiers & app.window.key.MOD_CTRL)
                shift = (modifiers & app.window.key.MOD_SHIFT)
                if (ctrl and shift):
                    self.trackball.set_state(Trackball.STATE_ZOOM)
                elif ctrl:
                    self.trackball.set_state(Trackball.STATE_ROLL)
                elif shift:
                    self.trackball.set_state(Trackball.STATE_PAN)
            elif (buttons == app.window.mouse.MIDDLE):
                self.trackball.set_state(Trackball.STATE_PAN)
            elif (buttons == app.window.mouse.RIGHT):
                self.trackball.set_state(Trackball.STATE_ZOOM)
    
            self.trackball.down(np.array([x, y]))
    
            # Stop animating while using the mouse
            self.mouse_pressed = True
    
        def on_mouse_drag(self, x, y, dx, dy, buttons):
            self.trackball.drag(np.array([x, y]))
    
        def on_mouse_release(self, x, y, button, modifiers):
            self.mouse_pressed = False
    
        def on_mouse_scroll(self, x, y, dx, dy):
            self.trackball.scroll(dy)
    
    
    if __name__ == '__main__':
        args = get_args()
    
        my_app = MyApp(args)
        my_app.run()
    

    FINALLY, try to run the Person 1 fitted scene again:

    $ python viewer.py --config downloads/person_1.yaml --viewport 2000,1328 --origin-view
    

    Depending on how much RAM your GPU has, you may see a CUDA out of memory error:

    loading pointcloud...
    === 3D model ===
    VERTICES:  3072078
    EXTENT:  [-16.5258255  -14.02860832 -30.76384926] [ 10.81384468   2.03398347 -20.07631493]
    ================
    new viewport size  (2000, 1328)
    [i] HiDPI detected, fixing window size
    [w] Cannot read STENCIL size from the framebuffer
    Unable to load numpy_formathandler accelerator from OpenGL_accelerate
    [i] Using GLFW (GL 4.6)
    Net checkpoint: downloads/scenes/person_1/02-20_08-42-55/UNet_stage_0_epoch_39_net.pth
    Texture checkpoint: downloads/scenes/person_1/02-20_08-42-55/PointTexture_stage_0_epoch_39.pth
    SUPERSAMPLING: 2
    [i] Running at 60 frames/second
    on_resize 1920x1009
    Traceback (most recent call last):
      File "viewer.py", line 452, in <module>
        my_app.run()
      File "viewer.py", line 256, in run
        app.run()
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/glumpy/app/__init__.py", line 317, in run
        clock = __init__(clock=clock, framerate=framerate, backend=__backend__)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/glumpy/app/__init__.py", line 277, in __init__
        window.dispatch_event('on_resize', window._width, window._height)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/glumpy/app/window/event.py", line 396, in dispatch_event
        if getattr(self, event_type)(*args):
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/glumpy/app/window/window.py", line 221, in on_resize
        self.dispatch_event('on_draw', 0.0)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/glumpy/app/window/event.py", line 386, in dispatch_event
        if handler(*args):
      File "viewer.py", line 366, in on_draw
        self.last_frame = self.render_frame(self.last_view_matrix)
      File "viewer.py", line 262, in render_frame
        frame = self.model.infer()['output'].flip([0])
      File "/home/mhdadk/Documents/npbg2/npbg/gl/nn.py", line 121, in infer
        out, net_input = self.model(input_dict, return_input=True)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/mhdadk/Documents/npbg2/npbg/models/compose.py", line 194, in forward
        out1 = self.net(*input_multiscale, **kwargs)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/mhdadk/Documents/npbg2/npbg/models/unet.py", line 271, in forward
        up2 = self.up2(up3, down1)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/mhdadk/Documents/npbg2/npbg/models/unet.py", line 130, in forward
        output= self.conv(torch.cat([in1_up, inputs2_], 1))
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/mhdadk/Documents/npbg2/npbg/models/unet.py", line 77, in forward
        features = self.block.act_f(self.block.conv_f(x))
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/module.py", line 541, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/modules/activation.py", line 329, in forward
        return F.elu(input, self.alpha, self.inplace)
      File "/home/mhdadk/miniconda3/envs/npbg/lib/python3.6/site-packages/torch/nn/functional.py", line 992, in elu
        result = torch._C._nn.elu(input, alpha)
    RuntimeError: CUDA out of memory. Tried to allocate 82.00 MiB (GPU 0; 1.96 GiB total capacity; 1.36 GiB already allocated; 71.62 MiB free; 98.74 MiB cached)
    

    In this case, change the viewport parameter from 2000,1328 to something smaller, like 500,500:

    $ python viewer.py --config downloads/person_1.yaml --viewport 500,500 --origin-view
    

    This should now work. In case you see the message:

    "viewer.py" is not responding.
    

    This just means that it is taking some time to load the render. Click on "Wait" and the render should load soon.

    opened by mhdadk 6
  • Eval mode=True during training

    Eval mode=True during training

    Hi, thank you for the great work! I have a doubt about the code. During training, you have set eval mode to true. I'd be grateful if you could help me understand why that's so and whether there is a difference in inference results if we set the model to train mode instead.

    Thanks in advance

    opened by Shubhendu-Jena 5
  • Headless render on remote servers without Xorg?

    Headless render on remote servers without Xorg?

    Can we train the scene model on remote servers without Xorg ? By the way, I have checked the docker you provided and tested whether glfw can work fine, but still got below : image

    opened by Sylvia6 1
  • How to generate data on server ?

    How to generate data on server ?

    I try to generate data for training data on a server, but not work. I run the command:

    python generate_dataset.py --config downloads/person_1.yaml
    

    and log:

    loading pointcloud...
    === 3D model ===
    VERTICES:  3072078
    EXTENT:  [-16.5258255  -14.02860832 -30.76384926] [ 10.81384468   2.03398347 -20.07631493]
    ================
    proj_matrix was not set
    viewport size  (4000, 2656)
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [w] b'The GLFW library is not initialized'
    [x] Window creation failed
    deleting buffers...
    

    Do you have any code to generate data on servers? Thank you!

    opened by bachtx12 1
  • How to train from scratch or fine-tune with multiply scenes datasets?

    How to train from scratch or fine-tune with multiply scenes datasets?

    I want to train the model with my own dataset from scratch, and also want to fine-tune the model with 2 different scenes datasets as you did in paper about scene editing. Could you tell me how to modify the train.py or release the training code from scratch?Looking forward to your reply.Thank you.

    opened by xdiyer 12
Owner
Ali Aliev
Computer graphics
Ali Aliev
Point-NeRF: Point-based Neural Radiance Fields

Point-NeRF: Point-based Neural Radiance Fields Project Sites | Paper | Primary c

Qiangeng Xu 662 Jan 1, 2023
Style-based Point Generator with Adversarial Rendering for Point Cloud Completion (CVPR 2021)

Style-based Point Generator with Adversarial Rendering for Point Cloud Completion (CVPR 2021) An efficient PyTorch library for Point Cloud Completion.

Microsoft 119 Jan 2, 2023
Not All Points Are Equal: Learning Highly Efficient Point-based Detectors for 3D LiDAR Point Clouds (CVPR 2022, Oral)

Not All Points Are Equal: Learning Highly Efficient Point-based Detectors for 3D LiDAR Point Clouds (CVPR 2022, Oral) This is the official implementat

Yifan Zhang 259 Dec 25, 2022
HashNeRF-pytorch - Pure PyTorch Implementation of NVIDIA paper on Instant Training of Neural Graphics primitives

HashNeRF-pytorch Instant-NGP recently introduced a Multi-resolution Hash Encodin

Yash Sanjay Bhalgat 616 Jan 6, 2023
Implementation of the "PSTNet: Point Spatio-Temporal Convolution on Point Cloud Sequences" paper.

PSTNet: Point Spatio-Temporal Convolution on Point Cloud Sequences Introduction Point cloud sequences are irregular and unordered in the spatial dimen

Hehe Fan 63 Dec 9, 2022
Code for "PV-RAFT: Point-Voxel Correlation Fields for Scene Flow Estimation of Point Clouds", CVPR 2021

PV-RAFT This repository contains the PyTorch implementation for paper "PV-RAFT: Point-Voxel Correlation Fields for Scene Flow Estimation of Point Clou

Yi Wei 43 Dec 5, 2022
Implementation of the "Point 4D Transformer Networks for Spatio-Temporal Modeling in Point Cloud Videos" paper.

Point 4D Transformer Networks for Spatio-Temporal Modeling in Point Cloud Videos Introduction Point cloud videos exhibit irregularities and lack of or

Hehe Fan 101 Dec 29, 2022
Point Cloud Denoising input segmentation output raw point-cloud valid/clear fog rain de-noised Abstract Lidar sensors are frequently used in environme

Point Cloud Denoising input segmentation output raw point-cloud valid/clear fog rain de-noised Abstract Lidar sensors are frequently used in environme

null 75 Nov 24, 2022
Synthetic LiDAR sequential point cloud dataset with point-wise annotations

SynLiDAR dataset: Learning From Synthetic LiDAR Sequential Point Cloud This is official repository of the SynLiDAR dataset. For technical details, ple

null 78 Dec 27, 2022
[ICCV 2021 Oral] SnowflakeNet: Point Cloud Completion by Snowflake Point Deconvolution with Skip-Transformer

This repository contains the source code for the paper SnowflakeNet: Point Cloud Completion by Snowflake Point Deconvolution with Skip-Transformer (ICCV 2021 Oral). The project page is here.

AllenXiang 65 Dec 26, 2022
General purpose GPU compute framework for cross vendor graphics cards (AMD, Qualcomm, NVIDIA & friends)

General purpose GPU compute framework for cross vendor graphics cards (AMD, Qualcomm, NVIDIA & friends). Blazing fast, mobile-enabled, asynchronous and optimized for advanced GPU data processing usecases. Backed by the Linux Foundation.

The Kompute Project 1k Jan 6, 2023
This repository contains notebook implementations of the following Neural Process variants: Conditional Neural Processes (CNPs), Neural Processes (NPs), Attentive Neural Processes (ANPs).

The Neural Process Family This repository contains notebook implementations of the following Neural Process variants: Conditional Neural Processes (CN

DeepMind 892 Dec 28, 2022
This project is the official implementation of our accepted ICLR 2021 paper BiPointNet: Binary Neural Network for Point Clouds.

BiPointNet: Binary Neural Network for Point Clouds Created by Haotong Qin, Zhongang Cai, Mingyuan Zhang, Yifu Ding, Haiyu Zhao, Shuai Yi, Xianglong Li

Haotong Qin 59 Dec 17, 2022
《A-CNN: Annularly Convolutional Neural Networks on Point Clouds》(2019)

A-CNN: Annularly Convolutional Neural Networks on Point Clouds Created by Artem Komarichev, Zichun Zhong, Jing Hua from Department of Computer Science

Artёm Komarichev 44 Feb 24, 2022
Neural Fixed-Point Acceleration for Convex Optimization

Licensing The majority of neural-scs is licensed under the CC BY-NC 4.0 License, however, portions of the project are available under separate license

Facebook Research 27 Oct 6, 2022
This is the code repository implementing the paper "TreePartNet: Neural Decomposition of Point Clouds for 3D Tree Reconstruction".

TreePartNet This is the code repository implementing the paper "TreePartNet: Neural Decomposition of Point Clouds for 3D Tree Reconstruction". Depende

刘彦超 34 Nov 30, 2022
Neural-Pull: Learning Signed Distance Functions from Point Clouds by Learning to Pull Space onto Surfaces(ICML 2021)

Neural-Pull: Learning Signed Distance Functions from Point Clouds by Learning to Pull Space onto Surfaces(ICML 2021) This repository contains the code

null 149 Dec 15, 2022
GndNet: Fast ground plane estimation and point cloud segmentation for autonomous vehicles using deep neural networks.

GndNet: Fast Ground plane Estimation and Point Cloud Segmentation for Autonomous Vehicles. Authors: Anshul Paigwar, Ozgur Erkent, David Sierra Gonzale

Anshul Paigwar 114 Dec 29, 2022
(CVPR 2021) Back-tracing Representative Points for Voting-based 3D Object Detection in Point Clouds

BRNet Introduction This is a release of the code of our paper Back-tracing Representative Points for Voting-based 3D Object Detection in Point Clouds,

null 86 Oct 5, 2022