├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── cmake ├── FindDataLoaders.cmake └── FindEasyPBR.cmake ├── config ├── ln_eval_cloud_ros.cfg ├── ln_train_shapenet_example.cfg ├── lnn_check_lattice_size.cfg ├── lnn_compare_semantic_kitti.cfg ├── lnn_eval_scannet.cfg ├── lnn_eval_semantic_kitti.cfg ├── lnn_train_scannet.cfg ├── lnn_train_semantic_kitti.cfg └── lnn_train_shapenet.cfg ├── data └── shapenet_part_seg │ ├── colorscheme_and_labels │ ├── airplane │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── bag │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── cap │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── car │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── chair │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── earphone │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── guitar │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── knife │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── lamp │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── laptop │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── motorbike │ │ ├── color_scheme.txt │ │ ├── frequency.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── mug │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── pistol │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── rocket │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ ├── skateboard │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ └── table │ │ ├── color_scheme.txt │ │ ├── frequency_uniform.txt │ │ └── labels.txt │ └── download_shapenet.sh ├── docker ├── Dockerfile ├── build.sh ├── cleanup.sh ├── data │ ├── libeigen3-dev_3.3.7-3_all.deb │ ├── libeigen3-dev_3.4.0-2ubuntu2_all.deb │ ├── libgphoto2-6_2.5.22-3_amd64.deb │ ├── libgphoto2-dev_2.5.22-3_amd64.deb │ └── libgphoto2-port12_2.5.22-3_amd64.deb ├── echo_to_file.sh ├── lattice_env.yaml ├── run.sh └── setup.sh ├── imgs ├── code_1.png ├── code_2.png ├── code_3.png ├── teaser.png ├── viewer.png └── viewer_2.png ├── include └── lattice_net │ ├── EvalParams.h │ ├── HashTable.cuh │ ├── Lattice.cuh │ ├── ModelParams.h │ ├── PyBridge.h │ ├── TrainParams.h │ ├── jitify_helper │ ├── jitify_helper.cuh │ ├── jitify_options.hpp │ └── jitify_options.hpp.in │ └── kernels │ ├── HashTableGPU.cuh │ └── LatticeGPU.cuh ├── latticenet_py ├── callbacks │ ├── __pycache__ │ │ ├── callback.cpython-36.pyc │ │ ├── phase.cpython-36.pyc │ │ ├── scores.cpython-36.pyc │ │ ├── state_callback.cpython-36.pyc │ │ ├── tensorboard_callback.cpython-36.pyc │ │ ├── viewer_callback.cpython-36.pyc │ │ ├── vis.cpython-36.pyc │ │ └── visdom_callback.cpython-36.pyc │ ├── callback.py │ ├── phase.py │ ├── scores.py │ ├── state_callback.py │ ├── tensorboard_callback.py │ ├── viewer_callback.py │ ├── vis.py │ └── visdom_callback.py ├── lattice │ ├── __pycache__ │ │ ├── diceloss.cpython-36.pyc │ │ ├── lattice_funcs.cpython-36.pyc │ │ ├── lattice_modules.cpython-36.pyc │ │ ├── lattice_py.cpython-36.pyc │ │ ├── lattice_wrapper.cpython-36.pyc │ │ ├── lovasz_loss.cpython-36.pyc │ │ └── models.cpython-36.pyc │ ├── diceloss.py │ ├── lattice_funcs.py │ ├── lattice_modules.py │ ├── lattice_wrapper.py │ ├── lovasz_loss.py │ ├── models.py │ └── models.py.orig ├── ln_eval.py ├── ln_eval_cloud_ros.py ├── ln_train.py ├── misc │ ├── check_minkowksi_pred.py │ ├── compute_class_frequency.py │ ├── gradcheck_custom.py │ ├── lnn_check_lattice_size.py │ ├── lnn_compare_semantic_kitti.py │ ├── lnn_eval_single_mesh.py │ ├── lnn_grad_check.py │ ├── lnn_make_teaser_img.py │ └── prepare_submission_semantickitti.py └── utils │ ├── __pycache__ │ └── utils.cpython-36.pyc │ └── utils.py ├── setup.py └── src ├── EvalParams.cxx ├── HashTable.cu ├── Lattice.cu ├── ModelParams.cxx ├── PyBridge.cxx └── TrainParams.cxx /.gitignore: -------------------------------------------------------------------------------- 1 | # wandb 2 | wandb/ 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | cover/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # poetry 101 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 102 | # This is especially recommended for binary packages to ensure reproducibility, and is more 103 | # commonly ignored for libraries. 104 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 105 | #poetry.lock 106 | 107 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 108 | __pypackages__/ 109 | 110 | # Celery stuff 111 | celerybeat-schedule 112 | celerybeat.pid 113 | 114 | # SageMath parsed files 115 | *.sage.py 116 | 117 | # Environments 118 | .env 119 | .venv 120 | env/ 121 | venv/ 122 | ENV/ 123 | env.bak/ 124 | venv.bak/ 125 | 126 | # Spyder project settings 127 | .spyderproject 128 | .spyproject 129 | 130 | # Rope project settings 131 | .ropeproject 132 | 133 | # mkdocs documentation 134 | /site 135 | 136 | # mypy 137 | .mypy_cache/ 138 | .dmypy.json 139 | dmypy.json 140 | 141 | # Pyre type checker 142 | .pyre/ 143 | 144 | # pytype static type analyzer 145 | .pytype/ 146 | 147 | # Cython debug symbols 148 | cython_debug/ 149 | 150 | # PyCharm 151 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 152 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 153 | # and can be added to the global gitignore or merged into this file. For a more nuclear 154 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 155 | #.idea/ 156 | 157 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/EasyCuda"] 2 | path = deps/EasyCuda 3 | url = https://github.com/RaduAlexandru/EasyCuda.git 4 | [submodule "deps/jitify"] 5 | path = deps/jitify 6 | url = https://github.com/RaduAlexandru/jitify 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #cmake 3.12 seems to have a problem finisng BLAS 2 | cmake_minimum_required(VERSION 3.13...3.22) 3 | 4 | project(lattice_net) 5 | 6 | 7 | ### VARIABLES ############################################################## 8 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 9 | set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wall -O3") 11 | # set(PYTORCH_PATH "/opt/pytorch") 12 | # set(PYTORCH_PATH_2 "/opt/conda/envs/lattice/lib/python3.6/site-packages/torch") 13 | # set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/opt/ros/melodic/\;${PYTORCH_PATH}" 14 | #set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${PYTORCH_PATH}:${PYTORCH_PATH_2}") 15 | # set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${PYTORCH_PATH};${PYTORCH_PATH_2}") 16 | set(CMAKE_CXX_STANDARD 17) #we need c++17 because this solves alignment issues with eigen http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1409 17 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 18 | set(CMAKE_CXX_EXTENSIONS OFF) 19 | 20 | # set(CMAKE_VERBOSE_MAKEFILE ON) 21 | 22 | 23 | 24 | #pybind attempt 3 25 | # pybind11_add_module(DataLoaderTest ${CMAKE_SOURCE_DIR}/src/pycom/PyCom.cxx ) 26 | 27 | 28 | #### GLOBAL OPTIONS ###https://stackoverflow.com/questions/15201064/cmake-conditional-preprocessor-define-on-code 29 | 30 | 31 | ###### PACKAGES ############################################################ 32 | # find_package(catkin REQUIRED) 33 | find_package(Eigen3 3.3 REQUIRED NO_MODULE) 34 | # find_package(OpenCV REQUIRED) 35 | find_package(EasyPBR REQUIRED) 36 | # find_package(DataLoaders REQUIRED) 37 | # find_package(Torch REQUIRED) 38 | find_package(CUDA REQUIRED) 39 | add_subdirectory(${EASYPBR_SRC_PATH}/deps/pybind11 [EXCLUDE_FROM_ALL]) 40 | # add_subdirectory(${PROJECT_SOURCE_DIR}/deps/pybind11) 41 | # find_package(catkin REQUIRED COMPONENTS roscpp std_msgs cv_bridge pcl_ros image_transport ) 42 | #compile with pytorch 43 | # get and append paths for finding dep 44 | execute_process( #do it like this https://github.com/facebookresearch/hanabi_SAD/blob/6e4ed590f5912fcb99633f4c224778a3ba78879b/rela/CMakeLists.txt#L10 45 | COMMAND python -c "import torch; import os; print(os.path.dirname(torch.__file__), end='')" 46 | OUTPUT_VARIABLE TorchPath 47 | ) 48 | list(APPEND CMAKE_PREFIX_PATH ${TorchPath}) 49 | find_package(Torch REQUIRED) 50 | 51 | 52 | ### INCLUDES ######################################################### 53 | # include_directories(${catkin_INCLUDE_DIRS}) 54 | include_directories(${CMAKE_SOURCE_DIR}/include) 55 | include_directories(${CMAKE_SOURCE_DIR}/deps) 56 | include_directories(${EIGEN3_INCLUDE_DIR}) 57 | include_directories(${EASYPBR_INCLUDE_DIR}) 58 | include_directories(${DATALOADERS_INCLUDE_DIR}) 59 | include_directories(${CUDA_INCLUDE_DIRS}) 60 | include_directories(${TORCH_INCLUDE_DIRS}) 61 | # catkin_package( INCLUDE_DIRS include CATKIN_DEPENDS roscpp std_msgs cv_bridge pcl_ros image_transport ) 62 | 63 | 64 | ### SOURCES ################################################################# 65 | set(MY_SRC 66 | # ${PROJECT_SOURCE_DIR}/src/Frame.cxx 67 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderVolRef.cxx 68 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderImgRos.cxx 69 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderScanNet.cxx 70 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderShapeNetPartSeg.cxx 71 | # ${PROJECT_SOURCE_DIR}/src/DataTransformer.cxx 72 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderSemanticKitti.cxx 73 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderStanfordIndoor.cxx 74 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderToyExample.cxx 75 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderCloudRos.cxx 76 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderRueMonge.cxx 77 | # ${PROJECT_SOURCE_DIR}/src/RosBagPlayer.cxx 78 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderPNG.cxx 79 | # ${PROJECT_SOURCE_DIR}/src/DataLoaderModelNet40.cxx 80 | ) 81 | set(DEPS_SRC 82 | # ${PROJECT_SOURCE_DIR}/deps/json11/json11.cpp 83 | ) 84 | 85 | 86 | ### SET ALL THE GLOBAL OPTIONS ######################################### 87 | 88 | #pybind 89 | pybind11_add_module(latticenet ${PROJECT_SOURCE_DIR}/src/PyBridge.cxx ) 90 | 91 | #lib 92 | # add_library( latticenet_cpp SHARED ${MY_SRC} ${DEPS_SRC} ) 93 | 94 | ## CUDA library ###################### 95 | #configure the include paths of jitify so that the kernels can properly include other ones 96 | configure_file(${PROJECT_SOURCE_DIR}/include/lattice_net/jitify_helper/jitify_options.hpp.in ${PROJECT_SOURCE_DIR}/include/lattice_net/jitify_helper/jitify_options.hpp) 97 | install(FILES "${PROJECT_SOURCE_DIR}/include/lattice_net/jitify_helper/jitify_options.hpp" DESTINATION ${PROJECT_SOURCE_DIR}/include/lattice_net/jitify_helper/) 98 | # set(CUDA_NVCC_FLAGS "-gencode arch=compute_30 -code=sm_30" CACHE STRING "nvcc flags" FORCE) 99 | #disabling a certain nvcc warning is done through https://stackoverflow.com/questions/14831051/how-to-disable-a-specific-nvcc-compiler-warnings 100 | # set(CUDA_NVCC_FLAGS "-arch=sm_60 -Xcudafe --diag_suppress=esa_on_defaulted_function_ignored --expt-relaxed-constexpr --display_error_number " CACHE STRING "nvcc flags" FORCE) 101 | # set(CUDA_NVCC_FLAGS "-arch=sm_60 -Xcudafe --diag_suppress=esa_on_defaulted_function_ignored --expt-relaxed-constexpr") 102 | # message("NVCC flags are ", ${CUDA_NVCC_FLAGS}) 103 | # set(CUDA_VERBOSE_BUILD ON CACHE BOOL "nvcc verbose" FORCE) 104 | # cuda_add_library(latticenet_cu SHARED ${CMAKE_SOURCE_DIR}/src/Lattice.cxx 105 | # add_library(latticenet_cu SHARED ${CMAKE_SOURCE_DIR}/src/Lattice.cxx 106 | cuda_add_library(latticenet_cu SHARED ${CMAKE_SOURCE_DIR}/src/Lattice.cu 107 | # ${CMAKE_SOURCE_DIR}/src/LatticeFuncs.cu 108 | ${CMAKE_SOURCE_DIR}/src/HashTable.cu 109 | ${CMAKE_SOURCE_DIR}/src/ModelParams.cxx 110 | ${CMAKE_SOURCE_DIR}/src/TrainParams.cxx 111 | ${CMAKE_SOURCE_DIR}/src/EvalParams.cxx 112 | ) 113 | # set(LIBS ${LIBS} latticenet_cu) 114 | 115 | 116 | ##pybind 117 | # pybind11_add_module(dataloaders ${PROJECT_SOURCE_DIR}/src/PyBridge.cxx ) 118 | 119 | ### EXECUTABLE ####################################### 120 | # add_executable(run_data_loaders ${PROJECT_SOURCE_DIR}/src/main.cxx ) 121 | 122 | 123 | ### LIBS ############################################### 124 | if(${TORCH_FOUND}) 125 | set(LIBS ${LIBS} ${TORCH_LIBRARIES} ) 126 | #torch 1.5.0 and above mess with pybind and we therefore need to link against libtorch_python.so also 127 | find_library(TORCH_PYTHON_LIBRARY torch_python PATHS "${TORCH_INSTALL_PREFIX}/lib") 128 | message(STATUS "TORCH_PYTHON_LIBRARY: ${TORCH_PYTHON_LIBRARY}") 129 | if(TORCH_PYTHON_LIBRARY) 130 | message(STATUS "Linking to torch_python_library") 131 | set(LIBS ${LIBS} ${TORCH_PYTHON_LIBRARY} ) 132 | endif() 133 | endif() 134 | set(LIBS ${LIBS} ${catkin_LIBRARIES} ${EASYPBR_LIBRARY} ${DATALOADERS_LIBRARY} ${CUDA_LIBRARIES} ${TORCH_LIBRARIES} ${OpenCV_LIBS}) 135 | 136 | 137 | 138 | 139 | 140 | 141 | target_link_libraries(latticenet_cu ${LIBS} ) 142 | target_link_libraries(latticenet PRIVATE latticenet_cu ) 143 | # target_link_libraries(run_data_loaders PRIVATE data_loaders_cpp ) 144 | 145 | 146 | #definitions for cmake variables that are necesarry during runtime 147 | target_compile_definitions(latticenet_cu PRIVATE PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") #point to the cmakelist folder of the easy_pbr 148 | target_compile_definitions(latticenet_cu PRIVATE CMAKE_SOURCE_DIR="${CMAKE_SOURCE_DIR}") # points to the CMakeList folder of whichever project included easy_pbr 149 | 150 | 151 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 University of Bonn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | echo "Building LatticeNet" 3 | python3 -m pip install -v --user --editable ./ 4 | 5 | clean: 6 | python3 -m pip uninstall latticenet 7 | rm -rf build *.egg-info build latticenet*.so liblatticenet_cpp.so 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LatticeNet 2 | 3 | ### [Project Page](https://www.ais.uni-bonn.de/videos/RSS_2020_Rosu/) | [Video](https://www.youtube.com/watch?v=503Z5Vw9a90) | [Paper](https://www.ais.uni-bonn.de/videos/RSS_2020_Rosu/RSS_2020_Rosu.pdf) 4 | 5 | [LatticeNet: Fast Point Cloud Segmentation Using Permutohedral Lattices](https://www.ais.uni-bonn.de/videos/RSS_2020_Rosu/) 6 | [Radu Alexandru Rosu](https://radualexandru.github.io/) 1, 7 | [Peer Schütt]() 1, 8 | [Jan Quenzel](https://www.ais.uni-bonn.de/%7Ejquenzel/) 1, 9 | [Sven Behnke](https://www.ais.uni-bonn.de/behnke/) 1 10 |
11 | 1University of Bonn, Autonomous Intelligent Systems 12 | 13 | 14 |

15 | 16 |

17 | 18 | This is the official PyTorch implementation of [LatticeNet: Fast Point Cloud Segmentation Using Permutohedral Lattices](http://www.ais.uni-bonn.de/videos/RSS_2020_Rosu/) 19 | 20 | LatticeNet can process raw point clouds for semantic segmentation (or any other per-point prediction task). The implementation is written in CUDA and PyTorch. There is no CPU implementation yet. 21 | 22 | # Getting started 23 | 24 | ### Install 25 | 26 | The easiest way to install LatticeNet is using the included dockerfile.
27 | You will need to have Docker>=19.03 and nvidia drivers installed.
28 | Afterwards, you can build the docker image which contains all the LatticeNet dependencies using: 29 | 30 | ```sh 31 | $ git clone --recursive https://github.com/RaduAlexandru/lattice_net 32 | $ cd lattice_net/docker 33 | $ bash ./build.sh lattice_img #this will take some time because some packages need to be build from source 34 | $ bash ./run.sh lattice_img 35 | $ git clone --recursive https://github.com/RaduAlexandru/easy_pbr 36 | $ cd easy_pbr && make && cd .. 37 | $ git clone --recursive https://github.com/RaduAlexandru/data_loaders 38 | $ cd data_loaders && make && cd .. 39 | $ git clone --recursive https://github.com/RaduAlexandru/lattice_net 40 | $ cd lattice_net && make && cd .. 41 | ``` 42 | 43 | ### Data 44 | 45 | LatticeNet uses point clouds for training. The data is loaded with the [DataLoaders] package and interfaced using [EasyPBR]. Here we show how to train on the ShapeNet dataset.
46 | While inside the docker container ( after running ./run.sh lattice_img ), download and unzip the ShapeNet dataset: 47 | 48 | ```sh 49 | $ bash ./lattice_net/data/shapenet_part_seg/download_shapenet.sh 50 | ``` 51 | 52 | # Usage 53 | 54 | ### Train 55 | 56 | LatticeNet uses config files to configure the dataset used, the training parameters, model architecture and various visualization options.
57 | The config file used to train on the shapenet dataset can be found under "lattice_net/config/ln_train_shapenet_example.cfg".
58 | Running the training script will by default read this config file and start the training. 59 | 60 | ```sh 61 | $ ./lattice_net/latticenet_py/ln_train.py 62 | ``` 63 | 64 | ### Configuration options 65 | 66 | Various configuration options can be interesting to check out and modify. We take ln_train_shapenet_example.cfg as an example. 67 | 68 | ``` 69 | core: hdpi: false #can be turned on an off to accomodate high DPI displays. If the text and fonts in the visualizer are too big, set this option to false 70 | train: with_viewer: false #setting to true will start a visualizer which displays the currently segmented point cloud and the difference to the ground truth 71 | ``` 72 |

73 | If training is performed with the viewer enabled, you should see something like this: 74 |
75 |

76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |

86 | 87 | 88 | ## Citation 89 | 90 | ``` 91 | @inproceedings{rosu2020latticenet, 92 | title={LatticeNet: Fast point cloud segmentation using permutohedral lattices}, 93 | author={Rosu, Radu Alexandru and Sch{\"u}tt, Peer and Quenzel, Jan and Behnke, Sven}, 94 | booktitle="Proc. of Robotics: Science and Systems (RSS)", 95 | year={2020} 96 | } 97 | 98 | ``` 99 | 100 | 101 | 102 | 121 | 122 | [EasyPBR]: 123 | [DataLoaders]: 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | # License 135 | LatticeNet is provided under the terms of the MIT license (see LICENSE). We bundle various other libraries (see ./deps) which may have different licenses. -------------------------------------------------------------------------------- /cmake/FindDataLoaders.cmake: -------------------------------------------------------------------------------- 1 | if(EASYPBR_FOUND) 2 | return() 3 | endif() 4 | 5 | 6 | #get the path of site packages which is where easypbr got installed https://stackoverflow.com/a/31384782 and https://stackoverflow.com/a/40006251 7 | execute_process( 8 | COMMAND "python" -c "if True: 9 | import sys 10 | print( next(p for p in sys.path if 'site-packages' in p))" 11 | OUTPUT_VARIABLE PYTHON_SITE 12 | OUTPUT_STRIP_TRAILING_WHITESPACE) 13 | message("--------------------PYTHON is at " ${PYTHON_SITE}) 14 | #Get only the first line of the egg_link because that is pointing towards the easypbrsrc 15 | execute_process ( 16 | # COMMAND bash -c "date +'%F %T'" "${PYTHON_SITE}/easypbr.egg-link" 17 | COMMAND bash -c "head -1 $0" "${PYTHON_SITE}/dataloaders.egg-link" 18 | OUTPUT_VARIABLE DATALOADERS_SRC_PATH 19 | OUTPUT_STRIP_TRAILING_WHITESPACE 20 | ) 21 | message("DATALOADERS source is ${DATALOADERS_SRC_PATH}") 22 | 23 | #DEBUG 24 | # set(EASYPBR_SRC_PATH "/media/rosu/Data/phd/c_ws/src/easy_pbr") 25 | 26 | find_path(DATALOADERS_CORE_INCLUDE_DIR NAMES data_loaders/DataLoaderShapeNetPartSeg.h PATHS "${DATALOADERS_SRC_PATH}/include" ) 27 | # find_path(EASYPBR_EASYGL_INCLUDE_DIR NAMES Texture2D.h PATHS "${EASYPBR_SRC_PATH}/deps/easy_gl" ) 28 | # find_path(EASYPBR_LOGURU_INCLUDE_DIR NAMES loguru.hpp PATHS "${EASYPBR_SRC_PATH}/deps/loguru" ) 29 | # find_path(EASYPBR_CONFIGURU_INCLUDE_DIR NAMES configuru.hpp PATHS "${EASYPBR_SRC_PATH}/deps/configuru" ) 30 | # find_path(EASYPBR_UTILS_INCLUDE_DIR NAMES Profiler.h PATHS "${EASYPBR_SRC_PATH}/deps/utils/include" ) 31 | # find_path(EASYPBR_CONCURRENTQUEUE_INCLUDE_DIR NAMES concurrentqueue.h PATHS "${EASYPBR_SRC_PATH}/deps/concurrent_queue" ) 32 | # find_path(EASYPBR_IMGUI_INCLUDE_DIR NAMES imgui.h PATHS "${EASYPBR_SRC_PATH}/deps/imgui" ) 33 | # find_path(EASYPBR_IMGUIZMO_INCLUDE_DIR NAMES ImGuizmo.h PATHS "${EASYPBR_SRC_PATH}/deps/imguizmo" ) 34 | # find_path(EASYPBR_BETTERENUM_INCLUDE_DIR NAMES enum.h PATHS "${EASYPBR_SRC_PATH}/deps/better_enums" ) 35 | 36 | # set( EASYPBR_INCLUDE_DIR ${EASYPBR_SRC_PATH}/extern ${EASYPBR_CORE_INCLUDE_DIR} ${EASYPBR_EASYGL_INCLUDE_DIR} ${EASYPBR_LOGURU_INCLUDE_DIR} ${EASYPBR_CONFIGURU_INCLUDE_DIR} ${EASYPBR_UTILS_INCLUDE_DIR} ${EASYPBR_CONCURRENTQUEUE_INCLUDE_DIR} ${EASYPBR_IMGUI_INCLUDE_DIR} ${EASYPBR_IMGUIZMO_INCLUDE_DIR} ${EASYPBR_BETTERENUM_INCLUDE_DIR} ) 37 | set( DATALOADERS_INCLUDE_DIR ${DATALOADERS_CORE_INCLUDE_DIR} ) 38 | 39 | # message("--------------------EASYPPBR include dir is at ", ${EASYPBR_INCLUDE_DIR}) 40 | 41 | 42 | find_library(DATALOADERS_LIBRARY 43 | NAMES libdataloaders_cpp.so 44 | HINTS ${DATALOADERS_SRC_PATH} 45 | DOC "The DataLoaders lib directory" 46 | NO_DEFAULT_PATH) 47 | message("--------------------DATALOADERS lib dir is at " ${DATALOADERS_LIBRARY}) 48 | 49 | 50 | -------------------------------------------------------------------------------- /cmake/FindEasyPBR.cmake: -------------------------------------------------------------------------------- 1 | if(EASYPBR_FOUND) 2 | return() 3 | endif() 4 | 5 | 6 | #get the path of site packages which is where easypbr got installed https://stackoverflow.com/a/31384782 and https://stackoverflow.com/a/40006251 7 | execute_process( 8 | COMMAND "python3" -c "if True: 9 | import sys 10 | print( next(p for p in sys.path if 'site-packages' in p))" 11 | OUTPUT_VARIABLE PYTHON_SITE 12 | OUTPUT_STRIP_TRAILING_WHITESPACE) 13 | # message("--------------------PYTHON is at ", ${PYTHON_SITE}) 14 | #Get only the first line of the egg_link because that is pointing towards the easypbrsrc 15 | execute_process ( 16 | # COMMAND bash -c "date +'%F %T'" "${PYTHON_SITE}/easypbr.egg-link" 17 | COMMAND bash -c "head -1 $0" "${PYTHON_SITE}/easypbr.egg-link" 18 | OUTPUT_VARIABLE EASYPBR_SRC_PATH 19 | OUTPUT_STRIP_TRAILING_WHITESPACE 20 | ) 21 | message("EASYPPBR source is ${EASYPBR_SRC_PATH}") 22 | 23 | #DEBUG 24 | # set(EASYPBR_SRC_PATH "/media/rosu/Data/phd/c_ws/src/easy_pbr") 25 | 26 | find_path(EASYPBR_CORE_INCLUDE_DIR NAMES easy_pbr/Viewer.h PATHS "${EASYPBR_SRC_PATH}/include" ) 27 | find_path(EASYPBR_EASYGL_INCLUDE_DIR NAMES easy_gl/Texture2D.h PATHS "${EASYPBR_SRC_PATH}/deps/easy_gl/include" ) 28 | find_path(EASYPBR_LOGURU_INCLUDE_DIR NAMES loguru.hpp PATHS "${EASYPBR_SRC_PATH}/deps/loguru" ) 29 | find_path(EASYPBR_CONFIGURU_INCLUDE_DIR NAMES configuru.hpp PATHS "${EASYPBR_SRC_PATH}/deps/configuru" ) 30 | find_path(EASYPBR_UTILS_INCLUDE_DIR NAMES Profiler.h PATHS "${EASYPBR_SRC_PATH}/deps/utils/include" ) 31 | find_path(EASYPBR_CONCURRENTQUEUE_INCLUDE_DIR NAMES concurrentqueue.h PATHS "${EASYPBR_SRC_PATH}/deps/concurrent_queue" ) 32 | find_path(EASYPBR_IMGUI_INCLUDE_DIR NAMES imgui.h PATHS "${EASYPBR_SRC_PATH}/deps/imgui" ) 33 | find_path(EASYPBR_IMGUIZMO_INCLUDE_DIR NAMES ImGuizmo.h PATHS "${EASYPBR_SRC_PATH}/deps/imguizmo" ) 34 | find_path(EASYPBR_BETTERENUM_INCLUDE_DIR NAMES enum.h PATHS "${EASYPBR_SRC_PATH}/deps/better_enums" ) 35 | find_path(EASYPBR_EASYPYTORCH_INCLUDE_DIR NAMES UtilsPytorch.h PATHS "${EASYPBR_SRC_PATH}/deps/easy_pytorch" ) 36 | find_path(EASYPBR_PYBIND_INCLUDE_DIR NAMES pybind11/pybind11.h PATHS "${EASYPBR_SRC_PATH}/deps/pybind11/include" ) #important because any module that tries to have python modules that interact with easypbr should be built with the same pybind version 37 | find_path(EASYPBR_TINYPLY_INCLUDE_DIR NAMES tinyply.h PATHS "${EASYPBR_SRC_PATH}/deps/tiny_ply/source" ) 38 | 39 | set( EASYPBR_INCLUDE_DIR ${EASYPBR_SRC_PATH}/extern ${EASYPBR_CORE_INCLUDE_DIR} ${EASYPBR_EASYGL_INCLUDE_DIR} ${EASYPBR_LOGURU_INCLUDE_DIR} 40 | ${EASYPBR_CONFIGURU_INCLUDE_DIR} ${EASYPBR_UTILS_INCLUDE_DIR} ${EASYPBR_CONCURRENTQUEUE_INCLUDE_DIR} 41 | ${EASYPBR_IMGUI_INCLUDE_DIR} ${EASYPBR_IMGUIZMO_INCLUDE_DIR} ${EASYPBR_BETTERENUM_INCLUDE_DIR} 42 | ${EASYPBR_EASYPYTORCH_INCLUDE_DIR} ${EASYPBR_PYBIND_INCLUDE_DIR} ${EASYPBR_TINYPLY_INCLUDE_DIR} 43 | ) 44 | 45 | # message("--------------------EASYPPBR include dir is at ", ${EASYPBR_INCLUDE_DIR}) 46 | 47 | 48 | find_library(EASYPBR_LIBRARY 49 | NAMES libeasypbr_cpp.so 50 | HINTS ${EASYPBR_SRC_PATH} 51 | DOC "The EasyPBR lib directory" 52 | NO_DEFAULT_PATH) 53 | # message("--------------------EASYPPBR lib dir is at ", ${EASYPBR_LIBRARY}) 54 | 55 | add_definitions( -DDEFAULT_CONFIG="${EASYPBR_SRC_PATH}/config/default_params.cfg" ) 56 | -------------------------------------------------------------------------------- /config/ln_eval_cloud_ros.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: false 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | eval: { 8 | dataset_name: "cloud_ros" //semantickitti, shapenet, cloud_ros 9 | with_viewer: true 10 | // checkpoint_path: "/media/rosu/Data/data/semantic_kitti/saved_models/home_comp_sigma_06/model_e_2_0.5351074128516075.pt" 11 | checkpoint_path: "/media/rosu/Data/data/semantic_kitti/saved_models/home_comp_sigma_06_dropout_finale/model_e_2_0.5341928188691084.pt" //seems a bit more stable 12 | do_write_predictions: false 13 | output_predictions_path: "/media/rosu/Data/data/drz/latticenet_predictions/bag_mbzirc8_2020-09-30-17-52-35/home_comp_sigma_06" 14 | } 15 | 16 | 17 | 18 | model: { 19 | positions_mode: "xyz" 20 | values_mode: "none" 21 | pointnet_layers: [16,32,64] 22 | pointnet_start_nr_channels: 64 23 | nr_downsamples: 3 24 | nr_blocks_down_stage: [2,2,2] 25 | nr_blocks_bottleneck: 3 26 | nr_blocks_up_stage: [1,2,2] 27 | nr_levels_down_with_normal_resnet: 3 28 | nr_levels_up_with_normal_resnet: 3 29 | compression_factor: 1.0 30 | dropout_last_layer: 0.0 31 | 32 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 33 | // none - default model with full features 34 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 35 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 36 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 37 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 38 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 39 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 40 | experiment: "none" 41 | } 42 | 43 | 44 | 45 | lattice_gpu: { 46 | hash_table_capacity: 100000 //good for smenaitc kitti which splat around 10k with sigma of 1 47 | nr_sigmas: 1 48 | 49 | sigma_0: "0.6 3" //sigma of X affecting Y dimensions of the positions vector 50 | } 51 | 52 | ros_bag: { 53 | bag_path: "/media/rosu/HDD/data/drz/bags/bag_mbzirc8_2020-09-30-17-52-35.bag" 54 | // bag_path: "/media/rosu/HDD/data/drz/bags/bag_mbzirc8_2020-11-11-16-14-51.bag" 55 | bag_args: "-r 1.0" 56 | 57 | } 58 | loader_cloud_ros: { 59 | cloud_topic: "/os_cloud_node/points" 60 | min_dist_filter: 0 61 | do_pose: false 62 | pose_file: "/media/rosu/Data/data/drz/semantic_poses/last_reg_pose_bag_mbzirc8_2020-09-30-17-52-35.txt" 63 | // pose_file: "/media/rosu/Data/data/drz/semantic_poses/gps_poses_bag_mbzirc8_2020-09-30-17-52-35.txt" 64 | pose_file_format: "tum" 65 | 66 | transformer: { 67 | random_translation_xyz_magnitude: 0.0 68 | random_translation_xz_magnitude: 0.0 69 | rotation_y_max_angle: 0.0 70 | random_stretch_xyz_magnitude: 0.0 71 | adaptive_subsampling_falloff_start: 0.0 72 | // adaptive_subsampling_falloff_end: 50.0 73 | // random_subsample_percentage: 0.3 //randomly removed x percent of the pointcloud 74 | adaptive_subsampling_falloff_end: 0.0 75 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 76 | random_mirror_x: false 77 | random_mirror_z: false 78 | random_rotation_90_degrees_y: false 79 | 80 | hsv_jitter:[0,0,0] 81 | 82 | chance_of_xyz_noise: 0.0 83 | xyz_noise_stddev: [0.0, 0.0, 0.0] 84 | } 85 | 86 | } 87 | 88 | 89 | visualization: { 90 | show_gui: true 91 | 92 | subsample_factor: 1 93 | enable_culling: true 94 | 95 | cam: { 96 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 97 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 98 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 99 | exposure: 1.0 //can be floar or "auto" 100 | } 101 | 102 | ssao: { 103 | enable_ssao: false 104 | ao_downsample: 0 105 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 106 | ao_power: 4 107 | ao_blur_sigma_spacial: 2.0 108 | ao_blur_sigma_depth: 0.0001 109 | } 110 | 111 | edl: { 112 | auto_settings: true 113 | enable_edl_lighting: true 114 | edl_strength: 8.0 115 | } 116 | 117 | background:{ 118 | show_background_img: false 119 | background_img_path: "" 120 | } 121 | 122 | ibl: { 123 | enable_ibl: false 124 | show_environment_map: false 125 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 126 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 127 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 128 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 129 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 130 | // environment_cubemap_resolution: 2048 131 | environment_cubemap_resolution: 512 132 | irradiance_cubemap_resolution: 32 133 | prefilter_cubemap_resolution: 128 134 | brdf_lut_resolution: 512 135 | } 136 | 137 | lights:{ 138 | nr_spot_lights: 0 139 | spot_light_0: { 140 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 141 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 142 | create_shadow: true 143 | shadow_map_resolution: 2048 144 | } 145 | spot_light_1: { 146 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 147 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 148 | create_shadow: true 149 | shadow_map_resolution: 1024 150 | } 151 | spot_light_2: { 152 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 153 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 154 | create_shadow: true 155 | shadow_map_resolution: 1024 156 | } 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /config/ln_train_shapenet_example.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: false 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | train: { 8 | dataset_name: "shapenet" //semantickitti, shapenet, toyexample 9 | with_viewer: false 10 | with_visdom: false 11 | with_tensorboard: false 12 | lr: 0.001 13 | weight_decay: 0.0 14 | // weight_decay: 3e-4 15 | save_checkpoint: false 16 | checkpoint_path: "" 17 | } 18 | 19 | model: { 20 | positions_mode: "xyz" 21 | values_mode: "none" 22 | pointnet_channels_per_layer: [16,32,64] 23 | pointnet_start_nr_channels: 32 24 | nr_downsamples: 3 25 | nr_blocks_down_stage: [4,4,4] 26 | nr_blocks_bottleneck: 3 27 | nr_blocks_up_stage: [2,2,2] 28 | nr_levels_down_with_normal_resnet: 3 29 | nr_levels_up_with_normal_resnet: 2 30 | compression_factor: 1.0 31 | dropout_last_layer: 0.0 32 | 33 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 34 | // none - default model with full features 35 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 36 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 37 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 38 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 39 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 40 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 41 | experiment: "none" 42 | } 43 | 44 | lattice_gpu: { 45 | hash_table_capacity: 60000 //good for shapenet which splat at around 1k for sigma 0.03 46 | nr_sigmas: 1 47 | 48 | // sigma_0: "0.06 3" //for bag IMPORTANT: if you change this, change it also int he lnn_eval.cfg 49 | sigma_0: "0.05 3" //for motorbike IMPORTANT: if you change this, change it also int he lnn_eval.cfg 50 | // sigma_0: "0.03 3" //for knife IMPORTANT: if you change this, change it also int he lnn_eval.cfg 51 | // sigma_0: "0.01 2" // IMPORTANT: if you change this, change it also int he lnn_eval.cfg 52 | // sigma_0: "0.055 3" //for table IMPORTANT: if you change this, change it also int he lnn_eval.cfg 53 | // sigma_0: "0.04 3" //for rocket IMPORTANT: if you change this, change it also int he lnn_eval.cfg 54 | // sigma_0: "0.06 3" //for cap IMPORTANT: if you change this, change it also int he lnn_eval.cfg 55 | // sigma_0: "0.06 3" //for car IMPORTANT: if you change this, change it also int he lnn_eval.cfg 56 | //finer lattice 57 | // sigma_0: "0.04 3" //for car IMPORTANT: if you change this, change it also int he lnn_eval.cfg 58 | 59 | } 60 | 61 | 62 | loader_shapenet_partseg: { 63 | dataset_path: "/workspace/lattice_net/data/shapenet_part_seg/shapenetcore_partanno_segmentation_benchmark_v0" 64 | autostart: false 65 | mode: "train" // train, test, val 66 | restrict_to_object: "motorbike" // you can leave it empty to get all of them or write any of (airplane, bag, cap, car, chair, earphone, guitar, knife, lamp, laptop, motorbike, mug, pistol, rocket, skateboard, table) 67 | shuffle_points: true 68 | normalize: false // normalize the point cloud between [-1 and 1] 69 | shuffle: true 70 | // do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 71 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 72 | 73 | // one used for actual augmentation 74 | transformer: { 75 | random_translation_xyz_magnitude: [0.2, 0.0, 0.2] 76 | rotation_x_max_angle: 0.0 77 | rotation_y_max_angle: 0.0 78 | rotation_z_max_angle: 0.0 79 | // random_stretch_xyz_magnitude: 0.2 80 | random_stretch_xyz_magnitude: [0.0, 0.0, 0.0] 81 | adaptive_subsampling_falloff_start: 0.0 82 | adaptive_subsampling_falloff_end: 0.0 83 | // random_subsample_percentage: 0.998 //randomly removed x percent of the pointcloud 84 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 85 | random_mirror_x: false 86 | random_mirror_y: false 87 | random_mirror_z: true 88 | random_rotation_90_degrees_y: false 89 | hsv_jitter: [0,0,0] 90 | chance_of_xyz_noise: 0.5 91 | xyz_noise_stddev: [0.001, 0.001, 0.001] 92 | } 93 | } 94 | 95 | 96 | 97 | visualization: { 98 | show_gui: true 99 | 100 | subsample_factor: 1 101 | enable_culling: true 102 | 103 | cam: { 104 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 105 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 106 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 107 | exposure: 1.0 //can be floar or "auto" 108 | } 109 | 110 | ssao: { 111 | enable_ssao: false 112 | ao_downsample: 0 113 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 114 | ao_power: 4 115 | ao_blur_sigma_spacial: 2.0 116 | ao_blur_sigma_depth: 0.0001 117 | } 118 | 119 | edl: { 120 | auto_settings: true 121 | enable_edl_lighting: true 122 | edl_strength: 8.0 123 | } 124 | 125 | background:{ 126 | show_background_img: false 127 | background_img_path: "" 128 | } 129 | 130 | ibl: { 131 | enable_ibl: false 132 | show_environment_map: false 133 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 134 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 135 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 136 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 137 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 138 | // environment_cubemap_resolution: 2048 139 | environment_cubemap_resolution: 512 140 | irradiance_cubemap_resolution: 32 141 | prefilter_cubemap_resolution: 128 142 | brdf_lut_resolution: 512 143 | } 144 | 145 | lights:{ 146 | nr_spot_lights: 0 147 | spot_light_0: { 148 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 149 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 150 | create_shadow: true 151 | shadow_map_resolution: 2048 152 | } 153 | spot_light_1: { 154 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 155 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 156 | create_shadow: true 157 | shadow_map_resolution: 1024 158 | } 159 | spot_light_2: { 160 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 161 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 162 | create_shadow: true 163 | shadow_map_resolution: 1024 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /config/lnn_compare_semantic_kitti.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: true 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | 8 | 9 | 10 | loader_semantic_kitti: { 11 | // dataset_path: "/media/rosu/Data/data/semantic_kitti" //FOR HOST 12 | dataset_path: "/media/rosu/Data/data/semantic_kitti/possible_clouds_we_used_for_the_image" //FOR HOST 13 | // dataset_path: "/home/local/staff/rosu/data/semantic_kitti" //FOR BIGCUDA5 14 | // dataset_path: "/home/user/rosu/data/semantic_kitti" //FOR INFCUDA2 15 | autostart: false 16 | mode: "test" // train, test, val 17 | sequence: "all" //between 00 and 10 without 08, also can be "all" which means it will run through all sequences shuffled or not 18 | nr_clouds_to_skip: 0 19 | nr_clouds_to_read: -1 20 | //nr_clouds_to_read: 100 21 | cap_distance: -1 22 | shuffle_points: false 23 | do_pose: false 24 | normalize: false // normalize the point cloud between [-1 and 1] TAKES PRECEDENCE OVER THE POSE TRANSFORMATION 25 | shuffle: false 26 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 27 | //do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 28 | 29 | label_mngr: { 30 | labels_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/labels.txt" 31 | color_scheme_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 32 | frequency_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 33 | 34 | // labels_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 35 | // color_scheme_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 36 | // frequency_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 37 | 38 | // labels_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 39 | // color_scheme_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 40 | // frequency_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 41 | 42 | unlabeled_idx: 0 43 | } 44 | 45 | transformer: { 46 | random_translation_xyz_magnitude: 0.0 47 | random_translation_xz_magnitude: 0.0 48 | rotation_y_max_angle: 0.0 49 | random_stretch_xyz_magnitude: 0.0 50 | adaptive_subsampling_falloff_start: 0.0 51 | adaptive_subsampling_falloff_end: 0.0 52 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 53 | random_mirror_x: false 54 | random_mirror_z: false 55 | random_rotation_90_degrees_y: false 56 | hsv_jitter: [0,0,0] 57 | } 58 | } 59 | 60 | 61 | 62 | visualization: { 63 | show_gui: true 64 | 65 | subsample_factor: 1 66 | enable_culling: true 67 | 68 | cam: { 69 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 70 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 71 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 72 | exposure: 1.0 //can be floar or "auto" 73 | } 74 | 75 | ssao: { 76 | enable_ssao: false 77 | ao_downsample: 0 78 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 79 | ao_power: 4 80 | ao_blur_sigma_spacial: 2.0 81 | ao_blur_sigma_depth: 0.0001 82 | } 83 | 84 | edl: { 85 | auto_settings: true 86 | enable_edl_lighting: true 87 | edl_strength: 40.0 88 | } 89 | 90 | background:{ 91 | show_background_img: false 92 | background_img_path: "" 93 | } 94 | 95 | ibl: { 96 | enable_ibl: false 97 | show_environment_map: false 98 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 99 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 100 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 101 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 102 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 103 | // environment_cubemap_resolution: 2048 104 | environment_cubemap_resolution: 512 105 | irradiance_cubemap_resolution: 32 106 | prefilter_cubemap_resolution: 128 107 | brdf_lut_resolution: 512 108 | } 109 | 110 | lights:{ 111 | nr_spot_lights: 0 112 | spot_light_0: { 113 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 114 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 115 | create_shadow: true 116 | shadow_map_resolution: 2048 117 | } 118 | spot_light_1: { 119 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 120 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 121 | create_shadow: true 122 | shadow_map_resolution: 1024 123 | } 124 | spot_light_2: { 125 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 126 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 127 | create_shadow: true 128 | shadow_map_resolution: 1024 129 | } 130 | } 131 | 132 | } -------------------------------------------------------------------------------- /config/lnn_eval_scannet.cfg: -------------------------------------------------------------------------------- 1 | eval: { 2 | dataset_name: "scannet" //semantickitti, shapenet 3 | with_viewer: false 4 | // checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_icra_experiments_none/model_e_68_0.5708144501707002.pt" 5 | // checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_icra_experiments_none_sigma_0_3/model_e_36_0.49091539349217744.pt" 6 | // checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_icra_experiments_none_sigma_0_6/model_e_43_0.40871909717486526.pt" 7 | // checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_icra_experiments_none_sigma_1_0/model_e_56_0.33611587723077097.pt" 8 | checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_rss_submision/model_e_112_0.5823387958072441.pt" 9 | do_write_predictions: true 10 | 11 | // output_predictions_path: "/home/user/rosu/data/scannet/predictions/after_icra_experiments_none_epoch_68" 12 | // output_predictions_path: "/home/user/rosu/data/scannet/predictions/after_icra_experiments_none_sigma_0_3_epoch_36" 13 | // output_predictions_path: "/home/user/rosu/data/scannet/predictions/after_icra_experiments_none_sigma_0_6_epoch_43" 14 | // output_predictions_path: "/home/user/rosu/data/scannet/predictions/after_icra_experiments_none_sigma_1_0_epoch_56" 15 | output_predictions_path: "/home/user/rosu/data/scannet/predictions/after_rss_submision_epoch_112" 16 | } 17 | 18 | 19 | model: { 20 | positions_mode: "xyz" 21 | values_mode: "rgb+height" 22 | pointnet_layers: [16,32,64] 23 | pointnet_start_nr_channels: 32 24 | nr_downsamples: 3 25 | nr_blocks_down_stage: [6,6,8] 26 | nr_blocks_bottleneck: 8 27 | nr_blocks_up_stage: [2,2,2] 28 | nr_levels_down_with_normal_resnet: 3 29 | nr_levels_up_with_normal_resnet: 3 30 | compression_factor: 1.0 31 | dropout_last_layer: 0.0 32 | experiment: "none" 33 | } 34 | 35 | core: { 36 | loguru_verbosity: 3 37 | hidpi: true 38 | debug_with_profiler: true //makes the profiler print when it starts and stops time 39 | } 40 | 41 | lattice_gpu: { 42 | hash_table_capacity: 5000000 43 | nr_sigmas: 1 44 | 45 | sigma_0: "0.08 3" 46 | } 47 | 48 | 49 | loader_scannet: { 50 | dataset_path: "/home/user/rosu/data/scannet" 51 | autostart: false 52 | mode: "test" // train, test, val 53 | nr_clouds_to_skip: 0 54 | nr_clouds_to_read: -1 55 | max_nr_points_per_cloud: -1 56 | shuffle_points: false 57 | shuffle: false 58 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 59 | 60 | label_mngr: { 61 | labels_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/labels.txt" 62 | color_scheme_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/color_scheme.txt" 63 | frequency_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/frequency_uniform.txt" 64 | unlabeled_idx: 0 65 | } 66 | 67 | // one used for actual augmentation 68 | transformer: { 69 | random_translation_xyz_magnitude: 0.0 70 | random_translation_xz_magnitude: 0.0 71 | rotation_y_max_angle: 0.0 72 | random_stretch_xyz_magnitude: 0.0 73 | adaptive_subsampling_falloff_start: 0.0 74 | adaptive_subsampling_falloff_end: 0.0 75 | // random_subsample_percentage: 0.6 //randomly removed x percent of the pointcloud 76 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 77 | random_mirror_x: false 78 | random_mirror_z: false 79 | random_rotation_90_degrees_y: false 80 | hsv_jitter: [0,0,0] 81 | chance_of_xyz_noise: 0.0 82 | xyz_noise_stddev: [0.0, 0.0, 0.0] 83 | } 84 | 85 | } 86 | 87 | visualization: { 88 | show_gui: true 89 | 90 | subsample_factor: 1 91 | enable_culling: true 92 | 93 | cam: { 94 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 95 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 96 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 97 | exposure: 1.0 //can be floar or "auto" 98 | } 99 | 100 | ssao: { 101 | enable_ssao: false 102 | ao_downsample: 0 103 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 104 | ao_power: 4 105 | ao_blur_sigma_spacial: 2.0 106 | ao_blur_sigma_depth: 0.0001 107 | } 108 | 109 | edl: { 110 | auto_settings: true 111 | enable_edl_lighting: true 112 | edl_strength: 8.0 113 | } 114 | 115 | background:{ 116 | show_background_img: false 117 | background_img_path: "" 118 | } 119 | 120 | ibl: { 121 | enable_ibl: false 122 | show_environment_map: false 123 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 124 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 125 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 126 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 127 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 128 | // environment_cubemap_resolution: 2048 129 | environment_cubemap_resolution: 512 130 | irradiance_cubemap_resolution: 32 131 | prefilter_cubemap_resolution: 128 132 | brdf_lut_resolution: 512 133 | } 134 | 135 | lights:{ 136 | nr_spot_lights: 0 137 | spot_light_0: { 138 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 139 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 140 | create_shadow: true 141 | shadow_map_resolution: 2048 142 | } 143 | spot_light_1: { 144 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 145 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 146 | create_shadow: true 147 | shadow_map_resolution: 1024 148 | } 149 | spot_light_2: { 150 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 151 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 152 | create_shadow: true 153 | shadow_map_resolution: 1024 154 | } 155 | } 156 | 157 | } 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /config/lnn_eval_semantic_kitti.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: true 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | eval: { 8 | dataset_name: "semantickitti" //semantickitti, shapenet 9 | with_viewer: false 10 | // checkpoint_path: "/home/user/rosu/data/semantic_kitti/saved_models/after_icra_experiments_fixed_deform_none/model_e_5_0.5141485143006357.pt" 11 | checkpoint_path: "/home/user/rosu/data/semantic_kitti/saved_models/after_rss_submision_tests_sigma_06_gn_lovasz_smallernet/model_e_2_0.5526584851362462.pt" 12 | do_write_predictions: true 13 | // output_predictions_path: "/home/local/staff/rosu/data/semantic_kitti/predictions/final_7_amsgrad_iou/" 14 | output_predictions_path: "/home/user/rosu/data/semantic_kitti/predictions/after_rss_submision_tests_sigma_06_gn_lovasz_smallernet/" 15 | } 16 | 17 | // model: { 18 | // positions_mode: "xyz" 19 | // values_mode: "none" 20 | // pointnet_start_nr_channels: 64 21 | // nr_downsamples: 3 22 | // nr_blocks_down_stage: [6,6,8] 23 | // nr_blocks_bottleneck: 8 24 | // nr_blocks_up_stage: [2,2,2] 25 | // nr_levels_down_with_normal_resnet: 3 26 | // nr_levels_up_with_normal_resnet: 3 27 | // compression_factor: 1.0 28 | // dropout_last_layer: 0.0 29 | 30 | // //we run some experiments by setting the string here which if it's none then we run with the default full model: 31 | // // none - default model with full features 32 | // // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 33 | // // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 34 | // // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 35 | // // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 36 | // // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 37 | // experiment: "none" 38 | // } 39 | 40 | model: { 41 | positions_mode: "xyz" 42 | values_mode: "none" 43 | pointnet_layers: [16,32,64] 44 | pointnet_start_nr_channels: 64 45 | nr_downsamples: 3 46 | nr_blocks_down_stage: [2,2,2] 47 | nr_blocks_bottleneck: 3 48 | nr_blocks_up_stage: [1,2,2] 49 | nr_levels_down_with_normal_resnet: 3 50 | nr_levels_up_with_normal_resnet: 3 51 | compression_factor: 1.0 52 | dropout_last_layer: 0.0 53 | 54 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 55 | // none - default model with full features 56 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 57 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 58 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 59 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 60 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 61 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 62 | experiment: "none" 63 | } 64 | 65 | 66 | 67 | lattice_gpu: { 68 | hash_table_capacity: 100000 //good for smenaitc kitti which splat around 10k with sigma of 1 69 | nr_sigmas: 1 70 | 71 | sigma_0: "0.6 3" //sigma of X affecting Y dimensions of the positions vector 72 | } 73 | 74 | loader_semantic_kitti: { 75 | // dataset_path: "/media/rosu/Data/data/semantic_kitti" //FOR HOST 76 | // dataset_path: "/home/local/staff/rosu/data/semantic_kitti" //FOR BIGCUDA5 77 | dataset_path: "/home/user/rosu/data/semantic_kitti" //FOR INFCUDA2 78 | autostart: false 79 | mode: "test" // train, test, val 80 | sequence: "all" //between 00 and 10 without 08, also can be "all" which means it will run through all sequences shuffled or not 81 | nr_clouds_to_skip: 0 82 | nr_clouds_to_read: -1 83 | //nr_clouds_to_read: 100 84 | cap_distance: -1 85 | shuffle_points: false 86 | do_pose: false 87 | normalize: false // normalize the point cloud between [-1 and 1] TAKES PRECEDENCE OVER THE POSE TRANSFORMATION 88 | shuffle: false 89 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 90 | //do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 91 | 92 | label_mngr: { 93 | // labels_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 94 | // color_scheme_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 95 | // frequency_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 96 | 97 | labels_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 98 | color_scheme_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 99 | frequency_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 100 | 101 | unlabeled_idx: 0 102 | } 103 | 104 | transformer: { 105 | random_translation_xyz_magnitude: 0.0 106 | random_translation_xz_magnitude: 0.0 107 | rotation_y_max_angle: 0.0 108 | random_stretch_xyz_magnitude: 0.0 109 | adaptive_subsampling_falloff_start: 0.0 110 | adaptive_subsampling_falloff_end: 0.0 111 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 112 | random_mirror_x: false 113 | random_mirror_z: false 114 | random_rotation_90_degrees_y: false 115 | hsv_jitter: [0,0,0] 116 | chance_of_xyz_noise: 0.0 117 | xyz_noise_stddev: [0.0, 0.0, 0.0] 118 | } 119 | } 120 | 121 | 122 | 123 | visualization: { 124 | show_gui: true 125 | 126 | subsample_factor: 1 127 | enable_culling: true 128 | 129 | cam: { 130 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 131 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 132 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 133 | exposure: 1.0 //can be floar or "auto" 134 | } 135 | 136 | ssao: { 137 | enable_ssao: false 138 | ao_downsample: 0 139 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 140 | ao_power: 4 141 | ao_blur_sigma_spacial: 2.0 142 | ao_blur_sigma_depth: 0.0001 143 | } 144 | 145 | edl: { 146 | auto_settings: true 147 | enable_edl_lighting: true 148 | edl_strength: 8.0 149 | } 150 | 151 | background:{ 152 | show_background_img: false 153 | background_img_path: "" 154 | } 155 | 156 | ibl: { 157 | enable_ibl: false 158 | show_environment_map: false 159 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 160 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 161 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 162 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 163 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 164 | // environment_cubemap_resolution: 2048 165 | environment_cubemap_resolution: 512 166 | irradiance_cubemap_resolution: 32 167 | prefilter_cubemap_resolution: 128 168 | brdf_lut_resolution: 512 169 | } 170 | 171 | lights:{ 172 | nr_spot_lights: 0 173 | spot_light_0: { 174 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 175 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 176 | create_shadow: true 177 | shadow_map_resolution: 2048 178 | } 179 | spot_light_1: { 180 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 181 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 182 | create_shadow: true 183 | shadow_map_resolution: 1024 184 | } 185 | spot_light_2: { 186 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 187 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 188 | create_shadow: true 189 | shadow_map_resolution: 1024 190 | } 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /config/lnn_train_scannet.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: true 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | train: { 8 | dataset_name: "scannet" //semantickitti, shapenet, toyexample, stanford, scannet 9 | with_viewer: false 10 | with_debug_output: false 11 | with_error_checking: false 12 | batch_size: 1 13 | // lr:0.001 // works well for adam with reduceonplateu and with the coarsening which doest the concatenation (if we do concatenation we have to reduce learning rate) 14 | lr: 0.001 //for radam we use a higher learning rate than adam as explained here which recommend x5 https://forums.fast.ai/t/meet-radam-imo-the-new-state-of-the-art-ai-optimizer/52656/41 15 | weight_decay: 1e-3 16 | max_training_epochs: -1 17 | 18 | save_checkpoint: true 19 | checkpoint_path: "/home/user/rosu/data/scannet/saved_models/after_rss_submision" 20 | } 21 | 22 | model: { 23 | positions_mode: "xyz" 24 | values_mode: "rgb+height" 25 | pointnet_layers: [16,32,64] 26 | pointnet_start_nr_channels: 32 27 | nr_downsamples: 3 28 | nr_blocks_down_stage: [6,6,8] 29 | nr_blocks_bottleneck: 8 30 | nr_blocks_up_stage: [2,2,2] 31 | nr_levels_down_with_normal_resnet: 3 32 | nr_levels_up_with_normal_resnet: 3 33 | compression_factor: 1.0 34 | dropout_last_layer: 0.0 35 | 36 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 37 | // none - default model with full features 38 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 39 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 40 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 41 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 42 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 43 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 44 | experiment: "none" 45 | } 46 | 47 | 48 | 49 | lattice_gpu: { 50 | hash_table_capacity: 5000000 51 | nr_sigmas: 1 52 | 53 | sigma_0: "0.08 3" //default 54 | } 55 | 56 | 57 | loader_scannet: { 58 | dataset_path: "/home/user/rosu/data/scannet" //infcuda2 59 | //dataset_path: "/home/local/staff/rosu/data/scannet" //bigcuda5 60 | autostart: false 61 | mode: "train" // train, test, val 62 | nr_clouds_to_skip: 0 63 | nr_clouds_to_read: -1 64 | max_nr_points_per_cloud: 400000 65 | shuffle_points: true 66 | shuffle: true 67 | // do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 68 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 69 | 70 | label_mngr: { 71 | //infcuda2 72 | labels_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/labels.txt" 73 | color_scheme_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/color_scheme.txt" 74 | frequency_file: "/home/user/rosu/data/scannet/colorscheme_and_labels/frequency_uniform.txt" 75 | 76 | //labels_file: "/home/local/staff/rosu/data/scannet/colorscheme_and_labels/labels.txt" 77 | //color_scheme_file: "/home/local/staff/rosu/data/scannet/colorscheme_and_labels/color_scheme.txt" 78 | //frequency_file: "/home/local/staff/rosu/data/scannet/colorscheme_and_labels/frequency_uniform.txt" 79 | 80 | unlabeled_idx: 0 81 | } 82 | 83 | // one used for actual augmentation 84 | transformer: { 85 | random_translation_xyz_magnitude: 0.0 86 | random_translation_xz_magnitude: 3.0 87 | rotation_y_max_angle: 0.0 88 | random_stretch_xyz_magnitude: 0.0 89 | adaptive_subsampling_falloff_start: 0.0 90 | adaptive_subsampling_falloff_end: 0.0 91 | // random_subsample_percentage: 0.6 //randomly removed x percent of the pointcloud 92 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 93 | random_mirror_x: true 94 | random_mirror_z: true 95 | random_rotation_90_degrees_y: true 96 | 97 | hsv_jitter: [5.0, 0.05, 0.05] //jitter in hsv space by this amount with a uniform random in [-h,h], [-s,s], [-v,v] 98 | chance_of_xyz_noise: 0.0 99 | xyz_noise_stddev: [0.0, 0.0, 0.0] 100 | } 101 | 102 | } 103 | 104 | visualization: { 105 | show_gui: true 106 | 107 | subsample_factor: 1 108 | enable_culling: true 109 | 110 | cam: { 111 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 112 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 113 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 114 | exposure: 1.0 //can be floar or "auto" 115 | } 116 | 117 | ssao: { 118 | enable_ssao: false 119 | ao_downsample: 0 120 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 121 | ao_power: 4 122 | ao_blur_sigma_spacial: 2.0 123 | ao_blur_sigma_depth: 0.0001 124 | } 125 | 126 | edl: { 127 | auto_settings: true 128 | enable_edl_lighting: true 129 | edl_strength: 8.0 130 | } 131 | 132 | background:{ 133 | show_background_img: false 134 | background_img_path: "" 135 | } 136 | 137 | ibl: { 138 | enable_ibl: false 139 | show_environment_map: false 140 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 141 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 142 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 143 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 144 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 145 | // environment_cubemap_resolution: 2048 146 | environment_cubemap_resolution: 512 147 | irradiance_cubemap_resolution: 32 148 | prefilter_cubemap_resolution: 128 149 | brdf_lut_resolution: 512 150 | } 151 | 152 | lights:{ 153 | nr_spot_lights: 0 154 | spot_light_0: { 155 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 156 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 157 | create_shadow: true 158 | shadow_map_resolution: 2048 159 | } 160 | spot_light_1: { 161 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 162 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 163 | create_shadow: true 164 | shadow_map_resolution: 1024 165 | } 166 | spot_light_2: { 167 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 168 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 169 | create_shadow: true 170 | shadow_map_resolution: 1024 171 | } 172 | } 173 | 174 | } 175 | 176 | -------------------------------------------------------------------------------- /config/lnn_train_semantic_kitti.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: false 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | train: { 8 | dataset_name: "semantickitti" //semantickitti, shapenet 9 | with_viewer: true 10 | with_visdom: false 11 | lr:0.001 // works well for adam with reduceonplateu and with the coarsening which doest the concatenation (if we do concatenation we have to reduce learning rate) 12 | weight_decay: 1e-3 13 | 14 | save_checkpoint: false 15 | // checkpoint_path: "/home/local/staff/rosu/data/semantic_kitti/saved_models/after_icra_experiments_slice_no_deform" //FOR BIGCUDA5 16 | // checkpoint_path: "/home/user/rosu/data/semantic_kitti/saved_models/after_rss_submision_tests_sigma_06_gn_lovasz_smallernet" //FOR INFCUDA2 17 | checkpoint_path: "/media/rosu/Data/data/semantic_kitti/saved_models/home_comp_sigma_06_dropout_finale" //FOR home 18 | } 19 | 20 | model: { 21 | //SHOULD BE USED WITH A SIGMA OF 0.6 22 | // positions_mode: "xyz" 23 | // values_mode: "none" 24 | // pointnet_layers: [16,32,64] 25 | // pointnet_start_nr_channels: 64 26 | // nr_downsamples: 3 27 | // nr_blocks_down_stage: [2,2,2] 28 | // nr_blocks_bottleneck: 3 29 | // nr_blocks_up_stage: [1,2,2] 30 | // nr_levels_down_with_normal_resnet: 3 31 | // nr_levels_up_with_normal_resnet: 3 32 | // compression_factor: 1.0 33 | // dropout_last_layer: 0.0 34 | 35 | //tiny also with a coarsen lattice with sigma 0.9 36 | positions_mode: "xyz" 37 | values_mode: "none" 38 | pointnet_layers: [16,32] 39 | pointnet_start_nr_channels: 32 40 | nr_downsamples: 2 41 | nr_blocks_down_stage: [1,1,1] 42 | nr_blocks_bottleneck: 1 43 | nr_blocks_up_stage: [1,1,1] 44 | nr_levels_down_with_normal_resnet: 3 45 | nr_levels_up_with_normal_resnet: 3 46 | compression_factor: 1.0 47 | dropout_last_layer: 0.0 48 | 49 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 50 | // none - default model with full features 51 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 52 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 53 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 54 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 55 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 56 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 57 | experiment: "none" 58 | } 59 | 60 | 61 | 62 | lattice_gpu: { 63 | hash_table_capacity: 100000 //good for smenaitc kitti which splat around 10k with sigma of 1 64 | nr_sigmas: 1 65 | 66 | // sigma_0: "0.6 3" //sigma of X affecting Y dimensions of the positions vector 67 | 68 | //coarser lattice 69 | sigma_0: "0.9 3" //sigma of X affecting Y dimensions of the positions vector 70 | 71 | } 72 | 73 | loader_semantic_kitti: { 74 | // dataset_path: "/media/rosu/Data/data/semantic_kitti" //FOR HOST 75 | // dataset_path: "/home/local/staff/rosu/data/semantic_kitti" //FOR BIGCUDA5 76 | // dataset_path: "/home/user/rosu/data/semantic_kitti" //FOR INFCUDA2 77 | dataset_path: "/media/rosu/Data/data/semantic_kitti" //FOR home 78 | autostart: false 79 | mode: "train" // train, test, val 80 | sequence: "all" //between 00 and 10 without 08, also can be "all" which means it will run through all sequences shuffled or not 81 | nr_clouds_to_skip: 0 82 | nr_clouds_to_read: -1 83 | //nr_clouds_to_read: 100 84 | cap_distance: 60 85 | shuffle_points: true 86 | do_pose: false 87 | normalize: false // normalize the point cloud between [-1 and 1] TAKES PRECEDENCE OVER THE POSE TRANSFORMATION 88 | shuffle: true 89 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 90 | //do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 91 | 92 | label_mngr: { 93 | // labels_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 94 | // color_scheme_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 95 | // frequency_file: "/home/local/staff/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 96 | 97 | //for infcuda2 98 | // labels_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/labels.txt" 99 | // color_scheme_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 100 | // frequency_file: "/home/user/rosu/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 101 | 102 | //for home 103 | labels_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/labels.txt" 104 | color_scheme_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/color_scheme.txt" 105 | frequency_file: "/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 106 | 107 | unlabeled_idx: 0 108 | } 109 | 110 | transformer: { 111 | random_translation_xyz_magnitude: 0.0 112 | random_translation_xz_magnitude: 20.0 113 | rotation_y_max_angle: 10.0 114 | random_stretch_xyz_magnitude: 0.0 115 | adaptive_subsampling_falloff_start: 0.0 116 | adaptive_subsampling_falloff_end: 0.0 117 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 118 | random_mirror_x: true 119 | random_mirror_z: true 120 | random_rotation_90_degrees_y: false 121 | hsv_jitter: [0,0,0] 122 | // chance_of_xyz_noise: 0.0 123 | // xyz_noise_stddev: [0.0, 0.0, 0.0] 124 | chance_of_xyz_noise: 0.0 125 | xyz_noise_stddev: [0.0, 0.0, 0.0] 126 | 127 | } 128 | } 129 | 130 | 131 | 132 | visualization: { 133 | show_gui: true 134 | 135 | subsample_factor: 1 136 | enable_culling: true 137 | 138 | cam: { 139 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 140 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 141 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 142 | exposure: 1.0 //can be floar or "auto" 143 | } 144 | 145 | ssao: { 146 | enable_ssao: false 147 | ao_downsample: 0 148 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 149 | ao_power: 4 150 | ao_blur_sigma_spacial: 2.0 151 | ao_blur_sigma_depth: 0.0001 152 | } 153 | 154 | edl: { 155 | auto_settings: true 156 | enable_edl_lighting: true 157 | edl_strength: 8.0 158 | } 159 | 160 | background:{ 161 | show_background_img: false 162 | background_img_path: "" 163 | } 164 | 165 | ibl: { 166 | enable_ibl: false 167 | show_environment_map: false 168 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 169 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 170 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 171 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 172 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 173 | // environment_cubemap_resolution: 2048 174 | environment_cubemap_resolution: 512 175 | irradiance_cubemap_resolution: 32 176 | prefilter_cubemap_resolution: 128 177 | brdf_lut_resolution: 512 178 | } 179 | 180 | lights:{ 181 | nr_spot_lights: 0 182 | spot_light_0: { 183 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 184 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 185 | create_shadow: true 186 | shadow_map_resolution: 2048 187 | } 188 | spot_light_1: { 189 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 190 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 191 | create_shadow: true 192 | shadow_map_resolution: 1024 193 | } 194 | spot_light_2: { 195 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 196 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 197 | create_shadow: true 198 | shadow_map_resolution: 1024 199 | } 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /config/lnn_train_shapenet.cfg: -------------------------------------------------------------------------------- 1 | core: { 2 | loguru_verbosity: 3 3 | hidpi: false 4 | debug_with_profiler: true //makes the profiler print when it starts and stops time 5 | } 6 | 7 | train: { 8 | dataset_name: "shapenet" //semantickitti, shapenet, toyexample 9 | with_viewer: false 10 | with_visdom: false 11 | with_tensorboard: false 12 | lr: 0.001 13 | weight_decay: 3e-4 14 | save_checkpoint: false 15 | checkpoint_path: "" 16 | } 17 | 18 | model: { 19 | positions_mode: "xyz" 20 | values_mode: "none" 21 | pointnet_channels_per_layer: [16,32,64] 22 | pointnet_start_nr_channels: 32 23 | nr_downsamples: 3 24 | nr_blocks_down_stage: [3,3,3] 25 | nr_blocks_bottleneck: 1 26 | nr_blocks_up_stage: [2,2,2] 27 | nr_levels_down_with_normal_resnet: 2 28 | nr_levels_up_with_normal_resnet: 2 29 | compression_factor: 1.0 30 | dropout_last_layer: 0.0 31 | 32 | //we run some experiments by setting the string here which if it's none then we run with the default full model: 33 | // none - default model with full features 34 | // slice_no_deform - doesn't use delta weights for the slicing, by setting them to zero 35 | // pointnet_no_elevate - doesn't elevate the distributed points into a higher dimensional space before doing the max but still substracts the local mean 36 | // pointnet_no_local_mean - doesn't perform the local mean substraction of the xyz positions and just uses them as is 37 | // pointnet_no_elevate_no_local_mean - doesnt elevate and doesnt do local mean 38 | // splat - just does a mean of all the features that fall into the lattice vertex without any elevatation or mean substraction 39 | // attention_pool - does an attention based pooling for pointnet instead of the maxpool 40 | // experiment: "none" 41 | } 42 | 43 | lattice_gpu: { 44 | hash_table_capacity: 60000 //good for shapenet which splat at around 1k for sigma 0.03 45 | nr_sigmas: 1 46 | 47 | // sigma_0: "0.06 3" //for bag IMPORTANT: if you change this, change it also int he lnn_eval.cfg 48 | sigma_0: "0.05 3" //for motorbike IMPORTANT: if you change this, change it also int he lnn_eval.cfg 49 | // sigma_0: "0.03 3" //for knife IMPORTANT: if you change this, change it also int he lnn_eval.cfg 50 | // sigma_0: "0.01 2" // IMPORTANT: if you change this, change it also int he lnn_eval.cfg 51 | // sigma_0: "0.055 3" //for table IMPORTANT: if you change this, change it also int he lnn_eval.cfg 52 | // sigma_0: "0.04 3" //for rocket IMPORTANT: if you change this, change it also int he lnn_eval.cfg 53 | // sigma_0: "0.06 3" //for cap IMPORTANT: if you change this, change it also int he lnn_eval.cfg 54 | // sigma_0: "0.06 3" //for car IMPORTANT: if you change this, change it also int he lnn_eval.cfg 55 | //finer lattice 56 | // sigma_0: "0.04 3" //for car IMPORTANT: if you change this, change it also int he lnn_eval.cfg 57 | 58 | } 59 | 60 | 61 | loader_shapenet_partseg: { 62 | dataset_path: "/media/rosu/Data/data/shapenet_part_seg/shapenet_part_seg/shapenetcore_partanno_segmentation_benchmark_v0" 63 | // dataset_path: "/home/local/staff/rosu/data/shapenet_part_seg/shapenet_part_seg/shapenetcore_partanno_segmentation_benchmark_v0" 64 | autostart: false 65 | mode: "train" // train, test, val 66 | restrict_to_object: "motorbike" // you can leave it empty to get all of them or write any of (airplane, bag, cap, car, chair, earphone, guitar, knife, lamp, laptop, motorbike, mug, pistol, rocket, skateboard, table) 67 | shuffle_points: true 68 | normalize: false // normalize the point cloud between [-1 and 1] 69 | shuffle: true 70 | // do_overfit: true //return only one of the samples the whole time, concretely the first sample in the dataset 71 | do_overfit: false //return only one of the samples the whole time, concretely the first sample in the dataset 72 | 73 | // one used for actual augmentation 74 | transformer: { 75 | random_translation_xyz_magnitude: [0.2, 0.0, 0.2] 76 | rotation_x_max_angle: 0.0 77 | rotation_y_max_angle: 0.0 78 | rotation_z_max_angle: 0.0 79 | // random_stretch_xyz_magnitude: 0.2 80 | random_stretch_xyz_magnitude: [0.0, 0.0, 0.0] 81 | adaptive_subsampling_falloff_start: 0.0 82 | adaptive_subsampling_falloff_end: 0.0 83 | // random_subsample_percentage: 0.998 //randomly removed x percent of the pointcloud 84 | random_subsample_percentage: 0.0 //randomly removed x percent of the pointcloud 85 | random_mirror_x: false 86 | random_mirror_y: false 87 | random_mirror_z: true 88 | random_rotation_90_degrees_y: false 89 | hsv_jitter: [0,0,0] 90 | chance_of_xyz_noise: 0.5 91 | xyz_noise_stddev: [0.001, 0.001, 0.001] 92 | } 93 | } 94 | 95 | 96 | 97 | visualization: { 98 | show_gui: true 99 | 100 | subsample_factor: 1 101 | enable_culling: true 102 | 103 | cam: { 104 | fov: 60 //can be a float value (fov: 30.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 105 | near: 0.3 //can be a float value (near: 0.01) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 106 | far: "auto" //can be a float value (far: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 107 | exposure: 1.0 //can be floar or "auto" 108 | } 109 | 110 | ssao: { 111 | enable_ssao: false 112 | ao_downsample: 0 113 | kernel_radius: "auto" //can be a float value (kernel_radius: 10,0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 114 | ao_power: 4 115 | ao_blur_sigma_spacial: 2.0 116 | ao_blur_sigma_depth: 0.0001 117 | } 118 | 119 | edl: { 120 | auto_settings: true 121 | enable_edl_lighting: true 122 | edl_strength: 8.0 123 | } 124 | 125 | background:{ 126 | show_background_img: false 127 | background_img_path: "" 128 | } 129 | 130 | ibl: { 131 | enable_ibl: false 132 | show_environment_map: false 133 | // environment_map_path: "/media/rosu/Data/data/sibl/Desert_Highway/Road_to_MonumentValley_Ref.hdr" 134 | // environment_map_path: "/media/rosu/Data/data/sibl/Footprint_Court/Footprint_Court_2k.hdr" 135 | // environment_map_path: "/media/rosu/Data/data/sibl/Circus_Backstage/Circus_Backstage_3k.hdr" 136 | // environment_map_path: "/media/rosu/Data/data/sibl/canary_wharf_4k.hdr" 137 | environment_map_path: "sibl/Barcelona_Rooftops/Barce_Rooftop_C_3k.hdr" 138 | // environment_cubemap_resolution: 2048 139 | environment_cubemap_resolution: 512 140 | irradiance_cubemap_resolution: 32 141 | prefilter_cubemap_resolution: 128 142 | brdf_lut_resolution: 512 143 | } 144 | 145 | lights:{ 146 | nr_spot_lights: 0 147 | spot_light_0: { 148 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 149 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 150 | create_shadow: true 151 | shadow_map_resolution: 2048 152 | } 153 | spot_light_1: { 154 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 155 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 156 | create_shadow: true 157 | shadow_map_resolution: 1024 158 | } 159 | spot_light_2: { 160 | power: "auto" //can be a float value (power: 1.0) or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 161 | color: "auto" //can be a vector of rgb [1.0, 1.0, 0.5] or can be set to "auto" so that it's set automatically when the first mesh is added to the scene 162 | create_shadow: true 163 | shadow_map_resolution: 1024 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/airplane/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 6 | 201, 28, 86 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/airplane/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 6 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/airplane/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 6 | part 5 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/bag/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/bag/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/bag/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/cap/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/cap/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/cap/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/car/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 6 | 201, 28, 86 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/car/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 6 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/car/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 6 | part 5 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/chair/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 6 | 201, 28, 86 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/chair/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 6 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/chair/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 6 | part 5 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/earphone/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/earphone/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/earphone/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/guitar/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/guitar/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/guitar/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/knife/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/knife/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/knife/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/lamp/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 6 | 201, 28, 86 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/lamp/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 6 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/lamp/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 6 | part 5 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/laptop/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/laptop/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/laptop/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/motorbike/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 6 | 201, 28, 86 7 | 255, 0, 0 8 | 30, 30, 25 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/motorbike/frequency.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 0.04679528528704627 4 | 0.039913798158681756 5 | 0.23515510467366446 6 | 0.015296428780859673 7 | 0.006500322523896089 8 | 0.6563390605758518 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/motorbike/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 6 | 1.0 7 | 1.0 8 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/motorbike/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 6 | part 5 7 | part 6 8 | part 7 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/mug/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/mug/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/mug/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/pistol/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/pistol/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/pistol/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/rocket/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/rocket/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/rocket/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/skateboard/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/skateboard/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/skateboard/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/table/color_scheme.txt: -------------------------------------------------------------------------------- 1 | #color scheme BGR format [0-255] 2 | 0, 0, 0 3 | 245, 150, 100 4 | 245, 230, 100 5 | 176, 70, 35 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/table/frequency_uniform.txt: -------------------------------------------------------------------------------- 1 | #frequency as a ratio to the total number of points 2 | 0.0 3 | 1.0 4 | 1.0 5 | 1.0 -------------------------------------------------------------------------------- /data/shapenet_part_seg/colorscheme_and_labels/table/labels.txt: -------------------------------------------------------------------------------- 1 | #label names 2 | part 1 3 | part 2 4 | part 3 5 | part 4 -------------------------------------------------------------------------------- /data/shapenet_part_seg/download_shapenet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 4 | 5 | ZIPPATH="${SCRIPTPATH}/shapenetcore_partanno_segmentation_benchmark_v0.zip" 6 | 7 | 8 | wget --no-check-certificate https://shapenet.cs.stanford.edu/ericyi/shapenetcore_partanno_segmentation_benchmark_v0.zip -P $SCRIPTPATH 9 | unzip $ZIPPATH -d $SCRIPTPATH 10 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check args 4 | if [ "$#" -ne 1 ]; then 5 | echo "usage: ./build.sh IMAGE_NAME" 6 | return 1 7 | fi 8 | 9 | # Get this script's path 10 | pushd `dirname $0` > /dev/null 11 | SCRIPTPATH=`pwd` 12 | popd > /dev/null 13 | #--build-arg workspace=$SCRIPTPATH\ 14 | 15 | # Build the docker image 16 | docker build\ 17 | --build-arg user=$USER\ 18 | --build-arg uid=$UID\ 19 | --build-arg home="/workspace"\ 20 | --build-arg workspace="/workspace"\ 21 | --build-arg shell=$SHELL\ 22 | -t $1 \ 23 | -f Dockerfile . 24 | -------------------------------------------------------------------------------- /docker/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | # AUTO_ADDED_PACKAGES=`apt-mark showauto` 4 | # 5 | # apt-get remove --purge -y $AUTO_ADDED_PACKAGES 6 | 7 | apt-get autoremove -y 8 | 9 | # . /build/cleanup.sh 10 | rm -rf /tmp/* /var/tmp/* 11 | 12 | apt-get clean 13 | rm -rf /var/lib/apt/lists/* 14 | -------------------------------------------------------------------------------- /docker/data/libeigen3-dev_3.3.7-3_all.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/docker/data/libeigen3-dev_3.3.7-3_all.deb -------------------------------------------------------------------------------- /docker/data/libeigen3-dev_3.4.0-2ubuntu2_all.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/docker/data/libeigen3-dev_3.4.0-2ubuntu2_all.deb -------------------------------------------------------------------------------- /docker/data/libgphoto2-6_2.5.22-3_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/docker/data/libgphoto2-6_2.5.22-3_amd64.deb -------------------------------------------------------------------------------- /docker/data/libgphoto2-dev_2.5.22-3_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/docker/data/libgphoto2-dev_2.5.22-3_amd64.deb -------------------------------------------------------------------------------- /docker/data/libgphoto2-port12_2.5.22-3_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/docker/data/libgphoto2-port12_2.5.22-3_amd64.deb -------------------------------------------------------------------------------- /docker/echo_to_file.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #check nr of arguments 3 | [ "$#" -eq 2 ] || die "2 argument required, $# provided. Usage: echo_to_file.sh FILE LINE" 4 | 5 | #echo into the file only if the line doesnt exist as per https://stackoverflow.com/a/28021305 6 | FILE=$1 7 | LINE=$2 8 | grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE" 9 | -------------------------------------------------------------------------------- /docker/lattice_env.yaml: -------------------------------------------------------------------------------- 1 | name: lattice 2 | channels: 3 | - defaults 4 | dependencies: 5 | - python=3.6 6 | # - _libgcc_mutex=0.1=main 7 | # - _pytorch_select=0.2=gpu_0 8 | # - blas=1.0=mkl 9 | # - ca-certificates=2020.1.1=0 10 | # - certifi=2020.4.5.1=py36_0 11 | # - cffi=1.14.0=py36h2e261b9_0 12 | # - cudatoolkit=10.1.243=h6bb024c_0 13 | # - cudnn=7.6.5=cuda10.1_0 14 | # - intel-openmp=2020.0=166 15 | # - ld_impl_linux-64=2.33.1=h53a641e_7 16 | # - libedit=3.1.20181209=hc058e9b_0 17 | # - libffi=3.2.1=hd88cf55_4 18 | # - libgcc-ng=9.1.0=hdf63c60_0 19 | # - libgfortran-ng=7.3.0=hdf63c60_0 20 | # - libstdcxx-ng=9.1.0=hdf63c60_0 21 | # - mkl=2020.0=166 22 | # - mkl-service=2.3.0=py36he904b0f_0 23 | # - mkl_fft=1.0.15=py36ha843d7b_0 24 | # - mkl_random=1.1.0=py36hd6b4f25_0 25 | # - ncurses=6.2=he6710b0_0 26 | # - ninja=1.9.0=py36hfd86e86_0 27 | # - numpy=1.18.1=py36h4f9e942_0 28 | # - numpy-base=1.18.1=py36hde5b4d6_1 29 | # - openssl=1.1.1f=h7b6447c_0 30 | # - pip=20.0.2=py36_1 31 | # - pycparser=2.20=py_0 32 | # - python=3.6.10=hcf32534_1 33 | # - pytorch=1.4.0=cuda101py36h02f0884_0 34 | # - readline=8.0=h7b6447c_0 35 | # - setuptools=46.1.3=py36_0 36 | # - six=1.14.0=py36_0 37 | # - sqlite=3.31.1=h7b6447c_0 38 | # - tk=8.6.8=hbc83047_0 39 | # - wheel=0.34.2=py36_0 40 | # - xz=5.2.4=h14c3975_4 41 | # - zlib=1.2.11=h7b6447c_3 42 | - pip: 43 | # - catkin-pkg==0.4.16 44 | # - chardet==3.0.4 45 | # - distro==1.5.0 46 | # - docutils==0.16 47 | # - idna==2.9 48 | # - jsonpatch==1.25 49 | # - jsonpointer==2.0 50 | - libtorch==1.2.0.1 51 | # - pillow==7.1.1 52 | # - pyparsing==2.4.7 53 | # - python-dateutil==2.8.1 54 | # - pyyaml==5.3.1 55 | # - pyzmq==19.0.0 56 | # - requests==2.23.0 57 | # - rospkg==1.2.4 58 | # - scipy==1.4.1 59 | # - termcolor==1.1.0 60 | # - torchfile==0.1.0 61 | # - torchnet==0.0.4 62 | # - tornado==6.0.4 63 | # - tqdm==4.45.0 64 | # - urllib3==1.25.8 65 | # - visdom==0.1.8.9 66 | # - websocket-client==0.57.0 67 | prefix: /opt/conda/envs/lattice 68 | 69 | -------------------------------------------------------------------------------- /docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check args 4 | if [ "$#" -ne 1 ]; then 5 | echo "usage: ./run.sh IMAGE_NAME" 6 | return 1 7 | fi 8 | 9 | # Get this script's path 10 | pushd `dirname $0` > /dev/null 11 | SCRIPTPATH=`pwd` 12 | popd > /dev/null 13 | 14 | set -e 15 | 16 | #the shm-size had to be increased to avoid bus error(core dumped) when using phoxi controller https://github.com/pytorch/pytorch/issues/2244#issuecomment-318864552 17 | #-v "$HOME:$HOME:rw"\ 18 | 19 | # Run the container with shared X11 20 | docker run\ 21 | --shm-size 2G\ 22 | --gpus all\ 23 | --publish-all=true\ 24 | --net=host\ 25 | --privileged\ 26 | -e SHELL\ 27 | -e DISPLAY\ 28 | -e DOCKER=1\ 29 | -e WORKSPACE="/workspace"\ 30 | -it $1 31 | -------------------------------------------------------------------------------- /docker/setup.sh: -------------------------------------------------------------------------------- 1 | echo "Performing setup of the system by writing some config files" 2 | #ros sourcing 3 | /echo_to_file.sh /.bashrc "source /opt/ros/melodic/setup.bash" 4 | 5 | #activate conda environment which is the same in which we install stuff in the Dockerfile 6 | # ./echo_to_file.sh ~/.bashrc "source activate pt" 7 | #make it so that conda doesnt modify the terminal line when we activate the conda environment 8 | #touch ~/.condarc 9 | #./echo_to_file.sh ~/.condarc "changeps1: false" 10 | -------------------------------------------------------------------------------- /imgs/code_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/code_1.png -------------------------------------------------------------------------------- /imgs/code_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/code_2.png -------------------------------------------------------------------------------- /imgs/code_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/code_3.png -------------------------------------------------------------------------------- /imgs/teaser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/teaser.png -------------------------------------------------------------------------------- /imgs/viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/viewer.png -------------------------------------------------------------------------------- /imgs/viewer_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/imgs/viewer_2.png -------------------------------------------------------------------------------- /include/lattice_net/EvalParams.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | //class used to read some network training parameters from a config file ( things like learnign rate and batch size ) This class is also exposed to python so it can be used in pytorch 7 | 8 | class EvalParams: public std::enable_shared_from_this 9 | { 10 | public: 11 | template 12 | static std::shared_ptr create( Args&& ...args ){ 13 | return std::shared_ptr( new EvalParams(std::forward(args)...) ); 14 | } 15 | 16 | bool with_viewer(); 17 | std::string dataset_name(); 18 | std::string checkpoint_path(); //points to the model that we want to load 19 | bool do_write_predictions(); 20 | std::string output_predictions_path(); 21 | 22 | 23 | 24 | private: 25 | EvalParams(const std::string config_file); 26 | void init_params(const std::string config_file); 27 | 28 | std::string m_dataset_name; 29 | bool m_with_viewer; //wether the training script will show in a viewer the gt_cloud and prediciton cloud 30 | std::string m_checkpoint_path; 31 | bool m_do_write_predictions; 32 | std::string m_output_predictions_path; 33 | }; -------------------------------------------------------------------------------- /include/lattice_net/HashTable.cuh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "torch/torch.h" 6 | 7 | 8 | class HashTableGPU; 9 | 10 | //adapted from https://github.com/MiguelMonteiro/permutohedral_lattice/blob/master/src/PermutohedralLatticeGPU.cuh 11 | class HashTable : public torch::nn::Module, public std::enable_shared_from_this { 12 | public: 13 | HashTable(const int capacity); 14 | void init(int pos_dim, int val_dim); 15 | 16 | int m_capacity; 17 | torch::Tensor m_keys_tensor; // size m_capacity x m_pos_dim of int 18 | torch::Tensor m_values_tensor; // Size m_capacity x m_val_dim of float 19 | torch::Tensor m_entries_tensor; // size m_capacity x 1 of int entries of the matrix for recording where the splatting happened for each point. The hash value h of the key is used to index into this tensor. the result is an index that points into the rows of the values and keys tensor where the corresponding key is stored 20 | torch::Tensor m_nr_filled_tensor; // 1x1 tensor of int storing the nr of filled cells of the keys and values tensor 21 | int m_nr_filled; //instead of reading all the time the nr_filled_tensor which requires syncronizing with the GPU, we read this when the value is not dirty 22 | bool m_nr_filled_is_dirty; 23 | // int m_pos_dim; 24 | 25 | //pointer to implementation 26 | std::shared_ptr m_impl; 27 | 28 | 29 | void clear(); 30 | void clear_only_values(); 31 | bool is_initialized(); 32 | void update_impl(); 33 | 34 | //getters 35 | int val_dim(); 36 | int pos_dim(); 37 | int capacity(); 38 | 39 | //setters 40 | void set_values(const torch::Tensor& new_values); //use this to set new values because it will also call update_impl to set the float pointers to the correct place in the implementation 41 | 42 | }; -------------------------------------------------------------------------------- /include/lattice_net/ModelParams.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | //class used to read some model parameters from a config file ( things like nr of layers and channels for each layer ) This class is also exposed to python so it can be used in pytorch 10 | 11 | class ModelParams: public std::enable_shared_from_this 12 | { 13 | public: 14 | template 15 | static std::shared_ptr create( Args&& ...args ){ 16 | return std::shared_ptr( new ModelParams(std::forward(args)...) ); 17 | } 18 | 19 | std::string positions_mode(); //the values we feed into the lattice can be either: xyz, xyz+rgb 20 | std::string values_mode(); //the values we feed into the lattice can be either: none, intensity 21 | Eigen::VectorXi pointnet_channels_per_layer(); 22 | int pointnet_start_nr_channels(); //after pointnet architecture we add one more fully connected layer to elevate the lattice vertices up to this nr_channels 23 | int nr_downsamples(); //the network uses this many corsening of the lattice graph 24 | std::vector nr_blocks_down_stage(); //each corsening stage inclues some amount of resnetblocks or bottleneck blocks. This says how many blocks for each stage we have 25 | int nr_blocks_bottleneck(); //after the last corsesning we have a certain amount of bottlneck blocks 26 | std::vector nr_blocks_up_stage(); 27 | int nr_levels_down_with_normal_resnet(); //starting from the top of the network (closer to the input) we count how many of the downsampling stages should include ResnetBlocks instead of BottleneckBlock (the first few stages have few channels so we can afford to use ResnetBlock instead of Bottleneck block) 28 | int nr_levels_up_with_normal_resnet(); //starting from the bottom of the network (closer to the output) we count how many of the upsampling stages should include ResnetBlocks instead of BottleneckBlocks (the first few stages have few channels so we can afford to use ResnetBlock instead of Bottleneck block) 29 | float compression_factor(); //each corsening of the graph increases the nr of channels by prev_nr_channels*2*compression_factor. So if the compression factor is 1.0 we will double the nr of channels 30 | float dropout_last_layer(); //Probability of dropout added to the last linear layer, the one that maps to the nr_classes and is just before the softmax 31 | // std::string experiment(); 32 | 33 | 34 | 35 | 36 | private: 37 | ModelParams(const std::string config_file); 38 | void init_params(const std::string config_file); 39 | 40 | std::string m_positions_mode; 41 | std::string m_values_mode; 42 | Eigen::VectorXi m_pointnet_channels_per_layer; 43 | int m_pointnet_start_nr_channels; 44 | int m_nr_downsamples; 45 | std::vector m_nr_blocks_down_stage; 46 | int m_nr_blocks_bottleneck; 47 | std::vector m_nr_blocks_up_stage; 48 | int m_nr_levels_down_with_normal_resnet; 49 | int m_nr_levels_up_with_normal_resnet; 50 | float m_compression_factor; 51 | float m_dropout_last_layer; 52 | 53 | // std::string m_experiment; 54 | 55 | }; -------------------------------------------------------------------------------- /include/lattice_net/PyBridge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | //pybind so you can read the cloud from python 5 | #include 6 | #include 7 | #include 8 | -------------------------------------------------------------------------------- /include/lattice_net/TrainParams.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | //class used to read some network training parameters from a config file ( things like learnign rate and batch size ) This class is also exposed to python so it can be used in pytorch 7 | 8 | class TrainParams: public std::enable_shared_from_this 9 | { 10 | public: 11 | template 12 | static std::shared_ptr create( Args&& ...args ){ 13 | return std::shared_ptr( new TrainParams(std::forward(args)...) ); 14 | } 15 | 16 | bool with_viewer(); 17 | bool with_visdom(); 18 | bool with_tensorboard(); 19 | std::string dataset_name(); 20 | float lr(); 21 | float weight_decay(); 22 | bool save_checkpoint(); 23 | std::string checkpoint_path(); 24 | 25 | 26 | private: 27 | TrainParams(const std::string config_file); 28 | void init_params(const std::string config_file); 29 | 30 | std::string m_dataset_name; 31 | bool m_with_viewer; //wether the training script will show in a viewer the gt_cloud and prediciton cloud 32 | bool m_with_visdom; 33 | bool m_with_tensorboard; 34 | float m_lr; 35 | float m_weight_decay; 36 | bool m_save_checkpoint; 37 | std::string m_checkpoint_path; 38 | 39 | }; -------------------------------------------------------------------------------- /include/lattice_net/jitify_helper/jitify_helper.cuh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //from https://github.com/lattice/quda/blob/develop/include/jitify_helper.cuh 4 | /** 5 | @file jitify_helper.cuh 6 | @brief Helper file when using jitify run-time compilation. This 7 | file should be included in source code, and not jitify.hpp 8 | directly. 9 | */ 10 | 11 | #include "lattice_net/jitify_helper/jitify_options.hpp" //Needs to be added BEFORE jitify because this defined the include paths so that the kernels can find each other 12 | #include 13 | 14 | 15 | static jitify::JitCache *kernel_cache = nullptr; 16 | // static jitify::Program *program = nullptr; 17 | static bool jitify_init = false; 18 | 19 | static jitify::Program create_jitify_program(const std::string file, const std::vector extra_options = {}) { 20 | 21 | if (!jitify_init) { 22 | jitify_init = true; 23 | kernel_cache = new jitify::JitCache; 24 | } 25 | 26 | // std::vector options = {"-std=c++11", "--generate-line-info", "-ftz=true", "-prec-div=false", "-prec-sqrt=false"}; 27 | // std::vector options = {"-std=c++11", "--generate-line-info"}; //https://stackoverflow.com/questions/41672506/how-do-i-direct-all-accesses-to-global-memory-in-cuda 28 | //-use_fast_math) implies --ftz=true --prec-div=false --prec-sqrt=false --fmad=true. 29 | std::vector options = {"-std=c++11", "--use_fast_math"}; 30 | 31 | // options.push_back(std::string("-G")); 32 | 33 | // add an extra compilation options specific to this instance 34 | for (auto option : extra_options) options.push_back(option); 35 | 36 | // program = new jitify::Program(kernel_cache->program(file, 0, options)); 37 | return kernel_cache->program(file, 0, options); 38 | } 39 | -------------------------------------------------------------------------------- /include/lattice_net/jitify_helper/jitify_options.hpp: -------------------------------------------------------------------------------- 1 | #define JITIFY_OPTIONS \ 2 | -I/media/rosu/Data/phd/c_ws/src/lattice_net/include \ 3 | -I/usr/local/lib/python3.6/dist-packages/torch/include;/usr/local/lib/python3.6/dist-packages/torch/include/torch/csrc/api/include 4 | -------------------------------------------------------------------------------- /include/lattice_net/jitify_helper/jitify_options.hpp.in: -------------------------------------------------------------------------------- 1 | #define JITIFY_OPTIONS \ 2 | -I${CMAKE_SOURCE_DIR}/include \ 3 | -I${TORCH_INCLUDE_DIRS} 4 | -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/callback.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/callback.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/phase.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/phase.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/scores.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/scores.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/state_callback.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/state_callback.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/tensorboard_callback.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/tensorboard_callback.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/viewer_callback.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/viewer_callback.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/vis.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/vis.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/__pycache__/visdom_callback.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/callbacks/__pycache__/visdom_callback.cpython-36.pyc -------------------------------------------------------------------------------- /latticenet_py/callbacks/callback.py: -------------------------------------------------------------------------------- 1 | #https://github.com/devforfu/pytorch_playground/blob/master/loop.ipynb 2 | 3 | import re 4 | 5 | def to_snake_case(string): 6 | """Converts CamelCase string into snake_case.""" 7 | 8 | s = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', string) 9 | return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s).lower() 10 | 11 | def classname(obj): 12 | return obj.__class__.__name__ 13 | 14 | 15 | class Callback: 16 | """ 17 | The base class inherited by callbacks. 18 | 19 | Provides a lot of hooks invoked on various stages of the training loop 20 | execution. The signature of functions is as broad as possible to allow 21 | flexibility and customization in descendant classes. 22 | """ 23 | def training_started(self, **kwargs): pass 24 | 25 | def training_ended(self, **kwargs): pass 26 | 27 | def epoch_started(self, **kwargs): pass 28 | 29 | def phase_started(self, **kwargs): pass 30 | 31 | def phase_ended(self, **kwargs): pass 32 | 33 | def epoch_ended(self, **kwargs): pass 34 | 35 | def batch_started(self, **kwargs): pass 36 | 37 | def batch_ended(self, **kwargs): pass 38 | 39 | def before_forward_pass(self, **kwargs): pass 40 | 41 | def after_forward_pass(self, **kwargs): pass 42 | 43 | def before_backward_pass(self, **kwargs): pass 44 | 45 | def after_backward_pass(self, **kwargs): pass 46 | 47 | 48 | class CallbacksGroup(Callback): 49 | """ 50 | Groups together several callbacks and delegates training loop 51 | notifications to the encapsulated objects. 52 | """ 53 | def __init__(self, callbacks): 54 | self.callbacks = callbacks 55 | self.named_callbacks = {to_snake_case(classname(cb)): cb for cb in self.callbacks} 56 | 57 | def __getitem__(self, item): 58 | item = to_snake_case(item) 59 | if item in self.named_callbacks: 60 | return self.named_callbacks[item] 61 | raise KeyError(f'callback name is not found: {item}') 62 | 63 | def training_started(self, **kwargs): self.invoke('training_started', **kwargs) 64 | 65 | def training_ended(self, **kwargs): self.invoke('training_ended', **kwargs) 66 | 67 | def epoch_started(self, **kwargs): self.invoke('epoch_started', **kwargs) 68 | 69 | def phase_started(self, **kwargs): self.invoke('phase_started', **kwargs) 70 | 71 | def phase_ended(self, **kwargs): self.invoke('phase_ended', **kwargs) 72 | 73 | def epoch_ended(self, **kwargs): self.invoke('epoch_ended', **kwargs) 74 | 75 | def batch_started(self, **kwargs): self.invoke('batch_started', **kwargs) 76 | 77 | def batch_ended(self, **kwargs): self.invoke('batch_ended', **kwargs) 78 | 79 | def before_forward_pass(self, **kwargs): self.invoke('before_forward_pass', **kwargs) 80 | 81 | def after_forward_pass(self, **kwargs): self.invoke('after_forward_pass', **kwargs) 82 | 83 | def before_backward_pass(self, **kwargs): self.invoke('before_backward_pass', **kwargs) 84 | 85 | def after_backward_pass(self, **kwargs): self.invoke('after_backward_pass', **kwargs) 86 | 87 | def invoke(self, method, **kwargs): 88 | for cb in self.callbacks: 89 | getattr(cb, method)(**kwargs) -------------------------------------------------------------------------------- /latticenet_py/callbacks/phase.py: -------------------------------------------------------------------------------- 1 | #https://github.com/devforfu/pytorch_playground/blob/master/loop.ipynbA 2 | 3 | from latticenet_py.callbacks.scores import * 4 | 5 | class Phase: 6 | """ 7 | Model training loop phase. 8 | 9 | Each model's training loop iteration could be separated into (at least) two 10 | phases: training and validation. The instances of this class track 11 | metrics and counters, related to the specific phase, and keep the reference 12 | to subset of data, used during phase. 13 | """ 14 | 15 | def __init__(self, name, loader, grad): 16 | self.name = name 17 | self.loader = loader 18 | self.grad = grad 19 | self.iter_nr = 0 20 | self.epoch_nr = 0 21 | self.samples_processed_this_epoch = 0 22 | self.scores= Scores() 23 | self.loss_acum_per_epoch=0.0 24 | # self.batch_loss = None 25 | # self.batch_index = 0 26 | # self.rolling_loss = 0 27 | # self.losses = [] 28 | # self.metrics = OrderedDict() 29 | 30 | # @property 31 | # def last_loss(self): 32 | # return self.losses[-1] if self.losses else None 33 | 34 | # @property 35 | # def last_metrics(self): 36 | # metrics = OrderedDict() 37 | # metrics[f'{self.name}_loss'] = self.last_loss 38 | # for name, values in self.metrics.items(): 39 | # metrics[f'{self.name}_{name}'] = values[-1] 40 | # return metrics 41 | 42 | # @property 43 | # def metrics_history(self): 44 | # metrics = OrderedDict() 45 | # for name, values in self.metrics.items(): 46 | # metrics[f'{self.name}_{name}'] = values 47 | # return metrics 48 | 49 | # def update(self, loss): 50 | # self.losses.append(loss) 51 | 52 | # def update_metric(self, name, value): 53 | # if name not in self.metrics: 54 | # self.metrics[name] = [] 55 | # self.metrics[name].append(value) -------------------------------------------------------------------------------- /latticenet_py/callbacks/scores.py: -------------------------------------------------------------------------------- 1 | 2 | import torchnet 3 | import numpy as np 4 | import torch 5 | import csv 6 | 7 | 8 | class Scores(): 9 | def __init__(self): 10 | # self.TPs=None 11 | # self.FPs=None 12 | # self.FNs=None 13 | # self.Total=None 14 | 15 | #attempt 2 16 | self.clear() 17 | 18 | 19 | # self.logger_iou = torchnet.logger.VisdomPlotLogger('line', opts={'title': 'logger_iou'}, port=port, env=node_name) 20 | 21 | #adapted from https://github.com/NVlabs/splatnet/blob/f7e8ca1eb16f6e1d528934c3df660bfaaf2d7f3b/splatnet/semseg3d/eval_seg.py 22 | def accumulate_scores(self, pred_softmax, gt, unlabeled_idx): 23 | # print("pred_softmax has shape, ", pred_softmax.shape) 24 | self.nr_classes=pred_softmax.shape[1] 25 | # self.nr_classes=nr_classes-1 #we dont take the background class into considertation for the evaluation 26 | # print("computing and accumulating iou") 27 | # print("pred_softmax after squeeze has shape, ", pred_softmax.shape) 28 | pred=pred_softmax.argmax(1) 29 | # print("pred has shape, ", pred.shape) 30 | gt=gt.detach() 31 | pred=pred.detach() 32 | 33 | # self.labels = np.unique(gt) 34 | self.labels = torch.unique(gt) # vector containing an index of the classes that are in the cloud. The order of them is not defined 35 | # assert np.all([(v in self.labels) for v in np.unique(pred)]) 36 | 37 | #instantiate the tps, fps, and so one to the nr of classes we have 38 | # if( self.TPs==None): 39 | # self.TPs = [0] * self.nr_classes 40 | # self.FPs = [0] * self.nr_classes 41 | # self.FNs = [0] * self.nr_classes 42 | # self.Total = [0] * self.nr_classes 43 | 44 | if( self.intersection_per_class==None): 45 | self.intersection_per_class = [0] * self.nr_classes 46 | self.union_per_class = [0] * self.nr_classes 47 | 48 | for i in range(len(self.labels)): 49 | l=self.labels[i] 50 | if not l==unlabeled_idx: 51 | # print("accumulating statistics for class ", l) 52 | # self.TPs[i]+=sum((gt == l) * (pred == l)) 53 | # self.FPs[i]+=sum((gt != l) * (pred == l)) 54 | # self.FNs[i]+=sum((gt == l) * (pred != l)) 55 | # self.Total[i]+=sum(gt == l) 56 | 57 | #attempt 2 58 | # self.TPs[l]+=((gt == l) * (pred == l)).sum().item() 59 | # self.FPs[l]+=((gt != l) * (pred == l)).sum().item() 60 | # self.FNs[l]+=((gt == l) * (pred != l)).sum().item() 61 | # self.Total[l]+=(gt == l).sum().item() 62 | 63 | #attempt 3 64 | current_intersection=((pred==gt)*(gt==l)).sum().item() 65 | self.intersection_per_class[l]+= current_intersection 66 | self.union_per_class[l]+= (gt==l).sum().item() + (pred==l).sum().item() - current_intersection 67 | 68 | def compute_stats(self, print_per_class_iou=False): 69 | valid_classes=0 70 | iou_sum=0 71 | 72 | # for i in range(self.nr_classes): 73 | # if( not self.Total[i]==0 ): 74 | # valid_classes+=1 75 | # iou=self.TPs[i] / (self.TPs[i] + self.FNs[i] + self.FPs[i]) 76 | # iou_sum+=iou 77 | # if print_per_class_iou: 78 | # print("class iou for idx", i, " is ", iou ) 79 | # avg_iou=iou_sum/valid_classes 80 | # return avg_iou 81 | 82 | #attempt 2 83 | iou_dict={} 84 | for i in range(self.nr_classes): 85 | if( self.union_per_class[i]>0 ): 86 | valid_classes+=1 87 | iou=self.intersection_per_class[i] / self.union_per_class[i] 88 | iou_sum+=iou 89 | if print_per_class_iou: 90 | print("class iou for idx", i, " is ", iou ) 91 | iou_dict[i]=iou 92 | avg_iou=iou_sum/valid_classes 93 | return avg_iou, iou_dict 94 | 95 | 96 | def avg_class_iou(self, print_per_class_iou=False): 97 | avg_iou, iou_dict= self.compute_stats(print_per_class_iou) 98 | return avg_iou 99 | 100 | def iou_per_class(self, print_per_class_iou=False): 101 | avg_iou, iou_dict= self.compute_stats(print_per_class_iou) 102 | return iou_dict 103 | 104 | def update_best(self): 105 | avg_iou, iou_dict= self.compute_stats(print_per_class_iou=False) 106 | if avg_iou>self.best_iou: 107 | self.best_iou=avg_iou 108 | self.best_iou_dict=iou_dict 109 | 110 | 111 | 112 | 113 | def show(self, epoch_nr): 114 | # self.scores['accuracy'] = sum(gt == pred) / len(gt) 115 | # # self.scores['confusion'] = confusion_matrix(gt, pred) 116 | # self.scores['class_accuracy'] = [self.TPs[i] / (self.TPs[i] + self.FNs[i]) for i in range(len(labels))] 117 | # self.scores['avg_class_accuracy'] = sum(scores['class_accuracy']) / len(labels) 118 | # self.scores['class_iou'] = [self.TPs[i] / (self.TPs[i] + self.FNs[i] + self.FPs[i]) for i in range(len(self.labels))] 119 | # self.scores['avg_class_iou'] = sum(self.scores['class_iou']) / len(self.labels) 120 | # self.scores['num_points'] = Total 121 | 122 | #the iou per class (only those that have any points in the gt) 123 | avg_iou=self.avg_class_iou(print_per_class_iou=True) 124 | # self.logger_iou.log(epoch_nr, avg_iou, name='Avg IoU') 125 | 126 | 127 | 128 | # for i in range( len(self.labels) ): 129 | # print("class iou for idx", i, " is ", self.scores['class_iou'][i] ) 130 | # print("true positives", self.TPs[i] ) 131 | 132 | # # print('-------------------- Summary --------------------') 133 | # # print(' Overall accuracy: {:.4f}'.format(scores['accuracy'])) 134 | # # print('Avg. class accuracy: {:.4f}'.format(scores['avg_class_accuracy'])) 135 | # print(' IoU: {:.4f}'.format(self.scores['avg_class_iou'])) 136 | # # print('-------------------- Breakdown --------------------') 137 | # # print(' class count(ratio) accuracy IoU') 138 | # # total_points = sum(scores['num_points']) 139 | # # for i in range(len(classes)): 140 | # # print('{:10} {:7d}({:4.1f}%) {:.4f} {:.4f}'.format(classes[i], scores['num_points'][i], 141 | # # 100 * scores['num_points'][i] / total_points, 142 | # # scores['class_accuracy'][i], scores['class_iou'][i])) 143 | # # print('-------------------- Confusion --------------------') 144 | # # print(' {}'.format(' '.join(['{:>7}'.format(v) for v in classes]))) 145 | # # for i, c in enumerate(classes): 146 | # # print('{:7} {}'.format(c, ' '.join(['{:7d}'.format(v) for v in scores['confusion'][i]]))) 147 | 148 | # ##log stuff 149 | # logger_iou.log(epoch_nr, self.scores['avg_class_iou'], name='Avg IoU') 150 | def clear(self): 151 | # self.TPs=None 152 | # self.FPs=None 153 | # self.FNs=None 154 | # self.Total=None 155 | # self.labels = None 156 | 157 | self.intersection_per_class=None 158 | self.union_per_class=None 159 | 160 | 161 | self.labels = None 162 | self.nr_classes =None 163 | 164 | #storing the best iou we got 165 | self.best_iou=-99999999 166 | self.best_iou_dict={} 167 | 168 | def start_fresh_eval(self): 169 | self.intersection_per_class=None 170 | self.union_per_class=None 171 | self.labels = None 172 | self.nr_classes =None 173 | 174 | def write_iou_to_csv(self,filename): 175 | iou_dict=self.iou_per_class(print_per_class_iou=False) 176 | avg_iou= self.avg_class_iou(print_per_class_iou=False) 177 | w = csv.writer(open(filename, "w")) 178 | for key, val in iou_dict.items(): 179 | w.writerow([key, val]) 180 | w.writerow(["mean_iou", avg_iou]) 181 | 182 | def write_best_iou_to_csv(self,filename): 183 | iou_dict=self.best_iou_dict 184 | best_iou=self.best_iou 185 | w = csv.writer(open(filename, "w")) 186 | for key, val in iou_dict.items(): 187 | w.writerow([key, val]) 188 | w.writerow(["best_iou", best_iou]) 189 | 190 | -------------------------------------------------------------------------------- /latticenet_py/callbacks/state_callback.py: -------------------------------------------------------------------------------- 1 | from latticenet_py.callbacks.callback import * 2 | import os 3 | import torch 4 | 5 | 6 | class StateCallback(Callback): 7 | 8 | def __init__(self): 9 | pass 10 | 11 | def after_forward_pass(self, phase, loss, pred_softmax, target, cloud, **kwargs): 12 | phase.iter_nr+=1 13 | phase.samples_processed_this_epoch+=1 14 | phase.loss_acum_per_epoch+=loss 15 | 16 | phase.scores.accumulate_scores(pred_softmax, target, cloud.m_label_mngr.get_idx_unlabeled() ) 17 | 18 | def epoch_started(self, phase, **kwargs): 19 | phase.loss_acum_per_epoch=0.0 20 | phase.scores.start_fresh_eval() 21 | 22 | def epoch_ended(self, phase, model, save_checkpoint, checkpoint_path, **kwargs): 23 | phase.scores.update_best() 24 | 25 | #for evaluation phase print the iou 26 | # if not phase.grad: 27 | mean_iou=phase.scores.avg_class_iou(print_per_class_iou=False) 28 | best_iou=phase.scores.best_iou 29 | best_iou_dict=phase.scores.best_iou_dict 30 | # print("iou for phase_", phase.name , " at epoch ", phase.epoch_nr , " is ", mean_iou, " best mean iou is ", best_iou, " with ious per classes \n" , best_iou_dict ) 31 | print("iou for phase_", phase.name , " at epoch ", phase.epoch_nr , " is ", mean_iou, " best mean iou is ", best_iou ) 32 | 33 | #save the checkpoint of the model if we are in testing mode 34 | if not phase.grad: 35 | if save_checkpoint and model is not None: 36 | model_name="model_e_"+str(phase.epoch_nr)+"_"+str( mean_iou )+".pt" 37 | info_txt_name="model_e_"+str(phase.epoch_nr)+"_info"+".csv" 38 | out_model_path=os.path.join(checkpoint_path, model_name) 39 | out_info_path=os.path.join(checkpoint_path, info_txt_name) 40 | torch.save(model.state_dict(), out_model_path) 41 | phase.scores.write_iou_to_csv(out_info_path) 42 | 43 | 44 | phase.epoch_nr+=1 45 | 46 | def phase_started(self, phase, **kwargs): 47 | phase.samples_processed_this_epoch=0 48 | 49 | def phase_ended(self, phase, **kwargs): 50 | # phase.loader.reset() 51 | 52 | if(type(phase.loader) == torch.utils.data.DataLoader): # pytorchs dataloder has no reset 53 | pass 54 | else: 55 | phase.loader.reset() 56 | -------------------------------------------------------------------------------- /latticenet_py/callbacks/tensorboard_callback.py: -------------------------------------------------------------------------------- 1 | from latticenet_py.callbacks.callback import * 2 | from torch.utils.tensorboard import SummaryWriter 3 | 4 | class TensorboardCallback(Callback): 5 | 6 | def __init__(self, experiment_name): 7 | self.tensorboard_writer = SummaryWriter("tensorboard_logs/"+experiment_name) 8 | self.experiment_name=experiment_name 9 | 10 | 11 | def after_forward_pass(self, phase, loss, loss_dice, lr, pred_softmax, target, cloud, **kwargs): 12 | # self.vis.log(phase.iter_nr, loss, "loss_"+phase.name, "loss_"+phase.name+"_"+self.experiment_name, smooth=True, show_every=10, skip_first=10) 13 | # self.vis.log(phase.iter_nr, loss_dice, "loss_dice_"+phase.name, "loss_"+phase.name+"_"+self.experiment_name, smooth=True, show_every=10, skip_first=10) 14 | # if phase.grad: 15 | # self.vis.log(phase.iter_nr, lr, "lr", "loss_"+phase.name+"_"+self.experiment_name, smooth=False, show_every=30) 16 | self.tensorboard_writer.add_scalar('LatticeNet/' + phase.name + '/loss', loss, phase.iter_nr) 17 | 18 | 19 | def epoch_ended(self, phase, **kwargs): 20 | mean_iou=phase.scores.avg_class_iou(print_per_class_iou=False) 21 | self.tensorboard_writer.add_scalar('LatticeNet/' + phase.name + '/mean_iou', mean_iou, phase.epoch_nr) 22 | # self.vis.log(phase.epoch_nr, mean_iou, "iou_"+phase.name, "loss_"+phase.name+"_"+self.experiment_name, smooth=False, show_every=1) -------------------------------------------------------------------------------- /latticenet_py/callbacks/viewer_callback.py: -------------------------------------------------------------------------------- 1 | from latticenet_py.callbacks.callback import * 2 | from easypbr import Scene 3 | import numpy as np 4 | 5 | class ViewerCallback(Callback): 6 | 7 | def __init__(self): 8 | pass 9 | 10 | def after_forward_pass(self, pred_softmax, cloud, **kwargs): 11 | self.show_predicted_cloud(pred_softmax, cloud) 12 | # self.show_difference_cloud(pred_softmax, cloud) 13 | 14 | 15 | def show_predicted_cloud(self, pred_softmax, cloud): 16 | mesh_pred=cloud.clone() 17 | l_pred=pred_softmax.detach().argmax(axis=1).cpu().numpy() 18 | mesh_pred.L_pred=l_pred 19 | mesh_pred.m_vis.m_point_size=4 20 | mesh_pred.m_vis.set_color_semanticpred() 21 | # mesh_pred.move_in_z(cloud.get_scale()) 22 | Scene.show(mesh_pred, "mesh_pred") 23 | 24 | def show_difference_cloud(self,pred_softmax, cloud): 25 | has_gt= cloud.L_gt.size != 0 26 | 27 | if has_gt: 28 | mesh_pred=cloud.clone() 29 | l_pred=pred_softmax.detach().argmax(axis=1).cpu().numpy() #(nr_points, ) 30 | l_gt=cloud.L_gt #(nr_points,1) 31 | l_pred=np.expand_dims(l_pred,1) #(nr_points,1) 32 | 33 | diff=l_pred!=cloud.L_gt 34 | diff_repeated=np.repeat(diff, 3,1) #repeat 3 times on axis 1 so to obtain a (nr_points,3) 35 | 36 | mesh_pred.C=diff_repeated 37 | mesh_pred.m_vis.m_point_size=4 38 | mesh_pred.m_vis.set_color_pervertcolor() 39 | # mesh_pred.move_in_z(-cloud.get_scale()) #good for shapenetpartseg 40 | mesh_pred.translate_model_matrix([0.0, 0.0, -2.0]) #good for shapenetpartseg 41 | Scene.show(mesh_pred, "mesh_diff") 42 | 43 | def show_confidence_cloud(self, pred_softmax, cloud): 44 | mesh_pred=cloud.clone() 45 | l_pred_confidence,_=pred_softmax.detach().exp().max(axis=1) 46 | l_pred_confidence=l_pred_confidence.cpu().numpy() #(nr_points, ) 47 | l_pred_confidence=np.expand_dims(l_pred_confidence,1) #(nr_points,1) 48 | l_pred_confidence=np.repeat(l_pred_confidence, 3,1) #repeat 3 times on axis 1 so to obtain a (nr_points,3) 49 | 50 | mesh_pred.C=l_pred_confidence 51 | mesh_pred.m_vis.m_point_size=4 52 | mesh_pred.m_vis.set_color_pervertcolor() 53 | # mesh_pred.move_in_z(-cloud.get_scale()) #good for shapenetpartseg 54 | # mesh_pred.move_in_z(-1.0) #good for shapenetpartseg 55 | Scene.show(mesh_pred, "mesh_confidence") 56 | 57 | 58 | def show_pca_of_features_cloud(self, per_point_features, cloud): 59 | mesh=cloud.clone() 60 | 61 | 62 | ## http://agnesmustar.com/2017/11/01/principal-component-analysis-pca-implemented-pytorch 63 | X=per_point_features.detach().squeeze(0).cpu()#we switch to cpu because svd for gpu needs magma: No CUDA implementation of 'gesdd'. Install MAGMA and rebuild cutorch (http://icl.cs.utk.edu/magma/) at /opt/pytorch/aten/src/THC/generic/THCTensorMathMagma.cu:191 64 | k=3 65 | # print("x is ", X.shape) 66 | X_mean = torch.mean(X,0) 67 | # print("x_mean is ", X_mean.shape) 68 | X = X - X_mean.expand_as(X) 69 | 70 | U,S,V = torch.svd(torch.t(X)) 71 | C = torch.mm(X,U[:,:k]) 72 | # print("C has shape ", C.shape) 73 | # print("C min and max is ", C.min(), " ", C.max() ) 74 | C-=C.min() 75 | C/=C.max() 76 | # print("after normalization C min and max is ", C.min(), " ", C.max() ) 77 | 78 | 79 | mesh.C=C.detach().cpu().numpy() 80 | mesh.m_vis.m_point_size=10 81 | mesh.m_vis.set_color_pervertcolor() 82 | mesh.move_in_z(-2*cloud.get_scale()) #good for shapenetpartseg 83 | Scene.show(mesh, "mesh_pca") 84 | -------------------------------------------------------------------------------- /latticenet_py/callbacks/vis.py: -------------------------------------------------------------------------------- 1 | import torchnet 2 | import numpy as np 3 | import torch 4 | 5 | node_name="lnn" 6 | port=8097 7 | # logger_iou = torchnet.logger.VisdomPlotLogger('line', opts={'title': 'logger_iou'}, port=port, env='train_'+node_name) 8 | 9 | 10 | class Vis(): 11 | def __init__(self, env, port): 12 | self.port=port 13 | self.env=env 14 | # self.win_id="0" 15 | self.win_id=None 16 | 17 | self.name_dict=dict() #maps from name of the plot to the values that are stored currectly for that plot 18 | self.name2id_dict=dict() #maps from the name of the plot to the windows id 19 | self.logger_dict=dict() 20 | self.exp_alpha=0.03 #the lower the value the smoother the plot is 21 | 22 | def update_val(self, val, name, smooth): 23 | if name not in self.name_dict: 24 | self.name2id_dict[name] = str(len(self.name_dict)) 25 | self.name_dict[name]=val 26 | else: 27 | if smooth: 28 | self.name_dict[name]= self.name_dict[name] + self.exp_alpha*(val-self.name_dict[name]) 29 | else: 30 | self.name_dict[name]=val 31 | 32 | return self.name_dict[name] 33 | 34 | def update_logger(self, x_axis, val, name_window, name_plot): 35 | if name_window not in self.logger_dict: 36 | self.logger_dict[name_window]=torchnet.logger.VisdomPlotLogger('line', opts={'title': name_window}, port=self.port, env=self.env, win=self.win_id) 37 | # self.logger_dict[name_window]=torchnet.logger.VisdomPlotLogger('line', opts={'title': name_window}, port=self.port, env=self.env, win=self.name2id_dict[name_plot] ) 38 | print("started new line plot on win ", self.logger_dict[name_window].win) 39 | 40 | # print("update_logger val is ", val, "name plot is ", name_plot) 41 | self.logger_dict[name_window].log(x_axis, val, name=name_plot) 42 | 43 | def log(self, x_axis, val, name_window, name_plot, smooth, show_every=1, skip_first=0): 44 | if (x_axis 1: # cover 1-pixel case 19 | jaccard[1:p] = jaccard[1:p] - jaccard[0:-1] 20 | return jaccard 21 | 22 | 23 | class LovaszSoftmax(nn.Module): 24 | def __init__(self, ignore_index, reduction='mean'): 25 | super(LovaszSoftmax, self).__init__() 26 | self.reduction = reduction 27 | self.ignore_index=ignore_index 28 | 29 | def prob_flatten(self, input, target): 30 | assert input.dim() in [2] 31 | num_class = input.size(1) 32 | # if input.dim() == 4: 33 | # input = input.permute(0, 2, 3, 1).contiguous() 34 | input_flatten = input.view(-1, num_class) 35 | # elif input.dim() == 5: 36 | # input = input.permute(0, 2, 3, 4, 1).contiguous() 37 | # input_flatten = input.view(-1, num_class) 38 | target_flatten = target.view(-1) 39 | return input_flatten, target_flatten 40 | 41 | def lovasz_softmax_flat(self, inputs, targets): 42 | num_classes = inputs.size(1) 43 | losses = [] 44 | for c in range(num_classes): 45 | if c!=self.ignore_index: 46 | target_c = (targets == c).float() 47 | nr_pixels_gt_for_this_class=target_c.sum() 48 | if nr_pixels_gt_for_this_class==0: 49 | continue #as described in the paper, we skip the penalty for the classes that are not present in this sample 50 | if num_classes == 1: 51 | input_c = inputs[:, 0] 52 | else: 53 | input_c = inputs[:, c] 54 | loss_c = (torch.autograd.Variable(target_c) - input_c).abs() 55 | loss_c_sorted, loss_index = torch.sort(loss_c, 0, descending=True) 56 | target_c_sorted = target_c[loss_index] 57 | losses.append(torch.dot(loss_c_sorted, torch.autograd.Variable(lovasz_grad(target_c_sorted)))) 58 | losses = torch.stack(losses) 59 | 60 | if self.reduction == 'none': 61 | loss = losses 62 | elif self.reduction == 'sum': 63 | loss = losses.sum() 64 | else: 65 | loss = losses.mean() 66 | return loss 67 | 68 | def forward(self, inputs, targets): 69 | inputs=inputs.exp() 70 | inputs, targets = self.prob_flatten(inputs, targets) 71 | losses = self.lovasz_softmax_flat(inputs, targets) 72 | return losses 73 | -------------------------------------------------------------------------------- /latticenet_py/ln_eval_cloud_ros.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | import torch 4 | 5 | import sys 6 | import os 7 | import numpy as np 8 | from tqdm import tqdm 9 | 10 | from easypbr import * 11 | from dataloaders import * 12 | from latticenet import TrainParams 13 | from latticenet import ModelParams 14 | from latticenet import EvalParams 15 | # from lattice.lattice_py import LatticePy 16 | from lattice.models import * 17 | 18 | from callbacks.callback import * 19 | from callbacks.viewer_callback import * 20 | from callbacks.visdom_callback import * 21 | from callbacks.state_callback import * 22 | from callbacks.phase import * 23 | 24 | #semantickitt on infcuda2 25 | 26 | 27 | config_file="ln_eval_cloud_ros.cfg" 28 | 29 | torch.manual_seed(0) 30 | 31 | # #initialize the parameters used for training 32 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../config', config_file) 33 | eval_params=EvalParams.create(config_path) 34 | model_params=ModelParams.create(config_path) 35 | 36 | def write_prediction(pred_softmax, cloud, pred_path): 37 | mesh_pred=cloud.clone() 38 | l_pred=pred_softmax.detach().argmax(axis=1).cpu().numpy() 39 | #l_pred=l_pred.unsqueeze(1) 40 | l_pred = np.expand_dims(l_pred, axis=1) 41 | #print("l_pred has shape ", l_pred.shape) 42 | mesh_pred.color_from_label_indices(l_pred) 43 | mesh_pred.L_pred=l_pred 44 | mesh_pred.save_to_file(pred_path) 45 | 46 | def write_gt(cloud, gt_path): 47 | mesh_gt=cloud.clone() 48 | mesh_gt.color_from_label_indices(cloud.L_gt) 49 | mesh_gt.save_to_file(gt_path) 50 | 51 | 52 | def run(): 53 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../config', config_file) 54 | if eval_params.with_viewer(): 55 | view=Viewer.create(config_path) 56 | 57 | first_time=True 58 | 59 | #torch stuff 60 | # lattice=LatticePy() 61 | # lattice.create(config_path, "splated_lattice") 62 | lattice=Lattice.create(config_path, "lattice") 63 | 64 | cb_list = [] 65 | # if(eval_params.with_viewer()): 66 | # cb_list.append(ViewerCallback()) 67 | cb_list.append(StateCallback()) 68 | cb = CallbacksGroup(cb_list) 69 | 70 | #create loaders 71 | # loader_test=create_loader(eval_params.dataset_name(), config_path) 72 | # loader_test.set_mode_test() 73 | bag=RosBagPlayer.create(config_path) 74 | loader=DataLoaderCloudRos(config_path) 75 | label_file="/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/labels.txt" 76 | colorscheme_file="/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/color_scheme_compacted_colors.txt" 77 | freq_file="/media/rosu/Data/data/semantic_kitti/colorscheme_and_labels/frequency.txt" 78 | label_mngr=LabelMngr(label_file, colorscheme_file, freq_file, 0) 79 | 80 | #create phases 81 | phases= [ 82 | Phase('test', loader, grad=False) 83 | ] 84 | #model 85 | model=LNN(label_mngr.nr_classes(), model_params ).to("cuda") 86 | 87 | predictions_list=[] 88 | scores_list=[] 89 | 90 | while loader.is_loader_thread_alive(): 91 | 92 | for phase in phases: 93 | cb.epoch_started(phase=phase) 94 | cb.phase_started(phase=phase) 95 | model.train(phase.grad) 96 | 97 | # pbar = tqdm(total=phase.loader.nr_samples()) 98 | pbar = tqdm(total=100000) 99 | # while ( phase.samples_processed_this_epoch < phase.loader.nr_samples()): 100 | while loader.is_loader_thread_alive(): 101 | 102 | # print("phase.loader.has_data()", phase.loader.has_data()) 103 | if(phase.loader.has_data()): 104 | cloud=phase.loader.get_cloud() 105 | cloud.m_label_mngr=label_mngr 106 | 107 | is_training = phase.grad 108 | 109 | #forward 110 | with torch.set_grad_enabled(is_training): 111 | cb.before_forward_pass(lattice=lattice) #sets the appropriate sigma for the lattice 112 | positions, values, target = prepare_cloud(cloud, model_params) #prepares the cloud for pytorch, returning tensors alredy in cuda 113 | TIME_START("forward") 114 | pred_logsoftmax, pred_raw =model(lattice, positions, values) 115 | TIME_END("forward") 116 | 117 | 118 | #debug 119 | #l_pred=pred_logsoftmax.detach().argmax(axis=1).cpu().numpy() 120 | #nr_zeros= l_pred ==0 121 | #nr_zeros=nr_zeros.sum() 122 | #print("nr_zeros is ", nr_zeros) 123 | 124 | 125 | #if its the first time we do a forward on the model we need to load here the checkpoint 126 | if first_time: 127 | first_time=False 128 | #TODO load checkpoint 129 | # now that all the parameters are created we can fill them with a model from a file 130 | model.load_state_dict(torch.load(eval_params.checkpoint_path())) 131 | #need to rerun forward with the new parameters to get an accurate prediction 132 | pred_logsoftmax, pred_raw =model(lattice, positions, values) 133 | 134 | 135 | cb.after_forward_pass(pred_softmax=pred_logsoftmax, target=target, cloud=cloud, loss=0, loss_dice=0, phase=phase, lr=0) #visualizes the prediction 136 | pbar.update(1) 137 | 138 | #show and accumulate the cloud 139 | if(eval_params.with_viewer()): 140 | mesh_pred=cloud.clone() 141 | l_pred=pred_logsoftmax.detach().argmax(axis=1).cpu().numpy() 142 | mesh_pred.L_pred=l_pred 143 | mesh_pred.m_vis.m_point_size=4 144 | mesh_pred.m_vis.set_color_semanticpred() 145 | # Scene.show(mesh_pred, "mesh_pred_"+str(phase.iter_nr) ) 146 | Scene.show(mesh_pred, "mesh_pred" ) 147 | 148 | # #get only the points that correspond to person 149 | # person_idx=label_mngr.label2idx("person") 150 | # mask_static=l_pred!=person_idx #is a vector of 1 for the point that are NOT person 151 | # mesh_dyn=mesh_pred.clone() 152 | # new_V=mesh_dyn.V.copy() 153 | # new_V[mask_static]=0 154 | # mesh_dyn.V=new_V 155 | # Scene.show(mesh_dyn, "mesh_dyn" ) 156 | 157 | 158 | 159 | 160 | 161 | # if phase.loader.is_finished(): 162 | # pbar.close() 163 | # cb.epoch_ended(phase=phase, model=model, save_checkpoint=False, checkpoint_path="" ) 164 | # cb.phase_ended(phase=phase) 165 | # return 166 | 167 | 168 | if eval_params.with_viewer(): 169 | view.update() 170 | 171 | 172 | def main(): 173 | run() 174 | 175 | 176 | 177 | if __name__ == "__main__": 178 | main() # This is what you would have, but the following is useful: 179 | 180 | # # These are temporary, for debugging, so meh for programming style. 181 | # import sys, trace 182 | 183 | # # If there are segfaults, it's a good idea to always use stderr as it 184 | # # always prints to the screen, so you should get as much output as 185 | # # possible. 186 | # sys.stdout = sys.stderr 187 | 188 | # # Now trace execution: 189 | # tracer = trace.Trace(trace=1, count=0, ignoredirs=["/usr", sys.prefix]) 190 | # tracer.run('main()' 191 | -------------------------------------------------------------------------------- /latticenet_py/misc/check_minkowksi_pred.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | 4 | import os 5 | import numpy as np 6 | import sys 7 | try: 8 | import torch 9 | except ImportError: 10 | pass 11 | from easypbr import * 12 | from dataloaders import * 13 | 14 | 15 | config_file="lnn_compare_semantic_kitti.cfg" 16 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../../config', config_file) 17 | view=Viewer.create(config_path) #first because it needs to init context 18 | 19 | loader=DataLoaderSemanticKitti(config_path) 20 | loader.start() 21 | 22 | arr=np.load("/home/rosu/Downloads/prediction.npz") 23 | data=arr["arr_0"] 24 | print("data has shape ", data.shape) 25 | 26 | mesh=Mesh() 27 | mesh.V=data[:,0:3] 28 | print("V is ", mesh.V.shape) 29 | mesh.L_pred=data[:,3:4] 30 | print("pred is ", mesh.L_pred.shape) 31 | 32 | 33 | while True: 34 | 35 | if(loader.has_data()): 36 | cloud=loader.get_cloud() 37 | 38 | mesh.m_label_mngr=cloud.m_label_mngr 39 | mesh.m_vis.m_show_points=True 40 | Scene.show(mesh,"mesh") 41 | 42 | view.update() -------------------------------------------------------------------------------- /latticenet_py/misc/compute_class_frequency.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | import torch 4 | from torch.autograd import Function 5 | from torch import Tensor 6 | 7 | import sys 8 | import os 9 | import numpy as np 10 | # http://wiki.ros.org/Packages#Client_Library_Support 11 | import rospkg 12 | rospack = rospkg.RosPack() 13 | sf_src_path=rospack.get_path('surfel_renderer') 14 | sf_build_path=os.path.abspath(sf_src_path + "/../../build/surfel_renderer") 15 | sys.path.append(sf_build_path) #contains the modules of pycom 16 | 17 | from DataLoaderTest import * 18 | 19 | 20 | config_file="compute_class_frequency.cfg" 21 | 22 | 23 | 24 | 25 | def run(): 26 | view=Viewer(config_file) 27 | # loader=DataLoaderSemanticKitti(config_file) 28 | loader=DataLoaderShapeNetPartSeg(config_file) 29 | loader.start() 30 | nr_total_points=0 31 | nr_points_of_class=None 32 | nr_classes=0 33 | 34 | 35 | while True: 36 | view.update() 37 | 38 | if(loader.has_data()): 39 | print("got cloud") 40 | cloud=loader.get_cloud() 41 | cloud.m_vis.m_point_size=4 42 | Scene.show(cloud,"cloud") 43 | 44 | nr_classes=cloud.m_label_mngr.nr_classes() 45 | if nr_points_of_class is None: 46 | nr_points_of_class=np.zeros(nr_classes) 47 | nr_total_points+=cloud.V.shape[0] 48 | # print("adding to total nr of points", cloud.V.shape[0], " updated is ", nr_total_points ) 49 | for i in range(nr_classes): 50 | nr_points_of_class[i]+=(cloud.L_gt==i).sum() 51 | # print("adding for class ", i, " nr of points ", (cloud.L_gt==i).sum(), " updated nr is now ", nr_points_of_class[i] ) 52 | 53 | if loader.is_finished(): 54 | print("frequencies are:") 55 | for i in range(nr_classes): 56 | print(nr_points_of_class[i]/nr_total_points) 57 | # return 58 | 59 | 60 | def main(): 61 | run() 62 | 63 | 64 | 65 | if __name__ == "__main__": 66 | main() # This is what you would have, but the following is useful: 67 | 68 | # # These are temporary, for debugging, so meh for programming style. 69 | # import sys, trace 70 | 71 | # # If there are segfaults, it's a good idea to always use stderr as it 72 | # # always prints to the screen, so you should get as much output as 73 | # # possible. 74 | # sys.stdout = sys.stderr 75 | 76 | # # Now trace execution: 77 | # tracer = trace.Trace(trace=1, count=0, ignoredirs=["/usr", sys.prefix]) 78 | # tracer.run('main()') -------------------------------------------------------------------------------- /latticenet_py/misc/lnn_check_lattice_size.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import numpy as np 5 | import sys 6 | try: 7 | import torch 8 | except ImportError: 9 | pass 10 | from easypbr import * 11 | from dataloaders import * 12 | 13 | 14 | config_file="lnn_check_lattice_size.cfg" 15 | 16 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../../config', config_file) 17 | view=Viewer.create(config_path) #first because it needs to init context 18 | 19 | loader=DataLoaderScanNet(config_path) 20 | loader.start() 21 | 22 | nr_points_in_radius=[] 23 | 24 | while True: 25 | if(loader.has_data()): 26 | cloud=loader.get_cloud() 27 | Scene.show(cloud, "cloud") 28 | 29 | random_point=cloud.V[1,:] 30 | # print("random point is ", random_point) 31 | nr_points=cloud.radius_search(random_point, 0.05) 32 | 33 | nr_points_in_radius.append(nr_points) 34 | print("mean_nr_points: ", np.mean(nr_points_in_radius)) 35 | 36 | 37 | view.update() -------------------------------------------------------------------------------- /latticenet_py/misc/lnn_compare_semantic_kitti.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | 4 | import os 5 | import numpy as np 6 | import sys 7 | try: 8 | import torch 9 | except ImportError: 10 | pass 11 | from easypbr import * 12 | from dataloaders import * 13 | 14 | 15 | config_file="lnn_compare_semantic_kitti.cfg" 16 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../../config', config_file) 17 | view=Viewer.create(config_path) #first because it needs to init context 18 | 19 | loader=DataLoaderSemanticKitti(config_path) 20 | loader.start() 21 | 22 | 23 | # mesh=Mesh("/media/rosu/Data/data/semantic_kitti/predictions/final_7_amsgrad_iou/18_pred.ply") 24 | # max_dist=-1 25 | # for i in range(mesh.V.shape[0]): 26 | # point=mesh.V[i,:] 27 | # dist=np.linalg.norm(point) 28 | # if dist>max_dist: 29 | # max_dist=dist 30 | # print("max_dist is " , max_dist) 31 | 32 | while True: 33 | 34 | if(loader.has_data()): 35 | cloud=loader.get_cloud() 36 | # Scene.show(cloud, "gt") 37 | 38 | #nice 39 | seq="19" 40 | cloud_name="004597" 41 | # seq="18" 42 | # cloud_name="001523" 43 | 44 | point_size=12 45 | 46 | 47 | #load gt 48 | # gt=Mesh("/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test/19/000535_gt.ply") 49 | gt=Mesh("/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test/"+seq+"/"+cloud_name+"_gt.ply") 50 | gt.m_vis.m_point_size=point_size 51 | Scene.show(gt, "gt") 52 | 53 | 54 | #load my prediction 55 | # my_pred=Mesh("/media/rosu/Data/data/semantic_kitti/predictions/final_7_amsgrad_iou/18_pred.ply") 56 | # my_pred=Mesh("/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test/19/000535_pred.ply") 57 | # my_pred_file="/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test/19/000535.label" 58 | my_pred_file="/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test/"+seq+"/"+cloud_name+".label" 59 | my_pred=gt.clone() 60 | my_pred.m_vis.m_point_size=point_size 61 | f = open(my_pred_file, "r") 62 | a = np.loadtxt(my_pred_file) 63 | my_pred.m_label_mngr=cloud.m_label_mngr 64 | my_pred.L_pred=a 65 | my_pred.m_vis.set_color_semanticpred() 66 | Scene.show(my_pred, "my_pred") 67 | 68 | 69 | 70 | #load also the prediction from splatnet 71 | # splatnet_pred_file="/media/rosu/Data/data/semantic_kitti/predictions_from_related_work/splatnet_semantic_kitti_single_frame_final_predictions_11_21/15/predictions/001700.label" 72 | splatnet_pred_file="/media/rosu/Data/data/semantic_kitti/predictions_from_related_work/splatnet_semantic_kitti_single_frame_final_predictions_11_21/"+seq+"/predictions/"+cloud_name+".label" 73 | cloud_splatnet=my_pred.clone() 74 | cloud_splatnet.m_vis.m_point_size=point_size 75 | f = open(splatnet_pred_file, "r") 76 | a = np.fromfile(f, dtype=np.uint32) 77 | cloud_splatnet.L_pred=a 78 | cloud_splatnet.m_vis.set_color_semanticpred() 79 | Scene.show(cloud_splatnet, "splatnet") 80 | 81 | #load also the prediction from tangentconv 82 | # tangentconv_pred_file="/media/rosu/Data/data/semantic_kitti/predictions_from_related_work/tangent_conv_semantic_kitti_single_frame_final_predictions_11_21/15/001700.label" 83 | tangentconv_pred_file="/media/rosu/Data/data/semantic_kitti/predictions_from_related_work/tangent_conv_semantic_kitti_single_frame_final_predictions_11_21/"+seq+"/"+cloud_name+".label" 84 | cloud_tangentconv=my_pred.clone() 85 | cloud_tangentconv.m_vis.m_point_size=point_size 86 | f = open(tangentconv_pred_file, "r") 87 | a = np.fromfile(f, dtype=np.uint32) 88 | cloud_tangentconv.L_pred=a 89 | cloud_tangentconv.m_vis.set_color_semanticpred() 90 | Scene.show(cloud_tangentconv, "tangentconv") 91 | 92 | view.m_camera.from_string("3.18081 306.493 215.98 -0.464654 0.00651987 0.00342135 0.885462 0 -6.3551 0 30 0.3 7830.87") 93 | 94 | 95 | 96 | view.update() -------------------------------------------------------------------------------- /latticenet_py/misc/lnn_eval_single_mesh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | import torch 4 | from torch.autograd import Function 5 | from torch import Tensor 6 | 7 | import sys 8 | import os 9 | # http://wiki.ros.org/Packages#Client_Library_Support 10 | import rospkg 11 | rospack = rospkg.RosPack() 12 | sf_src_path=rospack.get_path('surfel_renderer') 13 | sf_build_path=os.path.abspath(sf_src_path + "/../../build/surfel_renderer") 14 | sys.path.append(sf_build_path) #contains the modules of pycom 15 | 16 | from DataLoaderTest import * 17 | from lattice_py import LatticePy 18 | from lattice_funcs import * #for the timing macros 19 | import visdom 20 | import torchnet 21 | from lr_finder import LRFinder 22 | from scores import Scores 23 | from model_ctx import ModelCtx 24 | 25 | # np.set_printoptions(threshold=np.inf) 26 | # torch.set_printoptions(threshold=50000) 27 | # torch.set_printoptions(profile="full") 28 | 29 | # config_file="lnn_train_semantic_kitti.cfg" 30 | # config_file="lnn_eval_semantic_kitti_bg5.cfg" 31 | config_file="lnn_eval_single_mesh.cfg" 32 | # config_file="lnn_eval_scannet_bg5.cfg" 33 | 34 | 35 | torch.manual_seed(0) 36 | 37 | node_name="eval_lnn" 38 | vis = visdom.Visdom() 39 | port=8097 40 | logger_test_loss = torchnet.logger.VisdomPlotLogger('line', opts={'title': 'logger_test_loss'}, port=port, env=node_name) 41 | 42 | #initialize the parameters used for evaluating 43 | eval_params=EvalParams.create(config_file) 44 | dataset_name=eval_params.dataset_name() 45 | with_viewer=eval_params.with_viewer() 46 | with_viewer=eval_params.with_viewer() 47 | checkpoint_path=eval_params.checkpoint_path() 48 | do_write_predictions=eval_params.do_write_predictions() 49 | output_predictions_path=eval_params.output_predictions_path() 50 | #rest of params needed by the net to will not be used since we are not training 51 | batch_size=1 52 | learning_rate=0 53 | base_lr=0 54 | weight_decay=0 55 | nr_epochs_per_half_cycle=0 56 | exponential_gamma=0.0 57 | max_training_epochs=0 58 | with_debug_output=False 59 | with_error_checking=False 60 | 61 | model_params=ModelParams.create(config_file) 62 | 63 | def show_predicted_cloud(pred_softmax, cloud): 64 | mesh_pred=cloud.clone() 65 | l_pred=pred_softmax.detach().argmax(axis=1).cpu().numpy() 66 | mesh_pred.L_pred=l_pred 67 | mesh_pred.m_vis.m_point_size=4 68 | mesh_pred.m_vis.set_color_semanticpred() 69 | mesh_pred.move_in_z(cloud.get_scale()) #good for shapenetpartseg 70 | Scene.show(mesh_pred, "mesh_pred") 71 | 72 | 73 | def write_prediction(pred_softmax, cloud, pred_path): 74 | mesh_pred=cloud.clone() 75 | l_pred=pred_softmax.detach().argmax(axis=1).cpu().numpy() 76 | mesh_pred.color_from_label_indices(l_pred) 77 | mesh_pred.L_pred=l_pred 78 | mesh_pred.save_to_file(pred_path) 79 | 80 | def write_gt(cloud, gt_path): 81 | mesh_gt=cloud.clone() 82 | mesh_gt.color_from_label_indices(cloud.L_gt) 83 | mesh_gt.save_to_file(gt_path) 84 | 85 | def create_loader(dataset_name, config_file): 86 | if(dataset_name=="semantickitti"): 87 | loader=DataLoaderSemanticKitti(config_file) 88 | elif dataset_name=="shapenet": 89 | loader=DataLoaderShapeNetPartSeg(config_file) 90 | elif dataset_name=="toyexample": 91 | loader=DataLoaderToyExample(config_file) 92 | elif dataset_name=="stanford": 93 | loader=DataLoaderStanfordIndoor(config_file) 94 | elif dataset_name=="scannet": 95 | loader=DataLoaderScanNet(config_file) 96 | else: 97 | err="Datset name not recognized. It is " + dataset_name 98 | sys.exit(err) 99 | 100 | return loader 101 | 102 | 103 | def run(): 104 | if with_viewer: 105 | view=Viewer(config_file) 106 | 107 | loader_test=create_loader(dataset_name, config_file) 108 | loader_test.start() 109 | 110 | first_time=True 111 | iter_test_nr=0 #nr of batches processed 112 | samples_test_processed=0 113 | 114 | #torch stuff 115 | lattice_to_splat=LatticePy() 116 | lattice_to_splat.create(config_file, "splated_lattice") #IMPORTANT THAT the size of the lattice in this file is the same as the size of the lattice that was used during training 117 | model_ctx=ModelCtx(base_lr, learning_rate, weight_decay, batch_size, nr_epochs_per_half_cycle, exponential_gamma, model_params, with_debug_output=with_debug_output, with_error_checking=with_error_checking) 118 | mode="eval" #this will switch between train and eval as we finish each epoch 119 | 120 | torch.set_grad_enabled(False) 121 | scores=Scores(node_name, port) 122 | 123 | write_scannet_predictions=False 124 | 125 | cloud=MeshCore() 126 | cloud.load_from_file("/home/local/staff/rosu/data/ais_kitchen/kitchen_meshes/kitchen_2105.ply") 127 | cloud.random_subsample(0.7) 128 | cloud.rotate_x_axis(1.0) 129 | cloud.C=cloud.C/255 130 | cloud.C=cloud.C+0.2 # for some reason this yields better results 131 | # nr_classes=21 132 | #use the dataloader to get the labelmngr 133 | while True: 134 | if(loader_test.has_data()): 135 | cloud_with_label_mngr=loader_test.get_cloud() 136 | cloud.m_label_mngr=cloud_with_label_mngr.m_label_mngr 137 | break 138 | 139 | # for sigma in np.arange(0.04, 0.1, 0.01): 140 | # lattice_to_splat.lattice.set_sigma(sigma) 141 | # sigma=0.07 142 | # lattice_to_splat.lattice.set_sigma(sigma) 143 | 144 | positions, values, target = model_ctx.prepare_cloud(cloud) #prepares the cloud for pytorch, returning tensors alredy in cuda 145 | pred_softmax, pred_raw, delta_weight_error_sum=model_ctx.forward(lattice_to_splat, positions, values, mode, cloud.m_label_mngr.nr_classes(), 1 ) 146 | 147 | 148 | if first_time: 149 | first_time=False 150 | #now that all the parameters are created we can fill them with a model from a file 151 | model_ctx.model.load_state_dict(torch.load(checkpoint_path)) 152 | #need to rerun forward with the new parameters to get an accurate prediction 153 | pred_softmax, pred_raw, delta_weight_error_sum=model_ctx.forward(lattice_to_splat, positions, values, mode, cloud.m_label_mngr.nr_classes(), 1 ) 154 | 155 | lattice_to_splat.compute_nr_points_per_lattice_vertex() 156 | print("max color is ", cloud.C.max() ) 157 | 158 | 159 | if with_viewer: 160 | show_predicted_cloud(pred_softmax, cloud) 161 | 162 | if do_write_predictions: 163 | pred_path=os.path.join(output_predictions_path, str(samples_test_processed)+"_2105_pred.ply" ) 164 | print("writing prediction to ", pred_path) 165 | write_prediction(pred_softmax, cloud, pred_path) 166 | # write_gt(cloud, gt_path) 167 | 168 | 169 | def main(): 170 | run() 171 | 172 | 173 | 174 | if __name__ == "__main__": 175 | main() # This is what you would have, but the following is useful: 176 | 177 | # # These are temporary, for debugging, so meh for programming style. 178 | # import sys, trace 179 | 180 | # # If there are segfaults, it's a good idea to always use stderr as it 181 | # # always prints to the screen, so you should get as much output as 182 | # # possible. 183 | # sys.stdout = sys.stderr 184 | 185 | # # Now trace execution: 186 | # tracer = trace.Trace(trace=1, count=0, ignoredirs=["/usr", sys.prefix]) 187 | # tracer.run('main()') 188 | -------------------------------------------------------------------------------- /latticenet_py/misc/lnn_make_teaser_img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | import torch 4 | from torch.autograd import Function 5 | from torch import Tensor 6 | 7 | import sys 8 | import os 9 | import numpy as np 10 | import time 11 | # http://wiki.ros.org/Packages#Client_Library_Support 12 | import rospkg 13 | rospack = rospkg.RosPack() 14 | sf_src_path=rospack.get_path('surfel_renderer') 15 | sf_build_path=os.path.abspath(sf_src_path + "/../../build/surfel_renderer") 16 | sys.path.append(sf_build_path) #contains the modules of pycom 17 | 18 | from DataLoaderTest import * 19 | from vis import Vis 20 | 21 | config_file="lnn_make_teaser_img.cfg" 22 | 23 | train_params=TrainParams.create(config_file) 24 | dataset_name=train_params.dataset_name() 25 | with_viewer=train_params.with_viewer() 26 | 27 | 28 | def create_loader(dataset_name, config_file): 29 | if(dataset_name=="semantickitti"): 30 | loader=DataLoaderSemanticKitti(config_file) 31 | elif dataset_name=="shapenet": 32 | loader=DataLoaderShapeNetPartSeg(config_file) 33 | elif dataset_name=="toyexample": 34 | loader=DataLoaderToyExample(config_file) 35 | elif dataset_name=="stanford": 36 | loader=DataLoaderStanfordIndoor(config_file) 37 | elif dataset_name=="scannet": 38 | loader=DataLoaderScanNet(config_file) 39 | else: 40 | err="Datset name not recognized. It is " + dataset_name 41 | sys.exit(err) 42 | 43 | return loader 44 | 45 | 46 | 47 | 48 | 49 | def run(): 50 | if with_viewer: 51 | view=Viewer(config_file) 52 | loader=create_loader(dataset_name, config_file) 53 | # loader.set_mode_test() 54 | loader.start() 55 | 56 | 57 | # view.m_camera.from_string("-0.0229652 -0.0329689 5.88696 0.153809 -0.457114 -0.0806017 0.872292 5.88928 30 0.5 500") #for moto train 9 58 | view.m_camera.from_string("-0.0229652 -0.0329689 5.88696 0.153809 -0.457114 -0.0806017 0.872292 5.88928 30 0.5 500") #for moto train 10 59 | 60 | nr_processed_clouds=-1 61 | chosen_cloud=9 # train mode: nice scooter 62 | # chosen_cloud=10 #train mode: nice looking motorbike 63 | # chosen_cloud=41 64 | 65 | while True: 66 | if with_viewer: 67 | view.update() 68 | 69 | 70 | if(loader.has_data()): 71 | cloud=loader.get_cloud() 72 | print("\n\n\n") 73 | print("got cloud") 74 | 75 | nr_processed_clouds+=1 76 | 77 | if nr_processed_clouds!=chosen_cloud: 78 | continue 79 | # time.sleep(2) 80 | 81 | 82 | if with_viewer: 83 | cloud.m_vis.m_point_size=9 84 | # cloud.m_vis.set_color_pervertcolor() 85 | Scene.show(cloud,"cloud") 86 | 87 | print("showing cloud ", nr_processed_clouds) 88 | 89 | 90 | 91 | 92 | def main(): 93 | run() 94 | 95 | 96 | 97 | if __name__ == "__main__": 98 | main() # This is what you would have, but the following is useful: 99 | 100 | # # These are temporary, for debugging, so meh for programming style. 101 | # import sys, trace 102 | 103 | # # If there are segfaults, it's a good idea to always use stderr as it 104 | # # always prints to the screen, so you should get as much output as 105 | # # possible. 106 | # sys.stdout = sys.stderr 107 | 108 | # # Now trace execution: 109 | # tracer = trace.Trace(trace=1, count=0, ignoredirs=["/usr", sys.prefix]) 110 | # tracer.run('main()') -------------------------------------------------------------------------------- /latticenet_py/misc/prepare_submission_semantickitti.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.6 2 | 3 | import os 4 | import numpy as np 5 | import torch 6 | from easypbr import * 7 | from dataloaders import * 8 | 9 | 10 | pred_folder="/media/rosu/Data/data/semantic_kitti/predictions/after_icra_experiments_fixed_deform_none/test" 11 | 12 | out_folder="/media/rosu/Data/data/semantic_kitti/for_server/after_icra_experiments_fixed_deform_none" 13 | 14 | 15 | config_file="lnn_compare_semantic_kitti.cfg" 16 | config_path=os.path.join( os.path.dirname( os.path.realpath(__file__) ) , '../../config', config_file) 17 | view=Viewer.create(config_path) 18 | loader=DataLoaderSemanticKitti(config_path) 19 | loader.start() 20 | 21 | 22 | #inside the pred folder we must go though all of the sequences and read the .label and then write it to binary 23 | sequences = [ f.path for f in os.scandir(pred_folder) if f.is_dir() ] 24 | print("sequences is ", sequences) 25 | for seq_folder in sequences: 26 | seq=os.path.basename(seq_folder) 27 | out_folder_with_sequences=os.path.join(out_folder, "sequences", seq, "predictions" ) 28 | print("out_folder_with_sequences ", out_folder_with_sequences) 29 | os.makedirs(out_folder_with_sequences, exist_ok=True) 30 | files = [f for f in os.listdir(seq_folder) if os.path.isfile(os.path.join(seq_folder, f))] 31 | nr_files_for_seq=0 32 | for file_basename in files: 33 | file=os.path.join(seq_folder, file_basename) 34 | name_no_basename = os.path.splitext(file)[0] 35 | extension = os.path.splitext(file)[1] 36 | if extension==".label": 37 | nr_files_for_seq+=1 38 | labels = np.loadtxt(file) 39 | out_file=os.path.join(out_folder_with_sequences, file_basename) 40 | # print("writing in", out_file) 41 | f= open(out_file,"w+") 42 | labels=labels.astype(np.int32) 43 | labels.tofile(f) 44 | 45 | #sanity check 46 | a = np.fromfile(out_file, dtype=np.uint32) 47 | print("a is ", a) 48 | print("labels is ", labels) 49 | diff = (a!=labels).sum() 50 | print("diff is", diff) 51 | 52 | #read also the gt 53 | if(loader.has_data()): 54 | cloud=loader.get_cloud() 55 | mesh=Mesh( os.path.join(out_folder_with_sequences, (name_no_basename+"_gt.ply") ) ) 56 | mesh.L_pred=a 57 | mesh.m_label_mngr=cloud.m_label_mngr 58 | mesh.m_vis.set_color_semanticpred() 59 | Scene.show(mesh,"mesh") 60 | view.update() 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | print("nr_file_for_seq", nr_files_for_seq) 69 | 70 | 71 | -------------------------------------------------------------------------------- /latticenet_py/utils/__pycache__/utils.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AIS-Bonn/lattice_net/348dc9a68806678d2aa924399884d951edfc1475/latticenet_py/utils/__pycache__/utils.cpython-36.pyc -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import sys 4 | import platform 5 | import subprocess 6 | import glob 7 | 8 | from setuptools import setup, Extension 9 | from setuptools.command.build_ext import build_ext 10 | from distutils.version import LooseVersion 11 | from distutils.command.install_headers import install_headers as install_headers_orig 12 | from setuptools import setup 13 | from distutils.sysconfig import get_python_inc 14 | import site #section 2.7 in https://docs.python.org/3/distutils/setupscript.html 15 | # import catkin.workspace 16 | 17 | 18 | class CMakeExtension(Extension): 19 | def __init__(self, name, sourcedir=''): 20 | Extension.__init__(self, name, sources=[]) 21 | self.sourcedir = os.path.abspath(sourcedir) 22 | 23 | 24 | class CMakeBuild(build_ext): 25 | def run(self): 26 | try: 27 | out = subprocess.check_output(['cmake', '--version']) 28 | except OSError: 29 | raise RuntimeError("CMake must be installed to build the following extensions: " + 30 | ", ".join(e.name for e in self.extensions)) 31 | 32 | if platform.system() == "Windows": 33 | cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1)) 34 | if cmake_version < '3.1.0': 35 | raise RuntimeError("CMake >= 3.1.0 is required on Windows") 36 | 37 | for ext in self.extensions: 38 | self.build_extension(ext) 39 | 40 | def build_extension(self, ext): 41 | extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) 42 | cmake_args = [ 43 | '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, 44 | '-DPYTHON_EXECUTABLE=' + sys.executable 45 | # '-GNinja' 46 | ] 47 | 48 | # cfg = 'Debug' if self.debug else 'Release' 49 | # build_args = ['--config', cfg] 50 | build_args = [] 51 | 52 | if platform.system() == "Windows": 53 | # cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] 54 | if sys.maxsize > 2**32: 55 | cmake_args += ['-A', 'x64'] 56 | build_args += ['--', '/m'] 57 | else: 58 | # cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] 59 | build_args += ['--', '-j4'] 60 | 61 | env = os.environ.copy() 62 | env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''), 63 | self.distribution.get_version()) 64 | if not os.path.exists(self.build_temp): 65 | os.makedirs(self.build_temp) 66 | # print ("build temp is ", self.build_temp) 67 | 68 | #find out where do the header file and the shader files get copied into https://stackoverflow.com/questions/14375222/find-python-header-path-from-within-python 69 | # print("PRINTING-------------------------------------------------") 70 | # print( get_python_inc() ) #this gives the include dir 71 | # print( site.USER_BASE ) # data files that are added through data_files=[] get added here for --user instaltions https://docs.python.org/3/distutils/setupscript.html 72 | # pkg_dir, dist = self.create_dist(headers="dummy_header") 73 | # dummy_install_headers=install_headers_orig(dist=dist) 74 | # help(install_headers_orig) 75 | # dummy_install_headers=install_headers_orig(self.distribution) 76 | # print( dummy_install_headers.install_dir ) #this gives the include dir 77 | # cmake_args+=['-DEASYPBR_SHADERS_PATH=' + get_python_inc()+"/easypbr"] 78 | # cmake_args+=['-DEASYPBR_SHADERS_PATH=' + site.USER_BASE] 79 | # cmake_args+=['-DDATA_DIR=' + site.USER_BASE] 80 | # cmake_args+=['-DCATKIN_PACKAGE_LIB_DESTINATION=' + "./"] 81 | 82 | 83 | subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) 84 | subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp) 85 | # subprocess.check_call(['make', 'install'], cwd=self.build_temp) 86 | # subprocess.check_call(['catkin build', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) 87 | # subprocess.check_call(['catkin', 'build' ,'--this'] + build_args + cmake_args, cwd=self.build_temp, env=env) 88 | 89 | # ##get the workspace path depending on the current path and catkin.workspace.get_workspaces 90 | # # print("current path") 91 | # cur_dir=os.path.dirname(os.path.abspath(__file__)) 92 | # workspaces=catkin.workspace.get_workspaces() 93 | # # current_workspace=[x if cur_dir in else '' for x in row] 94 | # current_workspace="" 95 | # for path in workspaces: 96 | # last_part=os.path.basename(os.path.normpath(path)) 97 | # if(last_part=="devel"): 98 | # potential_workspace=os.path.dirname(path) #gets rid of /devel 99 | # if(potential_workspace in cur_dir): 100 | # current_workspace=potential_workspace 101 | # break 102 | # print("current workspace is ", current_workspace) 103 | 104 | # #simlink the libraries from the devel space towards the current dir so that the egg link can find them 105 | # catkin_lib_dir=os.path.join(current_workspace,"devel/lib/") 106 | # libs = [f for f in os.listdir(catkin_lib_dir) if os.path.isfile(os.path.join(catkin_lib_dir, f))] 107 | # print(libs) 108 | # for lib in libs: 109 | # if "dataloaders" in lib: 110 | # print ("linking ", lib) 111 | # print("cmd", ['ln', '-sf'] + [ os.path.join(catkin_lib_dir,lib) + " " + os.path.join(cur_dir, lib ) ] ) 112 | # subprocess.check_call(['ln', '-sf'] + [ os.path.join(catkin_lib_dir,lib) ] + [ os.path.join(cur_dir, lib ) ] ) 113 | # # subprocess.check_call(['cp'] + [ os.path.join(catkin_lib_dir,lib) + " " + os.path.join(cur_dir, lib )] ) 114 | 115 | 116 | 117 | with open("README.md", "r") as fh: 118 | long_description = fh.read() 119 | 120 | #install headers while retaining the structure of the tree folder https://stackoverflow.com/a/50114715 121 | class install_headers(install_headers_orig): 122 | 123 | def run(self): 124 | headers = self.distribution.headers or [] 125 | for header in headers: 126 | dst = os.path.join(self.install_dir, os.path.dirname(header)) 127 | print("----------------copying in ", dst) 128 | # dst = os.path.join(get_python_inc(), os.path.dirname(header)) 129 | self.mkpath(dst) 130 | (out, _) = self.copy_file(header, dst) 131 | self.outfiles.append(out) 132 | 133 | def has_any_extension(filename, extensions): 134 | for each in extensions: 135 | if filename.endswith(each): 136 | return True 137 | return False 138 | 139 | # https://stackoverflow.com/a/41031566 140 | def find_files(directory, strip, extensions): 141 | """ 142 | Using glob patterns in ``package_data`` that matches a directory can 143 | result in setuptools trying to install that directory as a file and 144 | the installation to fail. 145 | 146 | This function walks over the contents of *directory* and returns a list 147 | of only filenames found. The filenames will be stripped of the *strip* 148 | directory part. 149 | 150 | It only takes file that have a certain extension 151 | """ 152 | 153 | result = [] 154 | for root, dirs, files in os.walk(directory): 155 | for filename in files: 156 | # if filename.endswith('.h') or filename.endswith('.hpp') or filename.endswith('.cuh'): 157 | if has_any_extension(filename, extensions): 158 | # print("filename", filename) 159 | filename = os.path.join(root, filename) 160 | result.append(os.path.relpath(filename, strip)) 161 | 162 | # print("result of find_files is ", result) 163 | 164 | return result 165 | # return 'include/easy_pbr/LabelMngr.h' 166 | 167 | setup( 168 | name='latticenet', 169 | version='1.0.0', 170 | author="Radu Alexandru Rosu", 171 | author_email="rosu@ais.uni-bonn.de", 172 | description="LatticeNet", 173 | long_description=long_description, 174 | ext_modules=[CMakeExtension('latticenet')], 175 | cmdclass={ 'build_ext':CMakeBuild, 176 | 'install_headers': install_headers, 177 | }, 178 | zip_safe=False, 179 | ) 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /src/EvalParams.cxx: -------------------------------------------------------------------------------- 1 | #include "lattice_net/EvalParams.h" 2 | 3 | //loguru 4 | #define LOGURU_REPLACE_GLOG 1 5 | #include 6 | 7 | //configuru 8 | #define CONFIGURU_WITH_EIGEN 1 9 | #define CONFIGURU_IMPLICIT_CONVERSIONS 1 10 | #include 11 | using namespace configuru; 12 | 13 | //boost 14 | #include 15 | namespace fs = boost::filesystem; 16 | 17 | 18 | EvalParams::EvalParams(const std::string config_file){ 19 | 20 | init_params(config_file); 21 | } 22 | 23 | void EvalParams::init_params(const std::string config_file){ 24 | 25 | //read all the parameters 26 | // Config cfg = configuru::parse_file(std::string(CMAKE_SOURCE_DIR)+"/config/"+config_file, CFG); 27 | 28 | std::string config_file_abs; 29 | if (fs::path(config_file).is_relative()){ 30 | config_file_abs=(fs::path(PROJECT_SOURCE_DIR) / config_file).string(); 31 | }else{ 32 | config_file_abs=config_file; 33 | } 34 | Config cfg = configuru::parse_file(config_file_abs, CFG); 35 | 36 | Config eval_config=cfg["eval"]; 37 | m_dataset_name=(std::string)eval_config["dataset_name"]; 38 | m_with_viewer = eval_config["with_viewer"]; 39 | m_checkpoint_path = (std::string)eval_config["checkpoint_path"]; 40 | m_do_write_predictions=eval_config["do_write_predictions"]; 41 | m_output_predictions_path=(std::string)eval_config["output_predictions_path"]; 42 | 43 | if(!fs::is_regular_file(m_checkpoint_path)) { 44 | LOG(FATAL) << "The model file " << m_checkpoint_path << " does not exist"; 45 | } 46 | 47 | if(m_do_write_predictions && !fs::is_directory(m_output_predictions_path)) { 48 | LOG(FATAL) << "The directory for saving predictions was not created under " << m_output_predictions_path << ". Maybe you need to create it or maybe you are on the wrong machine."; 49 | } 50 | 51 | 52 | } 53 | 54 | std::string EvalParams::dataset_name(){ 55 | return m_dataset_name; 56 | } 57 | bool EvalParams::with_viewer(){ 58 | return m_with_viewer; 59 | } 60 | std::string EvalParams::checkpoint_path(){ 61 | return m_checkpoint_path; 62 | } 63 | bool EvalParams::do_write_predictions(){ 64 | return m_do_write_predictions; 65 | } 66 | std::string EvalParams::output_predictions_path(){ 67 | return m_output_predictions_path; 68 | } -------------------------------------------------------------------------------- /src/HashTable.cu: -------------------------------------------------------------------------------- 1 | #include "lattice_net/HashTable.cuh" 2 | 3 | #include 4 | // #include "torch/torch.h" 5 | 6 | //my stuff 7 | #include "lattice_net/kernels/HashTableGPU.cuh" 8 | 9 | 10 | 11 | HashTable::HashTable(const int capacity): 12 | m_capacity(capacity), 13 | // m_pos_dim(-1), 14 | m_impl( new HashTableGPU() ), 15 | m_nr_filled_is_dirty(true), 16 | m_nr_filled(-1) 17 | { 18 | } 19 | 20 | 21 | void HashTable::init(int pos_dim, int val_dim){ 22 | 23 | // CHECK() 24 | 25 | // m_capacity=capacity; 26 | // m_pos_dim=pos_dim; 27 | m_impl=std::make_shared( m_capacity, pos_dim ); 28 | 29 | // m_keys_tensor=register_buffer("keys", torch::zeros({capacity, pos_dim}).to(torch::kInt32) ); //TODO should it be short so kInt16 as in the original implementation 30 | // torch::zeros({m_capacity, pos_dim }, torch::dtype(torch::kFloat32).device(torch::kCUDA, 0) ) 31 | m_keys_tensor=register_buffer("keys", torch::zeros({m_capacity, pos_dim }, torch::dtype(torch::kInt32).device(torch::kCUDA, 0)) ); //TODO should it be short so kInt16 as in the original implementation 32 | m_values_tensor=register_buffer("values", torch::zeros({m_capacity, val_dim }, torch::dtype(torch::kFloat32).device(torch::kCUDA, 0)) ); 33 | m_entries_tensor=register_buffer("entries", torch::zeros({m_capacity }, torch::dtype(torch::kInt32).device(torch::kCUDA, 0)) ); 34 | m_nr_filled_tensor=register_buffer("nr_filled", torch::zeros({1}, torch::dtype(torch::kInt32).device(torch::kCUDA, 0)) ); 35 | m_nr_filled_is_dirty=true; 36 | 37 | // m_keys_tensor=m_keys_tensor.to("cuda"); 38 | // m_values_tensor=m_values_tensor.to("cuda"); 39 | // m_entries_tensor=m_entries_tensor.to("cuda"); 40 | // m_nr_filled_tensor=m_nr_filled_tensor.to("cuda"); 41 | 42 | 43 | clear(); 44 | update_impl(); 45 | 46 | 47 | } 48 | 49 | void HashTable::clear(){ 50 | if(is_initialized()){ 51 | m_values_tensor.fill_(0); 52 | m_keys_tensor.fill_(0); 53 | m_entries_tensor.fill_(-1); 54 | m_nr_filled_tensor.fill_(0); 55 | m_nr_filled_is_dirty=true; 56 | } 57 | } 58 | 59 | void HashTable::clear_only_values(){ 60 | if(is_initialized()){ 61 | m_values_tensor.fill_(0); 62 | // m_nr_filled_is_dirty=true; 63 | } 64 | } 65 | 66 | bool HashTable::is_initialized(){ 67 | if(m_keys_tensor.defined() ){ 68 | return true; 69 | }else{ 70 | return false; 71 | } 72 | 73 | } 74 | 75 | void HashTable::update_impl(){ 76 | m_impl->m_capacity = m_capacity; 77 | if(m_keys_tensor.defined()){ 78 | m_impl->m_keys = m_keys_tensor.data_ptr(); 79 | } 80 | if(m_values_tensor.defined()){ 81 | m_impl->m_values = m_values_tensor.data_ptr(); 82 | } 83 | if(m_entries_tensor.defined()){ 84 | m_impl->m_entries = m_entries_tensor.data_ptr(); 85 | } 86 | if(m_nr_filled_tensor.defined()){ 87 | m_impl->m_nr_filled = m_nr_filled_tensor.data_ptr(); 88 | } 89 | 90 | CHECK( m_keys_tensor.defined() )<<" We need the keys tensor to be defined here. Please use hash_table.init() first."; 91 | 92 | m_impl->m_pos_dim = m_keys_tensor.size(1); 93 | 94 | } 95 | 96 | 97 | 98 | //getters 99 | int HashTable::pos_dim(){ 100 | return m_keys_tensor.size(1); 101 | } 102 | int HashTable::val_dim(){ 103 | return m_values_tensor.size(1); 104 | } 105 | int HashTable::capacity(){ 106 | return m_keys_tensor.size(0); 107 | } 108 | 109 | 110 | 111 | //setters 112 | void HashTable::set_values(const torch::Tensor& new_values){ 113 | m_values_tensor=new_values.contiguous(); 114 | update_impl(); 115 | } 116 | -------------------------------------------------------------------------------- /src/ModelParams.cxx: -------------------------------------------------------------------------------- 1 | #include "lattice_net/ModelParams.h" 2 | 3 | //loguru 4 | #define LOGURU_REPLACE_GLOG 1 5 | #include 6 | 7 | //configuru 8 | #define CONFIGURU_WITH_EIGEN 1 9 | #define CONFIGURU_IMPLICIT_CONVERSIONS 1 10 | #include 11 | using namespace configuru; 12 | 13 | //boost 14 | #include 15 | namespace fs = boost::filesystem; 16 | 17 | 18 | ModelParams::ModelParams(const std::string config_file){ 19 | 20 | init_params(config_file); 21 | } 22 | 23 | void ModelParams::init_params(const std::string config_file){ 24 | 25 | //read all the parameters 26 | // Config cfg = configuru::parse_file(std::string(CMAKE_SOURCE_DIR)+"/config/"+config_file, CFG); 27 | std::string config_file_abs; 28 | if (fs::path(config_file).is_relative()){ 29 | config_file_abs=(fs::path(PROJECT_SOURCE_DIR) / config_file).string(); 30 | }else{ 31 | config_file_abs=config_file; 32 | } 33 | Config cfg = configuru::parse_file(config_file_abs, CFG); 34 | 35 | 36 | Config train_config=cfg["model"]; 37 | 38 | m_positions_mode=(std::string)train_config["positions_mode"]; 39 | m_values_mode=(std::string)train_config["values_mode"]; 40 | m_pointnet_channels_per_layer=train_config["pointnet_channels_per_layer"]; 41 | m_pointnet_start_nr_channels=train_config["pointnet_start_nr_channels"]; 42 | m_nr_downsamples=train_config["nr_downsamples"]; 43 | m_nr_blocks_down_stage=train_config["nr_blocks_down_stage"]; 44 | m_nr_blocks_bottleneck=train_config["nr_blocks_bottleneck"]; 45 | m_nr_blocks_up_stage=train_config["nr_blocks_up_stage"]; 46 | m_nr_levels_down_with_normal_resnet=train_config["nr_levels_down_with_normal_resnet"]; 47 | m_nr_levels_up_with_normal_resnet=train_config["nr_levels_up_with_normal_resnet"]; 48 | m_compression_factor=train_config["compression_factor"]; 49 | m_dropout_last_layer=train_config["dropout_last_layer"]; 50 | // m_experiment=(std::string)train_config["experiment"]; 51 | 52 | } 53 | 54 | std::string ModelParams::positions_mode(){ 55 | return m_positions_mode; 56 | } 57 | std::string ModelParams::values_mode(){ 58 | return m_values_mode; 59 | } 60 | Eigen::VectorXi ModelParams::pointnet_channels_per_layer(){ 61 | return m_pointnet_channels_per_layer; 62 | } 63 | int ModelParams::pointnet_start_nr_channels(){ 64 | return m_pointnet_start_nr_channels; 65 | } 66 | int ModelParams::nr_downsamples(){ 67 | return m_nr_downsamples; 68 | } 69 | std::vector ModelParams::nr_blocks_down_stage(){ 70 | return m_nr_blocks_down_stage; 71 | } 72 | int ModelParams::nr_blocks_bottleneck(){ 73 | return m_nr_blocks_bottleneck; 74 | } 75 | std::vector ModelParams::nr_blocks_up_stage(){ 76 | return m_nr_blocks_up_stage; 77 | } 78 | int ModelParams::nr_levels_down_with_normal_resnet(){ 79 | return m_nr_levels_down_with_normal_resnet; 80 | } 81 | int ModelParams::nr_levels_up_with_normal_resnet(){ 82 | return m_nr_levels_up_with_normal_resnet; 83 | } 84 | float ModelParams::compression_factor(){ 85 | return m_compression_factor; 86 | } 87 | float ModelParams::dropout_last_layer(){ 88 | return m_dropout_last_layer; 89 | } 90 | // std::string ModelParams::experiment(){ 91 | // return m_experiment; 92 | // } 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/PyBridge.cxx: -------------------------------------------------------------------------------- 1 | #include "lattice_net/PyBridge.h" 2 | 3 | #include 4 | #include "torch/torch.h" 5 | #include "torch/csrc/utils/pybind.h" 6 | 7 | //my stuff 8 | // #include "data_loaders/DataLoaderShapeNetPartSeg.h" 9 | // #include "easy_pbr/Mesh.h" 10 | // #include "easy_pbr/LabelMngr.h" 11 | #include "lattice_net/Lattice.cuh" 12 | #include "lattice_net/HashTable.cuh" 13 | #include "lattice_net/TrainParams.h" 14 | #include "lattice_net/ModelParams.h" 15 | #include "lattice_net/EvalParams.h" 16 | 17 | 18 | // https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html 19 | // PYBIND11_MAKE_OPAQUE(std::vector); //to be able to pass vectors by reference to functions and have things like push back actually work 20 | // PYBIND11_MAKE_OPAQUE(std::vector, std::allocator >); 21 | 22 | namespace py = pybind11; 23 | 24 | 25 | 26 | 27 | PYBIND11_MODULE(latticenet, m) { 28 | 29 | 30 | //Lattice 31 | // py::module::import("torch"); 32 | // py::object variable = (py::object) py::module::import("torch").attr("autograd").attr("Variable"); //from here but it segment faults https://pybind11.readthedocs.io/en/stable/advanced/misc.html 33 | py::class_ > (m, "HashTable") 34 | // .def_readonly("m_values_tensor", &HashTable::m_values_tensor) //careful when using this because setting it and not using update_impl is a big bug 35 | .def_readonly("m_keys_tensor", &HashTable::m_keys_tensor) //careful when using this because setting it and not using update_impl is a big bug 36 | .def_readonly("m_nr_filled_tensor", &HashTable::m_nr_filled_tensor) ////careful when using this because setting it and not using update_impl is a big bug 37 | // .def("update_impl", &HashTable::update_impl) 38 | // .def("set_values", &HashTable::set_values) 39 | ; 40 | 41 | py::class_ > (m, "Lattice") 42 | // py::class_ > (m, "Lattice", variable) 43 | // py::class_ > (m, "Lattice") 44 | // py::class_ > (m, "Lattice") 45 | // py::class_ (m, "Lattice") 46 | .def_static("create", &Lattice::create ) //for templated methods like this one we need to explicitly instantiate one of the arguments 47 | .def_static("create", &Lattice::create ) //for templated methods like this one we need to explicitly instantiate one of the arguments 48 | .def("begin_splat", &Lattice::begin_splat ) 49 | // .def("begin_splat_modify_only_values", &Lattice::begin_splat_modify_only_values ) 50 | .def("splat_standalone", &Lattice::splat_standalone ) 51 | .def("distribute", &Lattice::distribute ) 52 | .def("expand", &Lattice::expand ) 53 | // .def("create_splatting_mask", &Lattice::create_splatting_mask ) 54 | // .def("blur_standalone", &Lattice::blur_standalone ) 55 | // .def("convolve_standalone", &Lattice::convolve_standalone ) 56 | // .def("depthwise_convolve", &Lattice::depthwise_convolve ) 57 | .def("convolve_im2row_standalone", &Lattice::convolve_im2row_standalone ) 58 | .def("im2row", &Lattice::im2row ) 59 | .def("row2im", &Lattice::row2im ) 60 | .def("im2rowindices", &Lattice::im2rowindices ) 61 | .def("just_create_verts", &Lattice::just_create_verts ) 62 | .def("create_coarse_verts", &Lattice::create_coarse_verts ) 63 | .def("create_coarse_verts_naive", &Lattice::create_coarse_verts_naive ) 64 | .def("slice_standalone_with_precomputation", &Lattice::slice_standalone_with_precomputation ) 65 | .def("slice_standalone_no_precomputation", &Lattice::slice_standalone_no_precomputation ) 66 | // .def("slice_elevated_verts", &Lattice::slice_elevated_verts ) 67 | .def("slice_classify_no_precomputation", &Lattice::slice_classify_no_precomputation ) 68 | .def("slice_classify_with_precomputation", &Lattice::slice_classify_with_precomputation ) 69 | .def("gather_standalone_no_precomputation", &Lattice::gather_standalone_no_precomputation ) 70 | .def("gather_standalone_with_precomputation", &Lattice::gather_standalone_with_precomputation ) 71 | // .def("gather_elevated_standalone_no_precomputation", &Lattice::gather_elevated_standalone_no_precomputation ) 72 | .def("slice_backwards_standalone_with_precomputation", &Lattice::slice_backwards_standalone_with_precomputation ) 73 | .def("slice_backwards_standalone_with_precomputation_no_homogeneous", &Lattice::slice_backwards_standalone_with_precomputation_no_homogeneous ) 74 | // .def("slice_backwards_elevated_verts_with_precomputation", &Lattice::slice_backwards_elevated_verts_with_precomputation ) 75 | .def("slice_classify_backwards_with_precomputation", &Lattice::slice_classify_backwards_with_precomputation ) 76 | .def("gather_backwards_standalone_with_precomputation", &Lattice::gather_backwards_standalone_with_precomputation ) 77 | // .def("gather_backwards_elevated_standalone_with_precomputation", &Lattice::gather_backwards_elevated_standalone_with_precomputation ) 78 | // .def("row2im", &Lattice::row2im ) 79 | // .def("to_tensors", &Lattice::to_tensors ) 80 | // .def("from_tensors", &Lattice::from_tensors ) 81 | .def("get_filter_extent", &Lattice::get_filter_extent ) 82 | .def_static("get_expected_filter_extent", &Lattice::get_expected_filter_extent ) 83 | .def("val_dim", &Lattice::val_dim ) 84 | // .def("val_full_dim", &Lattice::val_full_dim ) 85 | .def("pos_dim", &Lattice::pos_dim ) 86 | .def("name", &Lattice::name ) 87 | .def("nr_lattice_vertices", &Lattice::nr_lattice_vertices ) 88 | // .def("set_nr_lattice_vertices", &Lattice::set_nr_lattice_vertices ) 89 | .def("capacity", &Lattice::capacity ) 90 | .def("positions", &Lattice::positions ) 91 | .def("sigmas_tensor", &Lattice::sigmas_tensor) 92 | .def("hash_table", &Lattice::hash_table) 93 | .def("values", &Lattice::values) 94 | .def("set_values", &Lattice::set_values) 95 | .def("set_positions", &Lattice::set_positions) 96 | // .def_readwrite("m_hash_table", &Lattice::m_hash_table ) 97 | // .def_readwrite("m_sliced_values_hom_tensor", &Lattice::m_sliced_values_hom_tensor ) 98 | // .def_readwrite("m_lattice_rowified", &Lattice::m_lattice_rowified ) 99 | // .def_readwrite("m_distributed_tensor", &Lattice::m_distributed_tensor) 100 | // .def_readwrite("m_splatting_indices_tensor", &Lattice::m_splatting_indices_tensor) 101 | // .def_readwrite("m_splatting_weights_tensor", &Lattice::m_splatting_weights_tensor) 102 | // .def_readwrite("m_positions", &Lattice::m_positions) 103 | // .def_readwrite("m_name", &Lattice::m_name ) 104 | // .def("set_val_dim", &Lattice::set_val_dim) 105 | // .def("set_val_full_dim", &Lattice::set_val_full_dim) 106 | .def("clone_lattice", &Lattice::clone_lattice) 107 | // .def("keys_to_verts", &Lattice::keys_to_verts) 108 | // .def("elevate", &Lattice::elevate) 109 | // .def("deelevate", &Lattice::deelevate) 110 | // .def("color_no_neighbours", &Lattice::color_no_neighbours) 111 | .def("increase_sigmas", &Lattice::increase_sigmas) 112 | .def("set_sigma", &Lattice::set_sigma) 113 | ; 114 | 115 | //TrainParams 116 | py::class_ > (m, "TrainParams", py::module_local()) 117 | .def_static("create", &TrainParams::create ) //for templated methods like this one we need to explicitly instantiate one of the arguments 118 | .def("dataset_name", &TrainParams::dataset_name ) 119 | .def("with_viewer", &TrainParams::with_viewer ) 120 | .def("with_visdom", &TrainParams::with_visdom ) 121 | .def("with_tensorboard", &TrainParams::with_tensorboard ) 122 | .def("lr", &TrainParams::lr ) 123 | .def("weight_decay", &TrainParams::weight_decay ) 124 | .def("save_checkpoint", &TrainParams::save_checkpoint ) 125 | .def("checkpoint_path", &TrainParams::checkpoint_path ) 126 | ; 127 | 128 | //EvalParams 129 | py::class_ > (m, "EvalParams", py::module_local()) 130 | .def_static("create", &EvalParams::create ) //for templated methods like this one we need to explicitly instantiate one of the arguments 131 | .def("dataset_name", &EvalParams::dataset_name ) 132 | .def("with_viewer", &EvalParams::with_viewer ) 133 | .def("checkpoint_path", &EvalParams::checkpoint_path ) 134 | .def("do_write_predictions", &EvalParams::do_write_predictions ) 135 | .def("output_predictions_path", &EvalParams::output_predictions_path ) 136 | ; 137 | 138 | //ModelParams 139 | py::class_ > (m, "ModelParams", py::module_local()) 140 | .def_static("create", &ModelParams::create ) //for templated methods like this one we need to explicitly instantiate one of the arguments 141 | .def("positions_mode", &ModelParams::positions_mode ) 142 | .def("values_mode", &ModelParams::values_mode ) 143 | .def("pointnet_channels_per_layer", &ModelParams::pointnet_channels_per_layer ) 144 | .def("pointnet_start_nr_channels", &ModelParams::pointnet_start_nr_channels ) 145 | .def("nr_downsamples", &ModelParams::nr_downsamples ) 146 | .def("nr_blocks_down_stage", &ModelParams::nr_blocks_down_stage ) 147 | .def("nr_blocks_bottleneck", &ModelParams::nr_blocks_bottleneck ) 148 | .def("nr_blocks_up_stage", &ModelParams::nr_blocks_up_stage ) 149 | .def("nr_levels_down_with_normal_resnet", &ModelParams::nr_levels_down_with_normal_resnet ) 150 | .def("nr_levels_up_with_normal_resnet", &ModelParams::nr_levels_up_with_normal_resnet ) 151 | .def("compression_factor", &ModelParams::compression_factor ) 152 | .def("dropout_last_layer", &ModelParams::dropout_last_layer ) 153 | // .def("experiment", &ModelParams::experiment ) 154 | ; 155 | 156 | 157 | } 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/TrainParams.cxx: -------------------------------------------------------------------------------- 1 | #include "lattice_net/TrainParams.h" 2 | 3 | //loguru 4 | #define LOGURU_REPLACE_GLOG 1 5 | #include 6 | 7 | //configuru 8 | #define CONFIGURU_WITH_EIGEN 1 9 | #define CONFIGURU_IMPLICIT_CONVERSIONS 1 10 | #include 11 | using namespace configuru; 12 | 13 | //boost 14 | #include 15 | namespace fs = boost::filesystem; 16 | 17 | 18 | TrainParams::TrainParams(const std::string config_file){ 19 | 20 | init_params(config_file); 21 | } 22 | 23 | void TrainParams::init_params(const std::string config_file){ 24 | 25 | //read all the parameters 26 | // Config cfg = configuru::parse_file(std::string(CMAKE_SOURCE_DIR)+"/config/"+config_file, CFG); 27 | 28 | std::string config_file_abs; 29 | if (fs::path(config_file).is_relative()){ 30 | config_file_abs=(fs::path(PROJECT_SOURCE_DIR) / config_file).string(); 31 | }else{ 32 | config_file_abs=config_file; 33 | } 34 | Config cfg = configuru::parse_file(config_file_abs, CFG); 35 | 36 | Config train_config=cfg["train"]; 37 | m_dataset_name=(std::string)train_config["dataset_name"]; 38 | m_with_viewer = train_config["with_viewer"]; 39 | m_with_visdom = train_config["with_visdom"]; 40 | m_with_tensorboard = train_config["with_tensorboard"]; 41 | m_lr = train_config["lr"]; 42 | m_weight_decay = train_config["weight_decay"]; 43 | m_save_checkpoint=train_config["save_checkpoint"]; 44 | m_checkpoint_path=(std::string)train_config["checkpoint_path"]; 45 | 46 | if(m_save_checkpoint && !fs::is_directory(m_checkpoint_path)) { 47 | LOG(FATAL) << "The directory for saving checkpoint was not created under " << m_checkpoint_path << ". Maybe you need to create it or maybe you are on the wrong machine."; 48 | } 49 | 50 | } 51 | 52 | std::string TrainParams::dataset_name(){ 53 | return m_dataset_name; 54 | } 55 | bool TrainParams::with_viewer(){ 56 | return m_with_viewer; 57 | } 58 | bool TrainParams::with_visdom(){ 59 | return m_with_visdom; 60 | } 61 | bool TrainParams::with_tensorboard(){ 62 | return m_with_tensorboard; 63 | } 64 | float TrainParams::lr(){ 65 | return m_lr; 66 | } 67 | float TrainParams::weight_decay(){ 68 | return m_weight_decay; 69 | } 70 | bool TrainParams::save_checkpoint(){ 71 | return m_save_checkpoint; 72 | } 73 | std::string TrainParams::checkpoint_path(){ 74 | return m_checkpoint_path; 75 | } 76 | 77 | 78 | 79 | --------------------------------------------------------------------------------