Copy disabled (too large)
Download .txt
Showing preview only (12,912K chars total). Download the full file to get everything.
Repository: rerun-io/simplerecon
Branch: main
Commit: 2a3778a8c89f
Files: 92
Total size: 49.9 MB
Directory structure:
gitextract_6sfl0utb/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── configs/
│ ├── data/
│ │ ├── 7scenes_default.yaml
│ │ ├── 7scenes_dense.yaml
│ │ ├── colmap_dense.yaml
│ │ ├── neucon_arkit_default.yaml
│ │ ├── neucon_arkit_dense.yaml
│ │ ├── scannet_default_test.yaml
│ │ ├── scannet_default_train.yaml
│ │ ├── scannet_default_val.yaml
│ │ ├── scannet_dense_test.yaml
│ │ ├── scannet_dense_val.yaml
│ │ ├── scanniverse_dense.yaml
│ │ ├── vdr_default.yaml
│ │ ├── vdr_dense.yaml
│ │ ├── vdr_dense_offline.yaml
│ │ └── vdr_dense_rerun.yaml
│ └── models/
│ ├── dot_product_model.yaml
│ └── hero_model.yaml
├── data_scripts/
│ ├── 7scenes_preprocessing.py
│ ├── IOS_LOGGER_ARKIT_README.md
│ ├── generate_test_tuples.py
│ ├── generate_train_tuples.py
│ ├── ios_logger_preprocessing.py
│ ├── precompute_valid_frames.py
│ └── scannet_wrangling_scripts/
│ ├── LICENSE
│ ├── README.md
│ ├── SensorData.py
│ ├── download_scannet.py
│ ├── env.yml
│ ├── reader.py
│ └── splits/
│ ├── scannetv2_test.txt
│ ├── scannetv2_train.txt
│ └── scannetv2_val.txt
├── data_splits/
│ ├── 7Scenes/
│ │ └── dvmvs_split/
│ │ ├── dvmvs_test_split.txt
│ │ └── test_eight_view_deepvmvs.txt
│ ├── ScanNetv2/
│ │ ├── dvmvs_split/
│ │ │ ├── dvmvs_train.txt
│ │ │ ├── dvmvs_val.txt
│ │ │ ├── test_eight_view_deepvmvs.txt
│ │ │ └── test_eight_view_deepvmvs_dense.txt
│ │ └── standard_split/
│ │ ├── scannetv2_test.txt
│ │ ├── scannetv2_train.txt
│ │ ├── scannetv2_val.txt
│ │ ├── test_eight_view_deepvmvs.txt
│ │ ├── test_eight_view_deepvmvs_dense.txt
│ │ ├── test_eight_view_deepvmvs_offline.txt
│ │ ├── train_eight_view_deepvmvs.txt
│ │ └── val_eight_view_deepvmvs.txt
│ ├── arkit/
│ │ ├── scans.txt
│ │ ├── test_eight_view_deepvmvs.txt
│ │ └── test_eight_view_deepvmvs_dense.txt
│ └── vdr/
│ ├── scans.txt
│ ├── test_eight_view_deepvmvs.txt
│ ├── test_eight_view_deepvmvs_dense.txt
│ └── test_eight_view_deepvmvs_dense_offline.txt
├── experiment_modules/
│ └── depth_model.py
├── losses.py
├── modules/
│ ├── cost_volume.py
│ ├── layers.py
│ └── networks.py
├── options.py
├── pc_fusion.py
├── pixi.toml
├── requirements.txt
├── rerun_visualize_live_meshing.py
├── simplerecon_env.yml
├── sr_datasets/
│ ├── arkit_dataset.py
│ ├── colmap_dataset.py
│ ├── generic_mvs_dataset.py
│ ├── scannet_dataset.py
│ ├── scanniverse_dataset.py
│ ├── seven_scenes_dataset.py
│ └── vdr_dataset.py
├── test.py
├── tools/
│ ├── fusers_helper.py
│ ├── keyframe_buffer.py
│ ├── mesh_renderer.py
│ ├── torch_point_cloud_fusion.py
│ └── tsdf.py
├── train.py
├── utils/
│ ├── dataset_utils.py
│ ├── generic_utils.py
│ ├── geometry_utils.py
│ ├── metrics_utils.py
│ └── visualization_utils.py
├── visualization_scripts/
│ ├── generate_gt_min_max_cache.py
│ ├── load_meshes_and_include_normals.py
│ └── visualize_scene_depth_output.py
├── visualize_live_meshing.py
└── weights/
└── strip_checkpoint.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# GitHub syntax highlighting
pixi.lock linguist-language=YAML
================================================
FILE: .gitignore
================================================
*.pyc
.vscode/
debug_scripts/
logs/
logs
models/*.ckpt
weights/*.ckpt
**__pycache__**
# pixi environments
.pixi
data/*
OUTPUT_PATH/*
================================================
FILE: LICENSE
================================================
Copyright © Niantic, Inc. 2022. Patent Pending.
All rights reserved.
================================================================================
This Software is licensed under the terms of the following SimpleRecon license
which allows for non-commercial use only. For any other use of the software not
covered by the terms of this license, please contact partnerships@nianticlabs.com
================================================================================
SimpleRecon License
This Agreement is made by and between the Licensor and the Licensee as
defined and identified below.
1. Definitions.
In this Agreement (“the Agreement”) the following words shall have the
following meanings:
"Authors" shall mean M. Sayed, J. Gibson, J. Watson, V. Prisacariu,
M. Firman, C. Godard
"Licensee" Shall mean the person or organization agreeing to use the
Software in accordance with these terms and conditions.
"Licensor" shall mean Niantic Inc., a company organized and existing under
the laws of Delaware, whose principal place of business is at 1 Ferry Building,
Suite 200, San Francisco, 94111.
"Software" shall mean the SimpleRecon Software uploaded by Licensor to the
GitHub repository at https://github.com/nianticlabs/SimpleRecon
on September 1st 2022 in source code or object code form and any
accompanying documentation as well as any modifications or additions uploaded
to the same GitHub repository by Licensor.
2. License.
2.1 The Licensor has all necessary rights to grant a license under: (i)
copyright and rights in the nature of copyright subsisting in the Software; and
(ii) certain patent rights resulting from a patent application(s) filed by the
Licensor in the United States and/or other jurisdictions in connection with the
Software. The Licensor grants the Licensee for the duration of this Agreement,
a free of charge, non-sublicenseable, non-exclusive, non-transferable copyright
and patent license (in consequence of said patent application(s)) to use the
Software for non-commercial purpose only, including teaching and research at
educational institutions and research at not-for-profit research institutions
in accordance with the provisions of this Agreement. Non-commercial use
expressly excludes any profit-making or commercial activities, including without
limitation sale, license, manufacture or development of commercial products, use in
commercially-sponsored research, use at a laboratory or other facility owned or
controlled (whether in whole or in part) by a commercial entity, provision of
consulting service, use for or on behalf of any commercial entity, use in
research where a commercial party obtains rights to research results or any
other benefit, and use of the code in any models, model weights or code
resulting from such procedure in any commercial product. Notwithstanding the
foregoing restrictions, you can use this code for publishing comparison results
for academic papers, including retraining on your own data. Any use of the
Software for any purpose other than pursuant to the license grant set forth
above shall automatically terminate this License.
2.2 The Licensee is permitted to make modifications to the Software
provided that any distribution of such modifications is in accordance with
Clause 3.
2.3 Except as expressly permitted by this Agreement and save to the
extent and in the circumstances expressly required to be permitted by law, the
Licensee is not permitted to rent, lease, sell, offer to sell, or loan the
Software or its associated documentation.
3. Redistribution and modifications
3.1 The Licensee may reproduce and distribute copies of the Software, with
or without modifications, in source format only and only to this same GitHub
repository , and provided that any and every distribution is accompanied by an
unmodified copy of this License and that the following copyright notice is
always displayed in an obvious manner: Copyright © Niantic, Inc. 2018. All
rights reserved.
3.2 In the case where the Software has been modified, any distribution must
include prominent notices indicating which files have been changed.
3.3 The Licensee shall cause any work that it distributes or publishes,
that in whole or in part contains or is derived from the Software or any part
thereof (“Work based on the Software”), to be licensed as a whole at no charge
to all third parties entitled to a license to the Software under the terms of
this License and on the same terms provided in this License.
4. Duration.
This Agreement is effective until the Licensee terminates it by destroying
the Software, any Work based on the Software, and its documentation together
with all copies. It will also terminate automatically if the Licensee fails to
abide by its terms. Upon automatic termination the Licensee agrees to destroy
all copies of the Software, Work based on the Software, and its documentation.
5. Disclaimer of Warranties.
The Software is provided as is. To the maximum extent permitted by law,
Licensor provides no warranties or conditions of any kind, either express or
implied, including without limitation, any warranties or condition of title,
non-infringement or fitness for a particular purpose.
6. LIMITATION OF LIABILITY.
IN NO EVENT SHALL THE LICENSOR AND/OR AUTHORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7. Indemnity.
The Licensee shall indemnify the Licensor and/or Authors against all third
party claims that may be asserted against or suffered by the Licensor and/or
Authors and which relate to use of the Software by the Licensee.
8. Intellectual Property.
8.1 As between the Licensee and Licensor, copyright and all other
intellectual property rights subsisting in or in connection with the Software
and supporting information shall remain at all times the property of the
Licensor. The Licensee shall acquire no rights in any such material except as
expressly provided in this Agreement.
8.2 No permission is granted to use the trademarks or product names of the
Licensor except as required for reasonable and customary use in describing the
origin of the Software and for the purposes of abiding by the terms of Clause
3.1.
8.3 The Licensee shall promptly notify the Licensor of any improvement or
new use of the Software (“Improvements”) in sufficient detail for Licensor to
evaluate the Improvements. The Licensee hereby grants the Licensor and its
affiliates a non-exclusive, fully paid-up, royalty-free, irrevocable and
perpetual license to all Improvements for non-commercial academic research and
teaching purposes upon creation of such improvements.
8.4 The Licensee grants an exclusive first option to the Licensor to be
exercised by the Licensor within three (3) years of the date of notification of
an Improvement under Clause 8.3 to use any the Improvement for commercial
purposes on terms to be negotiated and agreed by Licensee and Licensor in good
faith within a period of six (6) months from the date of exercise of the said
option (including without limitation any royalty share in net income from such
commercialization payable to the Licensee, as the case may be).
9. Acknowledgements.
The Licensee shall acknowledge the Authors and use of the Software in the
publication of any work that uses, or results that are achieved through, the
use of the Software. The following citation shall be included in the
acknowledgement: “SimpleRecon: 3D Reconstruction Without 3D Convolutions",
by M. Sayed, J. Gibson, J. Watson, V. Prisacariu, M. Firman, C. Godard,
arXiv:2208.14743”.
10. Governing Law.
This Agreement shall be governed by, construed and interpreted in
accordance with English law and the parties submit to the exclusive
jurisdiction of the English courts.
11. Termination.
Upon termination of this Agreement, the licenses granted hereunder will
terminate and Sections 5, 6, 7, 8, 9, 10 and 11 shall survive any termination
of this Agreement.
================================================
FILE: README.md
================================================
# SimpleRecon: 3D Reconstruction Without 3D Convolutions
This is the reference PyTorch implementation for training and testing MVS depth estimation models which has been modified to use [Rerun](https://github.com/rerun-io/rerun) for visualization.
https://github.com/nianticlabs/simplerecon/assets/25287427/1d32d2b2-61fe-4007-ac86-39134a0af2e5
## Run using `pixi`
The easiest way to get started is to install [pixi](https://prefix.dev/docs/pixi/overview).
The pixi environment described in `pixi.toml` contains all of the dependencies, including the rerun viewer,
allowing you to setup your development environment and download demo data
This will work with Linux and Mac
Run the following in order
1`pixi run download-data`
2`pixi run vdr`
> **SimpleRecon: 3D Reconstruction Without 3D Convolutions**
>
> [Mohamed Sayed](https://masayed.com), [John Gibson](https://www.linkedin.com/in/john-e-gibson-ii/), [Jamie Watson](https://www.linkedin.com/in/jamie-watson-544825127/), [Victor Adrian Prisacariu](https://www.robots.ox.ac.uk/~victor/), [Michael Firman](http://www.michaelfirman.co.uk), and [Clément Godard](http://www0.cs.ucl.ac.uk/staff/C.Godard/)
>
> [Paper, ECCV 2022 (arXiv pdf)](https://arxiv.org/abs/2208.14743), [Supplemental Material](https://nianticlabs.github.io/simplerecon/resources/SimpleRecon_supp.pdf), [Project Page](https://nianticlabs.github.io/simplerecon/), [Video](https://youtu.be/3LP8jp45Ef8)
<p align="center">
<img src="media/teaser.jpeg" alt="example output" width="720" />
</p>
https://user-images.githubusercontent.com/14994206/187824325-e1878d77-2f14-4ea9-bc02-3fded1bb1851.mp4
https://user-images.githubusercontent.com/14994206/189788536-5fa8a1b5-ae8b-4f64-92d6-1ff1abb03eaf.mp4
This code is for non-commercial use; please see the [license file](LICENSE) for terms. If you do find any part of this codebase helpful, please cite our paper using the BibTex below and link this repo. Thanks!
## 🆕 Updates
09/03/2023: Added kornia version to the environments file to fix kornia typing issue. (thanks @natesimon!)
26/01/2023: The license has been modified to make running the model for academic reasons easier. Please the LICENSE file for the exact details.
There is an update as of 31/12/2022 that fixes slightly wrong intrinsics, flip augmentation for the cost volume, and a
numerical precision bug in projection. All scores improve. You will need to update your forks and use new weights. See [Bug Fixes](#-bug-fixes).
Precomputed scans for online default frames are here: https://drive.google.com/drive/folders/1dSOFI9GayYHQjsx4I_NG0-3ebCAfWXjV?usp=share_link
## Table of Contents
* [🗺️ Overview](#%EF%B8%8F-overview)
* [⚙️ Setup](#%EF%B8%8F-setup)
* [📦 Models](#-models)
* [🚀 Speed](#-speed)
* [📝 TODOs:](#-todos)
* [🏃 Running out of the box!](#-running-out-of-the-box)
* [💾 ScanNetv2 Dataset](#-scannetv2-dataset)
* [🖼️🖼️🖼️ Frame Tuples](#%EF%B8%8F%EF%B8%8F%EF%B8%8F-frame-tuples)
* [📊 Testing and Evaluation](#-testing-and-evaluation)
* [👉☁️ Point Cloud Fusion](#%EF%B8%8F-point-cloud-fusion)
* [📊 Mesh Metrics](#-mesh-metrics)
* [⏳ Training](#-training)
+ [🎛️ Finetuning a pretrained model](#%EF%B8%8F-finetuning-a-pretrained-model)
* [🔧 Other training and testing options](#-other-training-and-testing-options)
* [✨ Visualization](#-visualization)
* [📝🧮👩💻 Notation for Transformation Matrices](#-notation-for-transformation-matrices)
* [🗺️ World Coordinate System](#%EF%B8%8F-world-coordinate-system)
* [🐜🔧 Bug Fixes](#-bug-fixes)
* [🗺️💾 COLMAP Dataset](#%EF%B8%8F-colmap-dataset)
* [🙏 Acknowledgements](#-acknowledgements)
* [📜 BibTeX](#-bibtex)
* [👩⚖️ License](#%EF%B8%8F-license)
## 🗺️ Overview
SimpleRecon takes as input posed RGB images, and outputs a depth map for a target image.
## ⚙️ Setup
### Conda
Assuming a fresh [Anaconda](https://www.anaconda.com/download/) distribution, you can install dependencies with:
```shell
conda env create -f simplerecon_env.yml
```
We ran our experiments with PyTorch 1.10, CUDA 11.3, Python 3.9.7 and Debian GNU/Linux 10.
### virtualenv + pip
(Last tested with Python 3.10.9, torch
Create a virtualenv and install dependencies.
```
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt
```
## 📦 Models
Download a pretrained model into the `weights/` folder.
We provide the following models (scores are with online default keyframes):
| `--config` | Model | Abs Diff↓| Sq Rel↓ | delta < 1.05↑| Chamfer↓ | F-Score↑ |
|-------------|----------|--------------------|---------|---------|--------------|----------|
| [`hero_model.yaml`](https://drive.google.com/file/d/1hCuKZjEq-AghrYAmFxJs_4eeixIlP488/view?usp=sharing) | Metadata + Resnet Matching | 0.0868 | 0.0127 | 74.26 | 5.69 | 0.680 |
| [`dot_product_model.yaml`](https://drive.google.com/file/d/13lW-VPgsl2eAo95E87RKWoK8KUZelkUK/view?usp=sharing) | Dot Product + Resnet Matching | 0.0910 | 0.0134 | 71.90 | 5.92 | 0.667 |
`hero_model` is the one we use in the paper as **Ours**
## 🚀 Speed
| `--config` | Model | Inference Speed (`--batch_size 1`) | Inference GPU memory | Approximate training time |
|------------|------------|------------|-------------------------|-----------------------------|
| `hero_model` | Hero, Metadata + Resnet | 130ms / 70ms (speed optimized) | 2.6GB / 5.7GB (speed optimized) | 36 hours |
| `dot_product_model` | Dot Product + Resnet | 80ms | 2.6GB | 36 hours |
With larger batches speed increases considerably. With batch size 8 on the non-speed optimized model, the latency drops to
~40ms.
## 📝 TODOs:
- [x] Simple scan for folks to quickly try the code, instead of downloading the ScanNetv2 test scenes. DONE
- [x] ScanNetv2 extraction, ~~ETA 10th October~~ DONE
- [ ] FPN model weights.
- ~~[ ] Tutorial on how to use Scanniverse data, ETA 5th October 10th October 20th October~~ At present there is no publically available way of exporting scans from Scanniverse. You'll have to use ios-logger; NeuralRecon have a good tutorial on [this](https://github.com/zju3dv/NeuralRecon/blob/master/DEMO.md), and a dataloader that accepts the processed format is at ```datasets/arkit_dataset.py```. UPDATE: There is now a quick readme [data_scripts/IOS_LOGGER_ARKIT_README.md](data_scripts/IOS_LOGGER_ARKIT_README.md) for how to process and run inference an ios-logger scan using the script at ```data_scripts/ios_logger_preprocessing.py```.
## 🏃 Running out of the box!
We've now included two scans for people to try out immediately with the code. You can download these scans [from here](https://drive.google.com/file/d/1x-auV7vGCMdu5yZUMPcoP83p77QOuasT/view?usp=sharing).
Steps:
1. Download weights for the `hero_model` into the weights directory.
2. Download the scans and unzip them to a directory of your choosing.
3. Modify the value for the option `dataset_path` in `configs/data/vdr_dense.yaml` to the base path of the unzipped vdr folder.
4. You should be able to run it! Something like this will work:
```bash
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config_file configs/data/vdr_dense.yaml \
--num_workers 8 \
--batch_size 2 \
--fast_cost_volume \
--run_fusion \
--depth_fuser open3d \
--fuse_color \
--dump_depth_visualization
```
for visualizing with rerun use the following command
```bash
CUDA_VISIBLE_DEVICES=0 python rerun_visualize_live_meshing.py \
--name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config_file configs/data/vdr_dense.yaml \
--num_workers 8 \
--run_fusion \
--depth_fuser open3d \
--fuse_color
```
This will output meshes, quick depth viz, and socres when benchmarked against LiDAR depth under `OUTPUT_PATH`.
This command uses `vdr_dense.yaml` which will generate depths for every frame and fuse them into a mesh. In the paper we report scores with fused keyframes instead, and you can run those using `vdr_default.yaml`. You can also use `dense_offline` tuples by instead using `vdr_dense_offline.yaml`.
See the section below on testing and evaluation. Make sure to use the correct config flags for datasets.
## 💾 ScanNetv2 Dataset
~~Please follow the instructions [here](https://github.com/ScanNet/ScanNet) to download the dataset. This dataset is quite big (>2TB), so make sure you have enough space, especially for extracting files.~~
~~Once downloaded, use this [script](https://github.com/ScanNet/ScanNet/tree/master/SensReader/python) to export raw sensor data to images and depth files.~~
We've written a quick tutorial and included modified scripts to help you with downloading and extracting ScanNetv2. You can find them at [data_scripts/scannet_wrangling_scripts/](data_scripts/scannet_wrangling_scripts)
You should change the `dataset_path` config argument for ScanNetv2 data configs at `configs/data/` to match where your dataset is.
The codebase expects ScanNetv2 to be in the following format:
dataset_path
scans_test (test scans)
scene0707
scene0707_00_vh_clean_2.ply (gt mesh)
sensor_data
frame-000261.pose.txt
frame-000261.color.jpg
frame-000261.color.512.png (optional, image at 512x384)
frame-000261.color.640.png (optional, image at 640x480)
frame-000261.depth.png (full res depth, stored scale *1000)
frame-000261.depth.256.png (optional, depth at 256x192 also
scaled)
scene0707.txt (scan metadata and image sizes)
intrinsic
intrinsic_depth.txt
intrinsic_color.txt
...
scans (val and train scans)
scene0000_00
(see above)
scene0000_01
....
In this example `scene0707.txt` should contain the scan's metadata:
colorHeight = 968
colorToDepthExtrinsics = 0.999263 -0.010031 0.037048 ........
colorWidth = 1296
depthHeight = 480
depthWidth = 640
fx_color = 1170.187988
fx_depth = 570.924255
fy_color = 1170.187988
fy_depth = 570.924316
mx_color = 647.750000
mx_depth = 319.500000
my_color = 483.750000
my_depth = 239.500000
numColorFrames = 784
numDepthFrames = 784
numIMUmeasurements = 1632
`frame-000261.pose.txt` should contain pose in the form:
-0.384739 0.271466 -0.882203 4.98152
0.921157 0.0521417 -0.385682 1.46821
-0.0587002 -0.961035 -0.270124 1.51837
`frame-000261.color.512.png` and `frame-000261.color.640.png` are precached resized versions of the original image to save load and compute time during training and testing. `frame-000261.depth.256.png` is also a
precached resized version of the depth map.
All resized precached versions of depth and images are nice to have but not
required. If they don't exist, the full resolution versions will be loaded, and downsampled on the fly.
## 🖼️🖼️🖼️ Frame Tuples
By default, we estimate a depth map for each keyframe in a scan. We use DeepVideoMVS's heuristic for keyframe separation and construct tuples to match. We use the depth maps at these keyframes for depth fusion. For each keyframe, we associate a list of source frames that will be used to build the cost volume. We also use dense tuples, where we predict a depth map for each frame in the data, and not just at specific keyframes; these are mostly used for visualization.
We generate and export a list of tuples across all scans that act as the dataset's elements. We've precomputed these lists and they are available at `data_splits` under each dataset's split. For ScanNet's test scans they are at `data_splits/ScanNetv2/standard_split`. Our core depth numbers are computed using `data_splits/ScanNetv2/standard_split/test_eight_view_deepvmvs.txt`.
Here's a quick taxonamy of the type of tuples for test:
- `default`: a tuple for every keyframe following DeepVideoMVS where all source frames are in the past. Used for all depth and mesh evaluation unless stated otherwise. For ScanNet use `data_splits/ScanNetv2/standard_split/test_eight_view_deepvmvs.txt`.
- `offline`: a tuple for every frame in the scan where source frames can be both in the past and future relative to the current frame. These are useful when a scene is captured offline, and you want the best accuracy possible. With online tuples, the cost volume will contain empty regions as the camera moves away and all source frames lag behind; however with offline tuples, the cost volume is full on both ends, leading to a better scale (and metric) estimate.
- `dense`: an online tuple (like default) for every frame in the scan where all source frames are in the past. For ScanNet this would be `data_splits/ScanNetv2/standard_split/test_eight_view_deepvmvs_dense.txt`.
- `offline`: an offline tuple for every keyframefor every keyframe in the scan.
For the train and validation sets, we follow the same tuple augmentation strategy as in DeepVideoMVS and use the same core generation script.
If you'd like to generate these tuples yourself, you can use the scripts at `data_scripts/generate_train_tuples.py` for train tuples and `data_scripts/generate_test_tuples.py` for test tuples. These follow the same config format as `test.py` and will use whatever dataset class you build to read pose informaiton.
Example for test:
```bash
# default tuples
python ./data_scripts/generate_test_tuples.py
--data_config configs/data/scannet_default_test.yaml
--num_workers 16
# dense tuples
python ./data_scripts/generate_test_tuples.py
--data_config configs/data/scannet_dense_test.yaml
--num_workers 16
```
Examples for train:
```bash
# train
python ./data_scripts/generate_train_tuples.py
--data_config configs/data/scannet_default_train.yaml
--num_workers 16
# val
python ./data_scripts/generate_val_tuples.py
--data_config configs/data/scannet_default_val.yaml
--num_workers 16
```
These scripts will first check each frame in the dataset to make sure it has an existing RGB frame, an existing depth frame (if appropriate for the dataset), and also an existing and valid pose file. It will save these `valid_frames` in a text file in each scan's folder, but if the directory is read only, it will ignore saving a `valid_frames` file and generate tuples anyway.
## 📊 Testing and Evaluation
You can use `test.py` for inferring and evaluating depth maps and fusing meshes.
All results will be stored at a base results folder (results_path) at:
opts.output_base_path/opts.name/opts.dataset/opts.frame_tuple_type/
where opts is the `options` class. For example, when `opts.output_base_path` is `./results`, `opts.name` is `HERO_MODEL`,
`opts.dataset` is `scannet`, and `opts.frame_tuple_type` is `default`, the output directory will be
./results/HERO_MODEL/scannet/default/
Make sure to set `--opts.output_base_path` to a directory suitable for you to store results.
`--frame_tuple_type` is the type of image tuple used for MVS. A selection should
be provided in the `data_config` file you used.
By default `test.py` will attempt to compute depth scores for each frame and provide both frame averaged and scene averaged metrics. The script will save these scores (per scene and totals) under `results_path/scores`.
We've done our best to ensure that a torch batching bug through the matching
encoder is fixed for (<10^-4) accurate testing by disabling image batching
through that encoder. Run `--batch_size 4` at most if in doubt, and if
you're looking to get as stable as possible numbers and avoid PyTorch
gremlins, use `--batch_size 1` for comparison evaluation.
If you want to use this for speed, set `--fast_cost_volume` to True. This will
enable batching through the matching encoder and will enable an einops
optimized feature volume.
```bash
# Example command to just compute scores
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--batch_size 4;
# If you'd like to get a super fast version use:
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--fast_cost_volume \
--batch_size 2;
```
This script can also be used to perform a few different auxiliary tasks,
including:
**TSDF Fusion**
To run TSDF fusion provide the `--run_fusion` flag. You have two choices for
fusers
1) `--depth_fuser ours` (default) will use our fuser, whose meshes are used
in most visualizations and for scores. This fuser does not support
color. We've provided a custom branch of scikit-image with our custom
implementation of `measure.matching_cubes` that allows single walled. We use
single walled meshes for evaluation. If this is isn't important to you, you
can set the export_single_mesh to `False` for call to `export_mesh` in `test.py`.
2) `--depth_fuser open3d` will use the open3d depth fuser. This fuser
supports color and you can enable this by using the `--fuse_color` flag.
By default, depth maps will be clipped to 3m for fusion and a tsdf
resolution of 0.04m<sup>3</sup> will be used, but you can change that by changing both
`--max_fusion_depth` and `--fusion_resolution`
You can optionnally ask for predicted depths used for fusion to be masked
when no vaiid MVS information exists using `--mask_pred_depths`. This is not
enabled by default.
You can also fuse the best guess depths from the cost volume before the
cost volume encoder-decoder that introduces a strong image prior. You can do this by using
`--fusion_use_raw_lowest_cost`.
Meshes will be stored under `results_path/meshes/`.
```bash
# Example command to fuse depths to get meshes
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--run_fusion \
--batch_size 8;
```
**Cache depths**
You can optionally store depths by providing the `--cache_depths` flag.
They will be stored at `results_path/depths`.
```bash
# Example command to compute scores and cache depths
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--cache_depths \
--batch_size 8;
# Example command to fuse depths to get color meshes
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--run_fusion \
--depth_fuser open3d \
--fuse_color \
--batch_size 4;
```
**Quick viz**
There are other scripts for deeper visualizations of output depths and
fusion, but for quick export of depth map visualization you can use
`--dump_depth_visualization`. Visualizations will be stored at `results_path/viz/quick_viz/`.
```bash
# Example command to output quick depth visualizations
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_default_test.yaml \
--num_workers 8 \
--dump_depth_visualization \
--batch_size 4;
```
## 👉☁️ Point Cloud Fusion
We also allow point cloud fusion of depth maps using the fuser from 3DVNet's [repo](https://github.com/alexrich021/3dvnet/blob/main/mv3d/eval/pointcloudfusion_custom.py).
```bash
# Example command to fuse depths into point clouds.
CUDA_VISIBLE_DEVICES=0 python pc_fusion.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_dense_test.yaml \
--num_workers 8 \
--batch_size 4;
```
Change `configs/data/scannet_dense_test.yaml` to `configs/data/scannet_default_test.yaml` to use keyframes only if you don't want to wait too long.
## 📊 Mesh Metrics
We use TransformerFusion's [mesh evaluation](https://github.com/AljazBozic/TransformerFusion/blob/main/src/evaluation/eval.py) for our main results table but set the seed to a fixed value for consistency when randomly sampling meshes. We also report mesh metrics using NeuralRecon's [evaluation](https://github.com/zju3dv/NeuralRecon/blob/master/tools/evaluation.py) in the supplemental material.
For point cloud evaluation, we use TransformerFusion's code but load in a point cloud in place of sampling a mesh's surface.
## ⏳ Training
By default models and tensorboard event files are saved to `~/tmp/tensorboard/<model_name>`.
This can be changed with the `--log_dir` flag.
We train with a batch_size of 16 with 16-bit precision on two A100s on the default ScanNetv2 split.
Example command to train with two GPUs:
```shell
CUDA_VISIBLE_DEVICES=0,1 python train.py --name HERO_MODEL \
--log_dir logs \
--config_file configs/models/hero_model.yaml \
--data_config configs/data/scannet_default_train.yaml \
--gpus 2 \
--batch_size 16;
```
The code supports any number of GPUs for training.
You can specify which GPUs to use with the `CUDA_VISIBLE_DEVICES` environment.
All our training runs were performed on two NVIDIA A100s.
**Different dataset**
You can train on a custom MVS dataset by writing a new dataloader class which inherits from `GenericMVSDataset` at `datasets/generic_mvs_dataset.py`. See the `ScannetDataset` class in `datasets/scannet_dataset.py` or indeed any other class in `datasets` for an example.
### 🎛️ Finetuning a pretrained model
To finetune, simple load a checkpoint (not resume!) and train from there:
```shell
CUDA_VISIBLE_DEVICES=0 python train.py --config configs/models/hero_model.yaml
--data_config configs/data/scannet_default_train.yaml
--load_weights_from_checkpoint weights/hero_model.ckpt
```
Change the data configs to whatever dataset you want to finetune to.
## 🔧 Other training and testing options
See `options.py` for the range of other training options, such as learning rates and ablation settings, and testing options.
## ✨ Visualization
Other than quick depth visualization in the `test.py` script, there are two scripts for visualizing depth output.
The first is `visualization_scripts/visualize_scene_depth_output.py`. This will produce a video with color images of the reference and source frames, depth prediction, cost volume estimate, GT depth, and estimated normals from depth. The script assumes you have cached depth output using `test.py` and accepts the same command template format as `test.py`:
```shell
# Example command to get visualizations for dense frames
CUDA_VISIBLE_DEVICES=0 python ./visualization_scripts/visualize_scene_depth_output.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--data_config configs/data/scannet_dense_test.yaml \
--num_workers 8;
```
where `OUTPUT_PATH` is the base results directory for SimpleRecon (what you used for test to begin with). You could optionally run `.visualization_scripts/generate_gt_min_max_cache.py` before this script to get a scene average for the min and max depth values used for colormapping; if those aren't available, the script will use 0m and 5m for colomapping min and max.
The second allows a live visualization of meshing. This script will use cached depth maps if available, otherwise it will use the model to predict them before fusion. The script will iteratively load in a depth map, fuse it, save a mesh file at this step, and render this mesh alongside a camera marker for the birdseye video, and from the point of view of the camera for the fpv video.
```shell
# Example command to get live visualizations for mesh reconstruction
CUDA_VISIBLE_DEVICES=0 python visualize_live_meshing.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/scannet_dense_test.yaml \
--num_workers 8;
```
By default the script will save meshes to an intermediate location, and you can optionally load those meshes to save time when visualizing the same meshes again by passing `--use_precomputed_partial_meshes`. All intermediate meshes will have had to be computed on the previous run for this to work.
## 📝🧮👩💻 Notation for Transformation Matrices
__TL;DR:__ `world_T_cam == world_from_cam`
This repo uses the notation "cam_T_world" to denote a transformation from world to camera points (extrinsics). The intention is to make it so that the coordinate frame names would match on either side of the variable when used in multiplication from *right to left*:
cam_points = cam_T_world @ world_points
`world_T_cam` denotes camera pose (from cam to world coords). `ref_T_src` denotes a transformation from a source to a reference view.
Finally this notation allows for representing both rotations and translations such as: `world_R_cam` and `world_t_cam`
## 🗺️ World Coordinate System
This repo is geared towards ScanNet, so while its functionality should allow for any coordinate system (signaled via input flags), the model weights we provide assume a ScanNet coordinate system. This is important since we include ray information as part of metadata. Other datasets used with these weights should be transformed to the ScanNet system. The dataset classes we include will perform the appropriate transforms.
## 🐜🔧 Bug Fixes
### **Update 31/12/2022:**
There are a few bugs addressed in this update, you will need to update your forks and use new weights from the table near the beginning of this README. You will also need to make sure you have the correct intrinsics files extracted using the reader.
- We were initially using a slightly incorrect set of intrinsics in ScanNet. The repo now uses intriniscs from the intriniscs folder.
- The MLP in the cost volume wasn't seeing any flip augmentation which led to biases around edges, so we've now included a geometry based flip in the base dataset class. It is enabled only for the train split.
- We had a bug in projection that never allowed the mask in the cost volume to properly function, so we've now switched to using the same normalization as in OpenCV and Kornia.
Thanks to all those that pointed it out and were patient while we worked on fixes.
All scores improve with these fixes, and the associated weights are uploaded here. For old scores, code, and weights, check this commit hash: 7de5b451e340f9a11c7fd67bd0c42204d0b009a9
Full scores for models with bug fixes:
_Depth_
| `--config` | Abs Diff↓ | Abs Rel↓ | Sq Rel↓ | RMSE↓ | log RMSE↓ |delta < 1.05↑ | delta < 1.10↑ |
|-------------|-----------|----------|---------|---------|-------------|--------------|---------------|
| `hero_model.yaml`, Metadata + Resnet | 0.0868 | 0.0428 | 0.0127 | 0.1472 | 0.0681 | 74.26 | 90.88 |
| `dot_product_model.yaml`, dot product + Resnet | 0.0910 | 0.0453 | 0.0134 | 0.1509 | 0.0704 | 71.90 | 89.75 |
_Mesh Fusion_
| `--config` | Acc↓ | Comp↓ | Chamfer↓ | Recall↑ | Precision↑ | F-Score↑ |
|-------------|------|-------|----------|---------|------------|----------|
| `hero_model.yaml`, Metadata + Resnet | 5.41 | 5.98 | 5.69 | 0.695 | 0.668 | 0.680 |
| `dot_product_model.yaml`, dot product + Resnet | 5.66 | 6.18 | 5.92 | 0.682 | 0.655 | 0.667 |
_Comparison:_
| `--config` | Model | Abs Diff↓| Sq Rel↓ | delta < 1.05↑| Chamfer↓ | F-Score↑ |
|-------------|----------|--------------------|---------|---------|--------------|----------|
| `hero_model.yaml` | Metadata + Resnet Matching | 0.0868 | 0.0127 | 74.26 | 5.69 | 0.680 |
| OLD `hero_model.yaml` | Metadata + Resnet Matching | 0.0885 | 0.0125 | 73.16 | 5.81 | 0.671 |
| `dot_product_model.yaml` | Dot Product + Resnet Matching | 0.0910 | 0.0134 | 71.90 | 5.92 | 0.667 |
| OLD `dot_product_model.yaml` | Dot Product + Resnet Matching | 0.0941 | 0.0139 | 70.48 | 6.29 | 0.642 |
### **Tiny bug with frame count:**
Initially this repo spat out tuple files for default DVMVS style keyframes with 9 extra frame of 25599 for the ScanNetv2 test set. There was a minor bug with handling lost tracking that's now fixed. This repo should now mimic the DVMVS keyframe buffer exactly, with 25590 keyframes for testing. The only effect this bug had was the inclusion of 9 extra frames, all the other tuples were exactly the same as that of DVMVS. The offending frames are in these scans
```
scan previous count new count
--------------------------------------
scene0711_00 393 392
scene0727_00 209 208
scene0736_00 1023 1022
scene0737_00 408 407
scene0751_00 165 164
scene0775_00 220 219
scene0791_00 227 226
scene0794_00 141 140
scene0795_00 102 101
```
The tuple files for default test have been updated. Since this is a small (~3e-4) difference in extra frames scored, the scores are unchanged.
## 🗺️💾 COLMAP Dataset
__TL;DR:__ Scale your poses and crop your images.
We do provide a dataloader for loading images from a COLMAP sparse reconstruction. For this to work with SimpleRecon, you'll need to crop your images to match the FOV of ScanNet (roughly similar to an iPhone's FOV in video mode), and scale your pose's location using known real world measurements. If these steps aren't taken, the cost volume won't be built correctly, and the network will not estimate depth properly.
## 🙏 Acknowledgements
We thank Aljaž Božič of [TransformerFusion](https://github.com/AljazBozic/TransformerFusion), Jiaming Sun of [Neural Recon](https://zju3dv.github.io/neuralrecon/), and Arda Düzçeker of [DeepVideoMVS](https://github.com/ardaduz/deep-video-mvs) for quickly providing useful information to help with baselines and for making their codebases readily available, especially on short notice.
The tuple generation scripts make heavy use of a modified version of DeepVideoMVS's [Keyframe buffer](https://github.com/ardaduz/deep-video-mvs/blob/master/dvmvs/keyframe_buffer.py) (thanks again Arda and co!).
The PyTorch point cloud fusion module at `torch_point_cloud_fusion` code is borrowed from 3DVNet's [repo](https://github.com/alexrich021/3dvnet/blob/main/mv3d/eval/pointcloudfusion_custom.py). Thanks Alexander Rich!
We'd also like to thank Niantic's infrastructure team for quick actions when we needed them. Thanks folks!
Mohamed is funded by a Microsoft Research PhD Scholarship (MRL 2018-085).
## 📜 BibTeX
If you find our work useful in your research please consider citing our paper:
```
@inproceedings{sayed2022simplerecon,
title={SimpleRecon: 3D Reconstruction Without 3D Convolutions},
author={Sayed, Mohamed and Gibson, John and Watson, Jamie and Prisacariu, Victor and Firman, Michael and Godard, Cl{\'e}ment},
booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
year={2022},
}
```
## 👩⚖️ License
Copyright © Niantic, Inc. 2022. Patent Pending.
All rights reserved.
Please see the [license file](LICENSE) for terms.
================================================
FILE: configs/data/7scenes_default.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/shared/datasets/7scenes/
tuple_info_file_location: data_splits/7Scenes/dvmvs_split/
dataset_scan_split_file: data_splits/7Scenes/dvmvs_split/dvmvs_test_split.txt
dataset: 7scenes
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: test
================================================
FILE: configs/data/7scenes_dense.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/shared/datasets/7scenes/
tuple_info_file_location: data_splits/7Scenes/dvmvs_split/
dataset_scan_split_file: data_splits/7Scenes/dvmvs_split/dvmvs_test_split.txt
dataset: 7scenes
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/colmap_dense.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/mohameds/datasets/colmap/
tuple_info_file_location: /mnt/res_nas/mohameds/datasets/colmap/tuples
dataset_scan_split_file: /mnt/res_nas/mohameds/datasets/colmap/test.txt
dataset: colmap
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/neucon_arkit_default.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/mohameds/datasets/arkit
tuple_info_file_location: data_splits/arkit/
dataset_scan_split_file: data_splits/arkit/scans.txt
dataset: arkit
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: test
================================================
FILE: configs/data/neucon_arkit_dense.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/mohameds/datasets/arkit
tuple_info_file_location: data_splits/arkit/
dataset_scan_split_file: data_splits/arkit/scans.txt
dataset: arkit
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/scannet_default_test.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/scannet-data-png2/
tuple_info_file_location: data_splits/ScanNetv2/standard_split
dataset_scan_split_file: data_splits/ScanNetv2/standard_split/scannetv2_test.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
# default means every keyframe defined by DVMVS.
frame_tuple_type: default
split: test
================================================
FILE: configs/data/scannet_default_train.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/scannet-data-png2/
tuple_info_file_location: data_splits/ScanNetv2/standard_split/
dataset_scan_split_file: data_splits/ScanNetv2/standard_split/scannetv2_train.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: train
================================================
FILE: configs/data/scannet_default_val.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/scannet-data-png2/
tuple_info_file_location: data_splits/ScanNetv2/standard_split/
dataset_scan_split_file: data_splits/ScanNetv2/standard_split/scannetv2_val.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: val
================================================
FILE: configs/data/scannet_dense_test.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/scannet-data-png2/
tuple_info_file_location: data_splits/ScanNetv2/standard_split/
dataset_scan_split_file: data_splits/ScanNetv2/standard_split/scannetv2_test.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/scannet_dense_val.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/scannet-data-png2/
tuple_info_file_location: data_splits/ScanNetv2/standard_split/
dataset_scan_split_file: data_splits/ScanNetv2/standard_split/scannetv2_val.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: val
================================================
FILE: configs/data/scanniverse_dense.yaml
================================================
!!python/object:options.Options
dataset_path: /mnt/res_nas/mohameds/datasets/scanniverse/
tuple_info_file_location: /mnt/res_nas/mohameds/datasets/scanniverse/tuples
dataset_scan_split_file: /mnt/res_nas/mohameds/datasets/scanniverse/scans.txt
dataset: scanniverse
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/vdr_default.yaml
================================================
!!python/object:options.Options
dataset_path: /media/data/mosayed/datasets/vdr
tuple_info_file_location: data_splits/vdr/
dataset_scan_split_file: data_splits/vdr/scans.txt
dataset: vdr
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: test
================================================
FILE: configs/data/vdr_dense.yaml
================================================
!!python/object:options.Options
dataset_path: /media/data/mosayed/datasets/vdr
tuple_info_file_location: data_splits/vdr/
dataset_scan_split_file: data_splits/vdr/scans.txt
dataset: vdr
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/data/vdr_dense_offline.yaml
================================================
!!python/object:options.Options
dataset_path: /media/data/mosayed/datasets/vdr
tuple_info_file_location: data_splits/vdr/
dataset_scan_split_file: data_splits/vdr/scans.txt
dataset: vdr
mv_tuple_file_suffix: _eight_view_deepvmvs_dense_offline.txt
num_images_in_tuple: 8
frame_tuple_type: dense_offline
split: test
================================================
FILE: configs/data/vdr_dense_rerun.yaml
================================================
!!python/object:options.Options
dataset_path: data/vdr
tuple_info_file_location: data_splits/vdr/
dataset_scan_split_file: data_splits/vdr/scans.txt
dataset: vdr
mv_tuple_file_suffix: _eight_view_deepvmvs_dense.txt
num_images_in_tuple: 8
frame_tuple_type: dense
split: test
================================================
FILE: configs/models/dot_product_model.yaml
================================================
!!python/object:options.Options
feature_volume_type: simple_cost_volume
batch_size: 16
cost_volume_aggregation: dot
cv_encoder_type: multi_scale_encoder
depth_decoder_name: unet_pp
gpus: 2
image_encoder_name: efficientnet
log_interval: 100
loss_type: log_l1
lr: 0.0001
wd: 0.0001
matching_encoder_type: resnet
name: dot_product_model
num_sanity_val_steps: 0
num_workers: 12
precision: 16
random_seed: 0
================================================
FILE: configs/models/hero_model.yaml
================================================
!!python/object:options.Options
feature_volume_type: mlp_feature_volume
batch_size: 16
cost_volume_aggregation: dot
cv_encoder_type: multi_scale_encoder
depth_decoder_name: unet_pp
gpus: 2
image_encoder_name: efficientnet
log_interval: 100
loss_type: log_l1
lr: 0.0001
wd: 0.0001
matching_encoder_type: resnet
name: hero_model
num_sanity_val_steps: 0
num_workers: 12
precision: 16
random_seed: 0
================================================
FILE: data_scripts/7scenes_preprocessing.py
================================================
# Code from https://github.com/tsattler/visloc_pseudo_gt_limitations/
import os
import warnings
import numpy as np
from skimage import io
from joblib import Parallel, delayed
# name of the folder where we download the original 7scenes dataset to
# we restructure the dataset by creating symbolic links to that folder
src_folder = '/mnt/res_nas/shared/datasets/7scenes'
focal_length = 525.0
# focal length of the depth sensor (source: https://www.microsoft.com/en-us/research/project/rgb-d-dataset-7-scenes/)
d_focal_length = 585.0
# RGB image dimensions
img_w = 640
img_h = 480
# sub sampling factor of eye coordinate tensor
nn_subsampling = 8
#transformation from depth sensor to RGB sensor
#calibration according to https://projet.liris.cnrs.fr/voir/activities-dataset/kinect-calibration.html
d_to_rgb = np.array([
[ 9.9996518012567637e-01, 2.6765126468950343e-03, -7.9041012313000904e-03, -2.5558943178152542e-02],
[-2.7409311281316700e-03, 9.9996302803027592e-01, -8.1504520778013286e-03, 1.0109636268061706e-04],
[ 7.8819942130445332e-03, 8.1718328771890631e-03, 9.9993554558014031e-01, 2.0318321729487039e-03],
[0, 0, 0, 1]
])
def mkdir(directory):
"""Checks whether the directory exists and creates it if necessacy."""
if not os.path.exists(directory):
os.makedirs(directory)
# download the original 7 scenes dataset for poses and images
# mkdir(src_folder)
# os.chdir(src_folder)
# for ds in ['chess', 'fire', 'heads', 'office', 'pumpkin', 'redkitchen', 'stairs']:
# print("=== Downloading 7scenes Data:", ds, "===============================")
# os.system('wget http://download.microsoft.com/download/2/8/5/28564B23-0828-408F-8631-23B1EFF1DAC8/' + ds + '.zip')
# os.system('unzip ' + ds + '.zip')
# os.system('rm ' + ds + '.zip')
# sequences = os.listdir(ds)
# for file in sequences:
# if file.endswith('.zip'):
# print("Unpacking", file)
# os.system('unzip ' + ds + '/' + file + ' -d ' + ds)
# os.system('rm ' + ds + '/' + file)
# print("Processing frames...")
def process_scene(ds):
def process_frames(split_file):
# read the split file
with open(ds + '/' + split_file, 'r') as f:
split = f.readlines()
# map sequences to folder names
split = ['seq-' + s.strip()[8:].zfill(2) for s in split]
for seq in split:
files = os.listdir(ds + '/' + seq)
# adjust depth files by mapping to RGB sensor
depth_files = [f for f in files if f.endswith('depth.png')]
for d_index, d_file in enumerate(depth_files):
if d_index % 1000 == 0:
print(d_index, ds, split_file)
depth = io.imread(ds + '/' + seq + '/' + d_file)
depth = depth.astype(np.float32)
depth /= 1000 # from millimeters to meters
d_h = depth.shape[0]
d_w = depth.shape[1]
# reproject depth map to 3D eye coordinates
eye_coords = np.zeros((4, d_h, d_w))
# set x and y coordinates
eye_coords[0] = 0.5 + np.dstack([np.arange(0, d_w)] * d_h)[0].T
eye_coords[1] = 0.5 + np.dstack([np.arange(0, d_h)] * d_w)[0]
eye_coords = eye_coords.reshape(4, -1)
depth = depth.reshape(-1)
# filter pixels with invalid depth
depth_mask = (depth > 0) & (depth < 100)
eye_coords = eye_coords[:, depth_mask]
depth = depth[depth_mask]
# substract depth principal point (assume image center)
eye_coords[0] -= d_w / 2
eye_coords[1] -= d_h / 2
# reproject
eye_coords[0:2] /= d_focal_length
eye_coords[0] *= depth
eye_coords[1] *= depth
eye_coords[2] = depth
eye_coords[3] = 1
# transform from depth sensor to RGB sensor
eye_coords = np.matmul(d_to_rgb, eye_coords)
# project
depth = eye_coords[2]
eye_coords[0] /= depth
eye_coords[1] /= depth
eye_coords[0:2] *= focal_length
# add RGB principal point (assume image center)
eye_coords[0] += img_w / 2
eye_coords[1] += img_h / 2
registered_depth = np.ones((img_h, img_w), dtype=np.float32) * 2e3
for pt in range(eye_coords.shape[1]):
x = round(eye_coords[0, pt])
y = round(eye_coords[1, pt])
d = eye_coords[2, pt]
if x < 0 or y < 0 or y >= d_h or x >= d_w:
continue
registered_depth[y, x] = min(registered_depth[y, x], d)
registered_depth[registered_depth > 1e3] = 0
registered_depth = (1000 * registered_depth).astype(np.uint16)
# store calibrated depth
with warnings.catch_warnings():
warnings.simplefilter("ignore")
io.imsave(ds + '/' + seq + '/' + d_file.replace("depth.png", "depth.proj.png"), registered_depth)
process_frames('TrainSplit.txt')
process_frames('TestSplit.txt')
Parallel(n_jobs=7, verbose=0)(
map(delayed(process_scene), [os.path.join(src_folder, scan_name) for scan_name in ['chess', 'fire', 'heads', 'office', 'pumpkin', 'redkitchen', 'stairs']]))
================================================
FILE: data_scripts/IOS_LOGGER_ARKIT_README.md
================================================
# Running with NeuralRecon's demo data and data from ios-logger.
Download the demo scene out of ios-logger from here: https://github.com/zju3dv/NeuralRecon/blob/master/DEMO.md
Follow the instructions in the NeuralRecon repo for how to use ios-logger to make your own captures.
Unzip the folder into your arkit dataset path so that it looks somthing like this:
```
dataset_path
scans
neucon_demodata_b5f1
...
....
```
Run the extraction script that uses modified versions of the functions provided by the NeuralRecon authors:
```bash
python ./data_scripts/ios_logger_preprocessing.py --data_config configs/data/neucon_arkit_default.yaml
```
Make sure you set your correct `dataset_path` folder.
Run tuple file generation (we've already computed one for you in data_splits):
```bash
python ./data_scripts/generate_test_tuples.py --num_workers 16 --data_config configs/data/neucon_arkit_default.yaml
```
Then run the model using this config file, see the full readme for more.
There is unfortunately a break in the pose in the NR demo scene, so you'll to trim the first 350 frames using `--skip_to_frame 350` when running dense frames and `--skip_to_frame 83` when running default.
Run:
```bash
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/neucon_arkit_default.yaml \
--num_workers 8 \
--batch_size 2 \
--fast_cost_volume \
--run_fusion \
--depth_fuser open3d \
--fuse_color \
--skip_to_frame 83;
```
```bash
CUDA_VISIBLE_DEVICES=0 python test.py --name HERO_MODEL \
--output_base_path OUTPUT_PATH \
--config_file configs/models/hero_model.yaml \
--load_weights_from_checkpoint weights/hero_model.ckpt \
--data_config configs/data/neucon_arkit_dense.yaml \
--num_workers 8 \
--batch_size 2 \
--fast_cost_volume \
--run_fusion \
--depth_fuser open3d \
--fuse_color \
--skip_to_frame 350;
```
Should get an output that looks like this for default frames:

================================================
FILE: data_scripts/generate_test_tuples.py
================================================
"""Script for generating DeeoVideoMVS multiview lists in the split folder
indicated. It will export these frame tuples in this format line by line in
the output file:
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
where frame_id_0 is the reference image.
Run like so for generating a list of test tuples of eight frames (default):
python ./data_scripts/generate_test_tuples.py
--data_config configs/data/scannet_default_test.yaml
--num_workers 16
where scannet_default_test.yaml looks like:
!!python/object:options.Options
dataset_path: SCANNET_PATH/
tuple_info_file_location: $tuples_directory$
dataset_scan_split_file: $test_split_list_location$
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: test
frame_tuple_type defines the type of test tuples to produce.
default: Used for all depth and fusion scores.
Will produce default online DVMVS style tuples (online) for each
keyframe. Online means all neighboring frames used in the tuple are in
the past.
offline: Like default but will produce an offline tuple for each keyframe.
Offline means that selected neighboring frames (source frames) will be
both in the future and in the past.
dense: Like default but will produce an online tuple for each frame in the
scan.
dense_offline: Like offline but will produce an offline tuple for each frame
in the scan.
It will output a tuples file with a tuple list at:
{tuple_info_file_location}/{split}{mv_split_filesuffix}
This file uses the defaults for keyframe distances from DVMVS.
"""
import os
import sys
sys.path.append("/".join(sys.path[0].split("/")[:-1]))
import random
import string
from functools import partial
from multiprocessing import Manager
from multiprocessing.pool import Pool
from pathlib import Path
import numpy as np
import options
import tools.keyframe_buffer
from tools.keyframe_buffer import DVMVS_Config
from utils.dataset_utils import get_dataset
def compute_offline_tuple(
poses,
n_measurement_frames,
current_keyframe_index,
reference_pose,
):
"""
Computes an offline tuple by scanning keyframes backwards and forwards in
time.
Args:
poses: poses for the scan
n_measurement_frames: number of measurement (source) frames required for
each tuple. Total number of frames in the tuple is
n_measurement_frames+1
current_keyframe_index: the current frame
reference_pose: the pose of the current frame at current_keyframe_index
Returns:
sample: a dictionary with the key indices whose values are the indices
of the tuple.
"""
sample = {'indices': [current_keyframe_index]}
tuple_keyframe_buffer = tools.keyframe_buffer.OfflineKeyframeBuffer(
buffer_size=DVMVS_Config.test_keyframe_buffer_size*2,
keyframe_pose_distance=DVMVS_Config.test_keyframe_pose_distance,
optimal_t_score=DVMVS_Config.test_optimal_t_measure,
optimal_R_score=DVMVS_Config.test_optimal_R_measure,
store_return_indices=True,
)
# prime the buffer with the reference pose
response = tuple_keyframe_buffer.try_new_keyframe(
reference_pose.copy(),
None,
index=current_keyframe_index,
)
current_backwards_index = current_keyframe_index-1
current_forwards_index = current_keyframe_index+1
direction = True
count_added = 0
exhausted_forward = False
exhausted_backward = False
while not exhausted_forward or not exhausted_backward:
# step away from the current frame alternating in both directions
# fill the buffer with keyframes from both direcitons as we go.
if exhausted_forward and exhausted_backward:
break
# check which way we should be looking
if direction:
# going forward, so get the forward pose to update the buffer
direction = False
if current_forwards_index >= len(poses):
exhausted_forward = True
continue
new_frame_index = current_forwards_index
new_frame_pose = poses[new_frame_index].copy()
current_forwards_index += 1
else:
# going backward, so get the forward pose to update the buffer
direction = True
if current_backwards_index < 0:
exhausted_backward = True
continue
new_frame_index = current_backwards_index
new_frame_pose = poses[new_frame_index].copy()
current_backwards_index -= 1
# poll the buffer,
response = tuple_keyframe_buffer.try_new_keyframe(
new_frame_pose, None, index=new_frame_index
)
if response == 1:
count_added +=1
# if we have enough frames, then stop.
if count_added >= DVMVS_Config.test_keyframe_buffer_size*2:
break
# the buffer is full, now get source frames.
measurement_frames = (tuple_keyframe_buffer.
get_best_measurement_frames_for_0index(n_measurement_frames))
for (_, _, measurement_index) in measurement_frames:
sample["indices"].append(measurement_index)
return sample
def default_dvmvs_tuples(scan, poses, dists_to_last_valid, n_measurement_frames):
"""
Creates a list of default DVMVS tuples for a scan's poses. Only tuples at
keyframes will be returned. Each tuple will be online (frames will be behind
the current frame in time.)
This will not return a tuple for the first frame.
Args:
scan: scan id string.
poses: a list of poses.
dists_to_last_valid: list with distances from each current valid frame
to the last valid frame. Pass Nones if you you're passing invalid
poses and want the DVMVS keyframe handler to take care of them.
n_measurement_frames: number of measurement (source) frames required for
each tuple. Total number of frames in the tuple is
n_measurement_frames+1
Returns:
samples: a list of dictionaries where each item dicitonary contians
a scan's id and a list of indices for the tuple's frames.
"""
keyframe_buffer = tools.keyframe_buffer.KeyframeBuffer(
buffer_size=DVMVS_Config.test_keyframe_buffer_size,
keyframe_pose_distance=DVMVS_Config.test_keyframe_pose_distance,
optimal_t_score=DVMVS_Config.test_optimal_t_measure,
optimal_R_score=DVMVS_Config.test_optimal_R_measure,
store_return_indices=True,
)
samples = []
for i in range(0, len(poses)):
sample = {'scan': scan,
'indices': [i]}
reference_pose = poses[i].copy()
# POLL THE KEYFRAME BUFFER
response = keyframe_buffer.try_new_keyframe(
reference_pose, None, dists_to_last_valid[i], index=i
)
if response == 3:
print("Tracking lost!")
elif response == 1:
measurement_frames = (keyframe_buffer.
get_best_measurement_frames(n_measurement_frames))
for (_, _, measurement_index) in measurement_frames:
sample["indices"].append(measurement_index)
samples.append(sample)
return samples
def offline_dvmvs_tuples(scan, poses, n_measurement_frames):
"""
Creates a list of offline DVMVS tuples for a scan's poses. Only tuples at
keyframes will be returned. This will provide frames both ahead of and
behind the current frame.
This will not return a tuple for the first frame.
Args:
scan: scan id string.
poses: a list of poses.
n_measurement_frames: number of measurement (source) frames required for
each tuple. Total number of frames in the tuple is
n_measurement_frames+1
Returns:
samples: a list of dictionaries where each item dicitonary contians
a scan's id and a list of indices for the tuple's frames.
"""
samples = []
keyframe_buffer = tools.keyframe_buffer.KeyframeBuffer(
buffer_size=DVMVS_Config.test_keyframe_buffer_size,
keyframe_pose_distance=DVMVS_Config.test_keyframe_pose_distance,
optimal_t_score=DVMVS_Config.test_optimal_t_measure,
optimal_R_score=DVMVS_Config.test_optimal_R_measure,
store_return_indices=True,
)
for i in range(0, len(poses)):
reference_pose = poses[i].copy()
response = keyframe_buffer.try_new_keyframe(
pose=reference_pose.copy(),
image=None,
index=i
)
if response != 1:
continue
sample = compute_offline_tuple(poses, n_measurement_frames,
i, reference_pose.copy())
sample['scan'] = scan
if len(sample["indices"]) == 1 and i == 0:
# first frame and no indices available.
continue
else:
samples.append(sample)
return samples
def dense_dvmvs_tuples(scan, poses, n_measurement_frames):
"""
Creates a list of DVMVS online tuples for a scan's poses at each frame.
This will not return a tuple for the first frame.
Args:
scan: scan id string.
poses: a list of poses.
n_measurement_frames: number of measurement (source) frames required for
each tuple. Total number of frames in the tuple is
n_measurement_frames+1
Returns:
samples: a list of dictionaries where each item dicitonary contians
a scan's id and a list of indices for the tuple's frames.
"""
samples = []
for i in range(0, len(poses)):
sample = {'scan': scan,
'indices': [i]}
reference_pose = poses[i]
keyframe_buffer = tools.keyframe_buffer.OfflineKeyframeBuffer(
buffer_size=DVMVS_Config.test_keyframe_buffer_size,
keyframe_pose_distance=DVMVS_Config.test_keyframe_pose_distance,
optimal_t_score=DVMVS_Config.test_optimal_t_measure,
optimal_R_score=DVMVS_Config.test_optimal_R_measure,
store_return_indices=True)
response = keyframe_buffer.try_new_keyframe(
reference_pose, None, index=i
)
num_available_measurement_frames = 0
current_backwards_index = i-1
exhausted_backward = False
count_added = 0
while num_available_measurement_frames != n_measurement_frames:
# POLL THE KEYFRAME BUFFER
if exhausted_backward:
break
if current_backwards_index < 0:
exhausted_backward = True
break
new_frame_index = current_backwards_index
new_frame_pose = poses[new_frame_index]
current_backwards_index -= 1
response = keyframe_buffer.try_new_keyframe(
new_frame_pose, None, index=new_frame_index
)
if response == 1:
count_added +=1
if count_added >= DVMVS_Config.test_keyframe_buffer_size:
break
measurement_frames = (keyframe_buffer.
get_best_measurement_frames_for_0index(n_measurement_frames))
for (_, _, measurement_index) in measurement_frames:
sample["indices"].append(measurement_index)
if len(sample["indices"]) == 1 and i == 0:
# first frame and no indices available.
continue
else:
samples.append(sample)
return samples
def offline_dense_dvmvs_tuples(scan, poses, n_measurement_frames):
"""
Creates a list of DVMVS offline tuples for a scan's poses at each frame.
This will not return a tuple for the first frame. For frames where there are
not enough keyframes to build the tuple (near the beginning of the sequency)
frame indices will be repeated to compensate and pad the tuple.
Args:
scan: scan id string.
poses: a list of poses.
n_measurement_frames: number of measurement (source) frames required for
each tuple. Total number of frames in the tuple is
n_measurement_frames+1
Returns:
samples: a list of dictionaries where each item dicitonary contians
a scan's id and a list of indices for the tuple's frames.
"""
samples = []
for i in range(0, len(poses)):
sample = {'scan': scan,
'indices': [i]}
reference_pose = poses[i]
sample = compute_offline_tuple(poses, n_measurement_frames,
i, reference_pose)
sample['scan'] = scan
if len(sample["indices"]) == 1 and i == 0:
# first frame and no indices available.
continue
else:
samples.append(sample)
return samples
def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
"""
Returns a list of tuples according to the options at opts_temp_filepath.
This will not return a tuple for the first frame. For frames where there are
not enough keyframes to build the tuple (near the beginning of the sequency)
frame indices will be repeated to compensate and pad the tuple.
Args:
opts_temp_filepath: filepath for an options config file.
scan: scan to operate on.
count: total count of multi process scans.
progress: a Pool() progress value for tracking progress. For debugging
you can pass
multiprocessing.Manager().Value('i', 0)
for this.
Returns:
item_list: a list of strings where each string is the cocnatenated
scan id and frame_ids for every tuple.
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
"""
item_list = []
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(
config_filepaths=opts_temp_filepath,
ignore_cl_args=True,
)
opts = option_handler.options
# get dataset
dataset_class, _ = get_dataset(
opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id,
verbose=False,
)
ds = dataset_class(
dataset_path=opts.dataset_path,
mv_tuple_file_suffix=None,
split=opts.split,
tuple_info_file_location=opts.tuple_info_file_location,
pass_frame_id=True,
verbose_init=False,
)
valid_frames = ds.get_valid_frame_ids(opts.split, scan)
try:
check_valid_dist = int(valid_frames[0].strip().split(" ")[2])
except:
if opts.frame_tuple_type == "default":
print(f"\nWARNING: Couldn't find max valid distances in the valid_frames "
f"file for scan {scan}. Please delete existing valid_frames.txt "
f"and rerun to regenerate valid frames. "
f"There's a difference of 9 extra frames out of 25599 for the "
f"ScanNetv2 test set.\n")
dists_to_last_valid = []
frame_ind_to_frame_id = {}
for frame_ind, frame_line in enumerate(valid_frames):
frame_ind_to_frame_id[frame_ind] = frame_line.strip().split(" ")[1]
try:
dists_to_last_valid.append(int(frame_line.strip().split(" ")[2]))
except:
# just add Noness
dists_to_last_valid.append(None)
poses = []
for frame_ind in range(len(valid_frames)):
frame_id = frame_ind_to_frame_id[frame_ind]
world_T_cam_44, _ = ds.load_pose(scan.rstrip("\n"), frame_id)
poses.append(world_T_cam_44)
subsequence_length = opts.num_images_in_tuple
n_measurement_frames = subsequence_length - 1
if opts.frame_tuple_type == "default":
samples = default_dvmvs_tuples(scan, poses, dists_to_last_valid, n_measurement_frames)
elif opts.frame_tuple_type == "offline":
samples = offline_dvmvs_tuples(scan, poses, n_measurement_frames)
elif opts.frame_tuple_type == "dense":
samples = dense_dvmvs_tuples(scan, poses, n_measurement_frames)
elif opts.frame_tuple_type == "dense_offline":
samples = offline_dense_dvmvs_tuples(scan, poses, n_measurement_frames)
else:
ValueError(f"Not a recognized tuple frame type: "
f"{opts.frame_tuple_type}")
num_repeats = 0
for sample in samples:
sampled_indices = sample["indices"]
if len(sampled_indices) != subsequence_length:
# not enough frames in the buffer.
# get all frames seen so far that aren't keyframes
available_indices = list(range(0, sampled_indices[0]))
available_indices = [frame_ind for frame_ind in available_indices
if frame_ind not in sampled_indices]
# pick from frames that haven't been touched yet (available_indices).
diff = subsequence_length - len(sampled_indices)
if diff > len(available_indices):
diff = len(available_indices)
# preferably pick from recent frames
back_search_dist = (30 if len(available_indices) >= 30 else
len(available_indices))
sampled_indices += random.sample(
available_indices[-back_search_dist:],
k=diff
)
# check again in case we still don't have enough and random sample
# repeat if we don't
if len(sampled_indices) != subsequence_length:
diff = subsequence_length - len(sampled_indices)
num_repeats+=diff
sampled_indices += random.choices(sampled_indices[1:], k=diff)
assert len(sampled_indices) == subsequence_length
chosen_frame_ids = [frame_ind_to_frame_id[frame_ind]
for frame_ind in sampled_indices]
cat_ids = ' '.join([str(frame_id) for frame_id in chosen_frame_ids])
item_list.append(f"{scan} {cat_ids}")
progress.value += 1
print(f"Completed scan {scan}, {progress.value} of total {count}. "
f"# Samples: {len(samples)} of {len(poses)} poses. "
f"Samples with repeated frames: {num_repeats}.\r")
return item_list
def crawl(opts_temp_filepath, opts, scans):
"""
Multiprocessing helper for crawl_subprocess_long.
Returns a list of tuples according to the options at opts_temp_filepath.
Args:
opts_temp_filepath: filepath for an options config file.
opts: options dataclass.
scans: scans to multiprocess.
Returns:
item_list: a list of strings where each string is the cocnatenated
scan id and frame_ids for every tuple for every scan in scans.
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
"""
pool = Pool(opts.num_workers)
manager = Manager()
count = len(scans)
progress = manager.Value('i', 0)
item_list = []
for scan_item_list in pool.imap_unordered(
partial(
crawl_subprocess_long,
opts_temp_filepath,
count=count,
progress=progress
),
scans,
):
item_list.extend(scan_item_list)
return item_list
if __name__ == '__main__':
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(ignore_cl_args=False)
option_handler.pretty_print_options()
opts = option_handler.options
Path(os.path.join(os.path.expanduser("~"), "tmp/")).mkdir(
parents=True, exist_ok=True
)
opts_temp_filepath = os.path.join(
os.path.expanduser("~"),
"tmp/",
''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
+ ".yaml",
)
option_handler.save_options_as_yaml(opts_temp_filepath, opts)
np.random.seed(42)
random.seed(42)
if opts.gpus == 0:
print("Setting precision to 32 bits since --gpus is set to 0.")
opts.precision = 32
# get dataset
dataset_class, scan_names = get_dataset(
opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id,
)
item_list = []
Path(opts.tuple_info_file_location).mkdir(exist_ok=True, parents=True)
split_filename = f"{opts.split}{opts.mv_tuple_file_suffix}"
split_filepath = os.path.join(opts.tuple_info_file_location, split_filename)
print(f"Saving to {split_filepath}\n")
if opts.single_debug_scan_id is not None:
item_list = crawl_subprocess_long(
opts_temp_filepath,
opts.single_debug_scan_id,
0, Manager().Value('i', 0),
)
else:
item_list = crawl(opts_temp_filepath, opts, scan_names)
with open(split_filepath, "w") as f:
for line in item_list:
f.write(line + "\n")
print(f"Saved to {split_filepath}")
================================================
FILE: data_scripts/generate_train_tuples.py
================================================
"""Script for generating DeeoVideoMVS multiview lists in the split folder
indicated. It will export these frame tuples in this format line by line in
the output file:
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
where frame_id_0 is the reference image.
Run like so for generating a list of train tuples of eight frames (default):
python ./data_scripts/generate_train_tuples.py
--data_config configs/data/scannet_default_train.yaml
--num_workers 16
where scannet_default_train.yaml looks like:
!!python/object:options.Options
dataset_path: SCANNET_PATH/
tuple_info_file_location: $tuples_directory$
dataset_scan_split_file: $train_split_list_location$
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
split: train
For val, use configs/data/scannet_default_val.yaml.
It will output a tuples file with a tuple list at:
{tuple_info_file_location}/{split}{mv_split_filesuffix}
This file uses the defaults for frame distances from DVMVS.
This module also borrows the main tuple generation function from
the DeepVideoMVS repo https://github.com/ardaduz/deep-video-mvs
"""
import copy
import os
import sys
sys.path.append("/".join(sys.path[0].split("/")[:-1]))
import random
import string
from functools import partial
from multiprocessing import Manager
from multiprocessing.pool import Pool
from pathlib import Path
import numpy as np
import options
from tools.keyframe_buffer import DVMVS_Config, is_valid_pair
from utils.dataset_utils import get_dataset
def gather_pairs_train(poses, used_pairs,
is_backward, initial_pose_dist_min, initial_pose_dist_max):
sequence_length = len(poses)
while_range = range(0, sequence_length)
pose_dist_min = copy.deepcopy(initial_pose_dist_min)
pose_dist_max = copy.deepcopy(initial_pose_dist_max)
used_measurement_indices = set()
# Gather pairs
check_future = False
pairs = []
if is_backward:
i = sequence_length - 1
step = -1
first_limit = 5
second_limit = sequence_length - 5
else:
i = 0
step = 1
first_limit = sequence_length - 5
second_limit = 5
loosening_counter = 0
while i in while_range:
pair = (i, -1)
if check_future:
for j in range(i + step, first_limit, step):
if (j not in used_measurement_indices
and (i, j) not in used_pairs):
valid = is_valid_pair(poses[i], poses[j],
pose_dist_min, pose_dist_max)
if valid:
pair = (i, j)
pairs.append(pair)
used_pairs.add(pair)
used_pairs.add((pair[1], pair[0]))
used_measurement_indices.add(j)
pose_dist_min = copy.deepcopy(initial_pose_dist_min)
pose_dist_max = copy.deepcopy(initial_pose_dist_max)
i += step
check_future = False
loosening_counter = 0
break
else:
for j in range(i - step, second_limit, -step):
if j not in used_measurement_indices and (i, j) not in used_pairs:
valid = is_valid_pair(poses[i], poses[j],
pose_dist_min, pose_dist_max)
if valid:
pair = (i, j)
pairs.append(pair)
used_pairs.add(pair)
used_pairs.add((pair[1], pair[0]))
used_measurement_indices.add(j)
pose_dist_min = copy.deepcopy(initial_pose_dist_min)
pose_dist_max = copy.deepcopy(initial_pose_dist_max)
i += step
check_future = False
loosening_counter = 0
break
if pair[1] == -1:
if check_future:
pose_dist_min = pose_dist_min / 1.1
pose_dist_max = pose_dist_max * 1.1
check_future = False
loosening_counter += 1
if loosening_counter > 1:
i += step
loosening_counter = 0
else:
check_future = True
else:
check_future = False
return pairs
def crawl_subprocess_short(opts_temp_filepath, scan, count, progress):
"""
Returns a list of DVMVS train tuples according to the options at
opts_temp_filepath for two frame tuples.
Args:
opts_temp_filepath: filepath for an options config file.
scan: scan to operate on.
count: total count of multi process scans.
progress: a Pool() progress value for tracking progress. For debugging
you can pass
multiprocessing.Manager().Value('i', 0)
for this.
Returns:
item_list: a list of strings where each string is the cocnatenated
scan id and frame_ids for every tuple.
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
"""
scan_item_list = []
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(config_filepaths=opts_temp_filepath,
ignore_cl_args=True)
opts = option_handler.options
# get dataset
dataset_class, _ = get_dataset(opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id, verbose=False)
ds = dataset_class(dataset_path=opts.dataset_path,
mv_tuple_file_suffix=None,
split=opts.split,
tuple_info_file_location=opts.tuple_info_file_location,
pass_frame_id=True,
verbose_init=False)
valid_frames = ds.get_valid_frame_ids(opts.split, scan)
frame_ind_to_frame_id = {}
for frame_ind, frame_line in enumerate(valid_frames):
frame_ind_to_frame_id[frame_ind] = frame_line.strip().split(" ")[1]
poses = []
for frame_ind in range(len(valid_frames)):
frame_id = frame_ind_to_frame_id[frame_ind]
world_T_cam_44, _ = ds.load_pose(scan.rstrip("\n"), frame_id)
poses.append(world_T_cam_44)
samples = []
used_pairs = set()
for multiplier in [(1.0, False), (0.666, True), (1.5, False)]:
pairs = gather_pairs_train(poses, used_pairs,
is_backward=multiplier[1],
initial_pose_dist_min=(multiplier[0] *
DVMVS_Config.train_minimum_pose_distance),
initial_pose_dist_max=(multiplier[0] *
DVMVS_Config.train_maximum_pose_distance))
for pair in pairs:
i, j = pair
sample = {'scan': scan,
'indices': [i, j]}
samples.append(sample)
for sample in samples:
chosen_frame_ids = [ds.idx_to_scan_id_frame_id(frame_ind)[1]
for frame_ind in sample["indices"]]
cat_ids = ' '.join([str(frame_id) for frame_id in chosen_frame_ids])
scan_item_list.append(f"{scan} {cat_ids}")
progress.value += 1
print(f"Completed scan {scan}, {progress.value} of total {count}\r")
return scan_item_list
def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
"""
Returns a list of DVMVS train tuples according to the options at
opts_temp_filepath for tuples longer than two frames.
Args:
opts_temp_filepath: filepath for an options config file.
scan: scan to operate on.
count: total count of multi process scans.
progress: a Pool() progress value for tracking progress. For debugging
you can pass
multiprocessing.Manager().Value('i', 0)
for this.
Returns:
item_list: a list of strings where each string is the cocnatenated
scan id and frame_ids for every tuple.
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
"""
scan_item_list = []
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(
config_filepaths=opts_temp_filepath,
ignore_cl_args=True,
)
opts = option_handler.options
# get dataset
dataset_class, _ = get_dataset(
opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id,
verbose=False,
)
ds = dataset_class(
dataset_path=opts.dataset_path,
mv_tuple_file_suffix=None,
split=opts.split,
tuple_info_file_location=opts.tuple_info_file_location,
pass_frame_id=True,
verbose_init=False,
)
valid_frames = ds.get_valid_frame_ids(opts.split, scan)
frame_ind_to_frame_id = {}
for frame_ind, frame_line in enumerate(valid_frames):
frame_ind_to_frame_id[frame_ind] = frame_line.strip().split(" ")[1]
poses = []
for frame_ind in range(len(valid_frames)):
frame_id = frame_ind_to_frame_id[frame_ind]
world_T_cam_44, _ = ds.load_pose(scan.rstrip("\n"), frame_id)
poses.append(world_T_cam_44)
subsequence_length = opts.num_images_in_tuple
sequence_length = len(poses)
used_pairs = set()
usage_threshold = 1
used_nodes = dict()
for i in range(sequence_length):
used_nodes[i] = 0
calculated_step = DVMVS_Config.train_crawl_step
samples = []
for offset, multiplier, is_backward in [(0 % calculated_step, 1.0, False),
(1 % calculated_step, 0.666, True),
(2 % calculated_step, 1.5, False),
(3 % calculated_step, 0.8, True),
(4 % calculated_step, 1.25, False),
(5 % calculated_step, 1.0, True),
(6 % calculated_step, 0.666, False),
(7 % calculated_step, 1.5, True),
(8 % calculated_step, 0.8, False),
(9 % calculated_step, 1.25, True)]:
if is_backward:
start = sequence_length - 1 - offset
step = -calculated_step
limit = subsequence_length
else:
start = offset
step = calculated_step
limit = sequence_length - subsequence_length + 1
for i in range(start, limit, step):
if used_nodes[i] > usage_threshold:
continue
sample = {'scan': scan,
'indices': [i]}
previous_index = i
valid_counter = 1
any_counter = 1
reached_sequence_limit = False
while valid_counter < subsequence_length:
if is_backward:
j = i - any_counter
reached_sequence_limit = j < 0
else:
j = i + any_counter
reached_sequence_limit = j >= sequence_length
if not reached_sequence_limit:
current_index = j
check1 = used_nodes[current_index] <= usage_threshold
check2 = (previous_index, current_index) not in used_pairs
check3 = is_valid_pair(
poses[previous_index],
poses[current_index],
(multiplier *
DVMVS_Config.train_minimum_pose_distance),
(multiplier *
DVMVS_Config.train_maximum_pose_distance),
t_norm_threshold=(multiplier *
DVMVS_Config.train_minimum_pose_distance * 0.5))
if check1 and check2 and check3:
sample['indices'].append(current_index)
previous_index = copy.deepcopy(current_index)
valid_counter += 1
any_counter += 1
else:
break
if not reached_sequence_limit:
previous_node = sample['indices'][0]
used_nodes[previous_node] += 1
for current_node in sample['indices'][1:]:
used_nodes[current_node] += 1
used_pairs.add((previous_node, current_node))
used_pairs.add((current_node, previous_node))
previous_node = copy.deepcopy(current_node)
samples.append(sample)
for sample in samples:
chosen_frame_ids = [frame_ind_to_frame_id[frame_ind] for
frame_ind in sample["indices"]]
cat_ids = ' '.join([str(frame_id) for frame_id in chosen_frame_ids])
scan_item_list.append(f"{scan} {cat_ids}")
progress.value += 1
print(f"Completed scan {scan}, {progress.value} of total {count}\r")
return scan_item_list
def crawl(opts_temp_filepath, opts, scans):
"""
Multiprocessing helper for crawl_subprocess_long and crawl_subprocess_long.
Returns a list of train tuples according to the options at
opts_temp_filepath.
Args:
opts_temp_filepath: filepath for an options config file.
opts: options dataclass.
scans: scans to multiprocess.
Returns:
item_list: a list of strings where each string is the cocnatenated
scan id and frame_ids for every tuple for every scan in scans.
scan_id frame_id_0 frame_id_1 ... frame_id_N-1
"""
pool = Pool(opts.num_workers)
manager = Manager()
count = len(scans)
progress = manager.Value('i', 0)
item_list = []
crawler = (crawl_subprocess_short if opts.num_images_in_tuple == 2
else crawl_subprocess_long)
for scan_item_list in pool.imap_unordered(
partial(
crawler,
opts_temp_filepath,
count=count,
progress=progress),
scans,
):
item_list.extend(scan_item_list)
return item_list
if __name__ == '__main__':
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(ignore_cl_args=False)
option_handler.pretty_print_options()
opts = option_handler.options
Path(os.path.join(os.path.expanduser("~"), "tmp/")).mkdir(
parents=True, exist_ok=True
)
opts_temp_filepath = os.path.join(
os.path.expanduser("~"),
"tmp/",
''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
+ ".yaml",
)
option_handler.save_options_as_yaml(opts_temp_filepath, opts)
np.random.seed(42)
random.seed(42)
if opts.gpus == 0:
print("Setting precision to 32 bits since --gpus is set to 0.")
opts.precision = 32
# get dataset
dataset_class, scan_names = get_dataset(opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id, verbose=False)
Path(opts.tuple_info_file_location).mkdir(exist_ok=True, parents=True)
split_filename = f"{opts.split}{opts.mv_tuple_file_suffix}"
split_filepath = os.path.join(opts.tuple_info_file_location, split_filename)
print(f"Saving to {split_filepath}")
item_list = []
if opts.single_debug_scan_id is not None:
crawler = (crawl_subprocess_short if opts.num_images_in_tuple == 2
else crawl_subprocess_long)
item_list = crawler(
opts_temp_filepath,
opts.single_debug_scan_id,
0, Manager().Value('i', 0),
)
else:
item_list = crawl(opts_temp_filepath, opts, scan_names)
random.shuffle(item_list)
with open(split_filepath, "w") as f:
for line in item_list:
f.write(line + "\n")
print(f"Saved to {split_filepath}")
================================================
FILE: data_scripts/ios_logger_preprocessing.py
================================================
import os
import sys
sys.path.append("/".join(sys.path[0].split("/")[:-1]))
from datasets.arkit_dataset import process_data
import options
""" Download scans and extract each to a folder with their name like so:
dataset_path
scans
neucon_demodata_b5f1
...
....
"""
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options()
opts = option_handler.options
if opts.dataset_scan_split_file is not None:
f = open(opts.dataset_scan_split_file, "r")
scans = f.readlines()
scans = [scan.strip() for scan in scans]
f.close()
elif opts.single_debug_scan_id is not None:
scans = [opts.single_debug_scan_id]
else:
print("No valid scans pointers.")
for scan in scans:
path_dir = os.path.join(opts.dataset_path, "scans", scan)
process_data(path_dir)
================================================
FILE: data_scripts/precompute_valid_frames.py
================================================
"""Script for precomputing and storing a list of valid frames per scan. A valid
frame is defined as one that has an existing RGB frame, an existing depth
map, and a valid pose.
Run like so for test (default):
python ./scripts/precompute_valid_frames.py
--data_config configs/data/scannet_default_test.yaml
--num_workers 16
--split test
where scannet_default_test.yaml looks like:
!!python/object:options.Options
dataset_path: SCANNET_PATH/
tuple_info_file_location: SCANNET_PATH/tuples
dataset_scan_split_file: SCANNET_PATH/scannetv2_test.txt
dataset: scannet
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
num_images_in_tuple: 8
frame_tuple_type: default
For validation, use scannet_default_val.yaml, and for train use
scannet_default_train.yaml
It will save a valid_frames.txt file where the dataset class defines.
"""
import os
import sys
sys.path.append("/".join(sys.path[0].split("/")[:-1]))
import random
import string
from functools import partial
from multiprocessing import Manager
from multiprocessing.pool import Pool
from pathlib import Path
import numpy as np
import options
from utils.dataset_utils import get_dataset
def process_scan(opts_temp_filepath, scan, count, progress):
"""
Precomputes a scan's valid frames by calling the dataset's appropriate
function.
Args:
opts_temp_filepath: filepath for an options config file.
scan: scan to operate on.
count: total count of multi process scans.
progress: a Pool() progress value for tracking progress. For debugging
you can pass
multiprocessing.Manager().Value('i', 0)
for this.
"""
item_list = []
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(config_filepaths=opts_temp_filepath,
ignore_cl_args=True)
opts = option_handler.options
# get dataset
dataset_class, _ = get_dataset(
opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id,
verbose=False,
)
ds = dataset_class(
dataset_path=opts.dataset_path,
mv_tuple_file_suffix=None,
split=opts.split,
tuple_info_file_location=opts.tuple_info_file_location,
pass_frame_id=True,
verbose_init=False,
)
_ = ds.get_valid_frame_ids(opts.split, scan)
progress.value += 1
print(f"Completed scan {scan}, {progress.value} of total {count}.")
return item_list
def multi_process_scans(opts_temp_filepath, opts, scans):
"""
Multiprocessing helper for crawl_subprocess_long and crawl_subprocess_long.
Precomputes a scan's valid frames by calling the dataset's appropriate
function.
Args:
opts_temp_filepath: filepath for an options config file.
opts: options dataclass.
scans: scans to multiprocess.
"""
pool = Pool(opts.num_workers)
manager = Manager()
count = len(scans)
progress = manager.Value('i', 0)
item_list = []
for scan_item_list in pool.imap_unordered(
partial(
process_scan,
opts_temp_filepath,
count=count,
progress=progress
),
scans,
):
item_list.extend(scan_item_list)
return item_list
if __name__ == '__main__':
# load options file
option_handler = options.OptionsHandler()
option_handler.parse_and_merge_options(ignore_cl_args=False)
option_handler.pretty_print_options()
opts = option_handler.options
opts_temp_filepath = os.path.join(
os.path.expanduser("~"),
"tmp/",
''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
+ ".yaml",
)
option_handler.save_options_as_yaml(opts_temp_filepath, opts)
np.random.seed(42)
random.seed(42)
if opts.gpus == 0:
print("Setting precision to 32 bits since --gpus is set to 0.")
opts.precision = 32
# get dataset
dataset_class, scan_names = get_dataset(
opts.dataset,
opts.dataset_scan_split_file,
opts.single_debug_scan_id,
)
item_list = []
Path(opts.tuple_info_file_location).mkdir(exist_ok=True, parents=True)
split_filename = f"{opts.split}{opts.mv_tuple_file_suffix}"
split_filepath = os.path.join(opts.tuple_info_file_location, split_filename)
print(f"Processing valid frames.\n")
if opts.single_debug_scan_id is not None:
item_list = process_scan(
opts_temp_filepath,
opts.single_debug_scan_id,
0,
Manager().Value('i', 0),
)
else:
item_list = multi_process_scans(opts_temp_filepath, opts, scan_names)
with open(split_filepath, "w") as f:
for line in item_list:
f.write(line + "\n")
print(f"Complete")
================================================
FILE: data_scripts/scannet_wrangling_scripts/LICENSE
================================================
The LICENSE applies only to reader.py and SensorData.py.
Copyright 2017
Angela Dai, Angel X. Chang, Manolis Savva, Maciej Halber, Thomas Funkhouser, Matthias Niessner
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: data_scripts/scannet_wrangling_scripts/README.md
================================================
# Downloading and Extracting ScanNetv2
Developed and tested with python 3.9.
The included license at LICENSE applies only to `reader.py` and `SensorData.py`.
These scripts should help you export ScanNetv2 to the following format:
SCANNET_ROOT
scans_test (test scans)
scene0707
scene0707_00_vh_clean_2.ply (gt mesh)
sensor_data
frame-000261.pose.txt
frame-000261.color.jpg
frame-000261.color.512.png (optional, image at 512x384)
frame-000261.color.640.png (optional, image at 640x480)
frame-000261.depth.png (full res depth, stored scale *1000)
frame-000261.depth.256.png (optional, depth at 256x192 also
scaled)
scene0707.txt (scan metadata and image sizes)
intrinsic
intrinsic_depth.txt
intrinsic_color.txt
...
scans (val and train scans)
scene0000_00
(see above)
scene0000_01
....
Make sure all the packages in `env.yml` are installed in your environment.
## Downloading ScanNetv2
The `download_scannet.py` script is from https://kaldir.vc.in.tum.de/scannet/download-scannet.py
Please make sure you fill in this form before downloading the data:
https://kaldir.vc.in.tum.de/scannet/ScanNet_TOS.pdf
Download the dataset by running:
```
python download_scannet.py -o SCANNET_ROOT
```
For one scan debug use:
```
python download_scannet.py -o SCANNET_ROOT --id scene0707_00
```
This will download a `.sens` file, `.txt` file, the high resolution mesh `ply`, and a lower resolution mesh `ply`.
`.txt` will include meta information for the scan. See the next section for extracting the `.sens` file.
## Extracting data from .sens files
Please use the intrinsics directly from the downloaded `.txt` file from the dataset.
This is a modified version of the SensReader python script at
https://github.com/ScanNet/ScanNet/tree/master/SensReader/python
`reader.py` will extract depth, jpg, and intrinics files from ScanNetv2's downloaded `.sens` files. It will dump the `jpg` data directly to disk without uncompressing/compressing.
To extract all scans for test:
```
python reader.py --scans_folder SCANNET_ROOT/scans_test \
--output_path OUTPUT_PATH/scans_test \
--scan_list_file splits/scannetv2_test.txt \
--num_workers 12 \
--export_poses \
--export_depth_images \
--export_color_images \
--export_intrinsics;
```
For train and val
```
python reader.py --scans_folder SCANNET_ROOT/scans \
--output_path OUTPUT_PATH/scans \
--scan_list_file splits/scannetv2_train.txt \
--num_workers 12 \
--export_poses \
--export_depth_images \
--export_color_images \
--export_intrinsics;
python reader.py --scans_folder SCANNET_ROOT/scans \
--output_path OUTPUT_PATH/scans \
--scan_list_file splits/scannetv2_val.txt \
--num_workers 12 \
--export_poses \
--export_depth_images \
--export_color_images \
--export_intrinsics;
```
`OUTPUT_PATH` can be the same directory as the ScanNet root directory `SCANNET_ROOT`.
For one scan use `--single_debug_scan_id`.
For caching resized pngs for depth and color files, run:
```
python reader.py --scans_folder SCANNET_ROOT/scans \
--output_path OUTPUT_PATH/scans \
--scan_list_file splits/scannetv2_train.txt \
--num_workers 12 \
--export_depth_images \
--export_color_images \
--rgb_resize 512 384 \
--depth_resize 256 192;
```
and for images at `640x480`:
```
python reader.py --scans_folder SCANNET_ROOT/scans \
--output_path OUTPUT_PATH/scans \
--scan_list_file splits/scannetv2_train.txt \
--num_workers 12 \
--export_color_images \
--rgb_resize 640 480 \
```
================================================
FILE: data_scripts/scannet_wrangling_scripts/SensorData.py
================================================
import os, struct
import numpy as np
import zlib
import imageio
import cv2
import png
from PIL import Image
from contextlib import contextmanager
COMPRESSION_TYPE_COLOR = {-1:'unknown', 0:'raw', 1:'png', 2:'jpeg'}
COMPRESSION_TYPE_DEPTH = {-1:'unknown', 0:'raw_ushort', 1:'zlib_ushort', 2:'occi_ushort'}
@contextmanager
def print_array_on_one_line():
oldoptions = np.get_printoptions()
np.set_printoptions(linewidth=np.inf)
np.set_printoptions(linewidth=np.inf)
yield
np.set_printoptions(**oldoptions)
class RGBDFrame():
def load(self, file_handle):
self.camera_to_world = np.asarray(struct.unpack('f'*16, file_handle.read(16*4)), dtype=np.float32).reshape(4, 4)
self.timestamp_color = struct.unpack('Q', file_handle.read(8))[0]
self.timestamp_depth = struct.unpack('Q', file_handle.read(8))[0]
self.color_size_bytes = struct.unpack('Q', file_handle.read(8))[0]
self.depth_size_bytes = struct.unpack('Q', file_handle.read(8))[0]
self.color_data = b''.join(struct.unpack('c'*self.color_size_bytes, file_handle.read(self.color_size_bytes)))
self.depth_data = b''.join(struct.unpack('c'*self.depth_size_bytes, file_handle.read(self.depth_size_bytes)))
def decompress_depth(self, compression_type):
if compression_type == 'zlib_ushort':
return self.decompress_depth_zlib()
else:
raise
def decompress_depth_zlib(self):
return zlib.decompress(self.depth_data)
def decompress_color(self, compression_type):
if compression_type == 'jpeg':
return self.decompress_color_jpeg()
else:
raise
def dump_color_to_file(self, compression_type, filepath):
if compression_type == 'jpeg':
filepath += ".jpg"
else:
raise
f = open(filepath, "wb")
f.write(self.color_data)
f.close()
def decompress_color_jpeg(self):
return imageio.imread(self.color_data)
class SensorData:
def __init__(self, filename):
self.version = 4
self.load(filename)
def load(self, filename):
with open(filename, 'rb') as f:
version = struct.unpack('I', f.read(4))[0]
assert self.version == version
strlen = struct.unpack('Q', f.read(8))[0]
self.sensor_name = b''.join(struct.unpack('c'*strlen, f.read(strlen)))
self.intrinsic_color = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4)
self.extrinsic_color = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4)
self.intrinsic_depth = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4)
self.extrinsic_depth = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4)
self.color_compression_type = COMPRESSION_TYPE_COLOR[struct.unpack('i', f.read(4))[0]]
self.depth_compression_type = COMPRESSION_TYPE_DEPTH[struct.unpack('i', f.read(4))[0]]
self.color_width = struct.unpack('I', f.read(4))[0]
self.color_height = struct.unpack('I', f.read(4))[0]
self.depth_width = struct.unpack('I', f.read(4))[0]
self.depth_height = struct.unpack('I', f.read(4))[0]
self.depth_shift = struct.unpack('f', f.read(4))[0]
self.num_frames = struct.unpack('Q', f.read(8))[0]
self.frames = []
for i in range(self.num_frames):
frame = RGBDFrame()
frame.load(f)
self.frames.append(frame)
self.num_IMU_frames = struct.unpack('Q', f.read(8))[0]
def export_depth_images(self, output_path, image_size=None, frame_skip=1):
if not os.path.exists(output_path):
os.makedirs(output_path)
print('exporting', len(self.frames), frame_skip, ' depth frames to', output_path)
for f in range(0, len(self.frames), frame_skip):
depth_data = self.frames[f].decompress_depth(self.depth_compression_type)
depth = np.fromstring(depth_data, dtype=np.uint16).reshape(self.depth_height, self.depth_width)
if image_size is not None:
depth = cv2.resize(depth, (image_size[0], image_size[1]), interpolation=cv2.INTER_NEAREST)
filepath = os.path.join(output_path, f"frame-{f:06d}.depth.{int(image_size[0])}.png")
else:
filepath = os.path.join(output_path, f"frame-{f:06d}.depth.png")
with open(filepath, 'wb') as f: # write 16-bit
writer = png.Writer(width=depth.shape[1], height=depth.shape[0], bitdepth=16)
depth = depth.reshape(-1, depth.shape[1]).tolist()
writer.write(f, depth)
def export_color_images(self, output_path, image_size=None, frame_skip=1):
if not os.path.exists(output_path):
os.makedirs(output_path)
print('exporting', len(self.frames), frame_skip, 'color frames to', output_path)
for f in range(0, len(self.frames), frame_skip):
color = self.frames[f].decompress_color(self.color_compression_type)
if image_size is not None:
resized = Image.fromarray(color).resize((image_size[0], image_size[1]), resample=Image.BILINEAR)
filepath = os.path.join(output_path, f"frame-{f:06d}.color.{int(image_size[0])}.png")
resized.save(filepath)
else:
filepath = os.path.join(output_path, f"frame-{f:06d}.color")
self.frames[f].dump_color_to_file(self.color_compression_type, filepath)
def save_mat_to_file(self, matrix, filename):
with open(filename, 'w') as f:
for line in matrix:
np.savetxt(f, line[np.newaxis], fmt='%f')
def export_poses(self, output_path, frame_skip=1):
if not os.path.exists(output_path):
os.makedirs(output_path)
print('exporting', len(self.frames), frame_skip, 'camera poses to', output_path)
for f in range(0, len(self.frames), frame_skip):
self.save_mat_to_file(self.frames[f].camera_to_world, os.path.join(output_path, f"frame-{f:06d}.pose.txt"))
def export_intrinsics(self, output_path, scan_name):
default_intrinsics_path = os.path.join(output_path, 'intrinsic')
if not os.path.exists(default_intrinsics_path):
os.makedirs(default_intrinsics_path)
print('exporting camera intrinsics to', default_intrinsics_path)
self.save_mat_to_file(self.intrinsic_color, os.path.join(default_intrinsics_path, 'intrinsic_color.txt'))
self.save_mat_to_file(self.extrinsic_color, os.path.join(default_intrinsics_path, 'extrinsic_color.txt'))
self.save_mat_to_file(self.intrinsic_depth, os.path.join(default_intrinsics_path, 'intrinsic_depth.txt'))
self.save_mat_to_file(self.extrinsic_depth, os.path.join(default_intrinsics_path, 'extrinsic_depth.txt'))
================================================
FILE: data_scripts/scannet_wrangling_scripts/download_scannet.py
================================================
#!/usr/bin/env python
# Downloads ScanNet public data release
# Run with ./download-scannet.py (or python download-scannet.py on Windows)
# -*- coding: utf-8 -*-
import argparse
import os
import urllib.request
import tempfile
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
BASE_URL = 'http://kaldir.vc.in.tum.de/scannet/'
TOS_URL = BASE_URL + 'ScanNet_TOS.pdf'
FILETYPES = ['.aggregation.json', '.sens', '.txt', '_vh_clean.ply', '_vh_clean_2.0.010000.segs.json', '_vh_clean_2.ply', '_vh_clean.segs.json', '_vh_clean.aggregation.json', '_vh_clean_2.labels.ply', '_2d-instance.zip', '_2d-instance-filt.zip', '_2d-label.zip', '_2d-label-filt.zip']
FILETYPES_TEST = ['.sens', '.txt', '_vh_clean.ply', '_vh_clean_2.ply']
PREPROCESSED_FRAMES_FILE = ['scannet_frames_25k.zip', '5.6GB']
TEST_FRAMES_FILE = ['scannet_frames_test.zip', '610MB']
LABEL_MAP_FILES = ['scannetv2-labels.combined.tsv', 'scannet-labels.combined.tsv']
DATA_EFFICIENT_FILES = ['limited-reconstruction-scenes.zip', 'limited-annotation-points.zip', 'limited-bboxes.zip', '1.7MB']
GRIT_FILES = ['ScanNet-GRIT.zip']
RELEASES = ['v2/scans', 'v1/scans']
RELEASES_TASKS = ['v2/tasks', 'v1/tasks']
RELEASES_NAMES = ['v2', 'v1']
RELEASE = RELEASES[0]
RELEASE_TASKS = RELEASES_TASKS[0]
RELEASE_NAME = RELEASES_NAMES[0]
LABEL_MAP_FILE = LABEL_MAP_FILES[0]
RELEASE_SIZE = '1.2TB'
V1_IDX = 1
def get_release_scans(release_file):
scan_lines = urllib.request.urlopen(release_file)
scans = []
for scan_line in scan_lines:
scan_id = scan_line.decode('utf8').rstrip('\n')
scans.append(scan_id)
return scans
def download_release(release_scans, out_dir, file_types, use_v1_sens):
if len(release_scans) == 0:
return
print('Downloading ScanNet ' + RELEASE_NAME + ' release to ' + out_dir + '...')
for scan_id in release_scans:
scan_out_dir = os.path.join(out_dir, scan_id)
download_scan(scan_id, scan_out_dir, file_types, use_v1_sens)
print('Downloaded ScanNet ' + RELEASE_NAME + ' release.')
def download_file(url, out_file):
out_dir = os.path.dirname(out_file)
if not os.path.isdir(out_dir):
os.makedirs(out_dir)
if not os.path.isfile(out_file):
print('\t' + url + ' > ' + out_file)
fh, out_file_tmp = tempfile.mkstemp(dir=out_dir)
f = os.fdopen(fh, 'w')
f.close()
urllib.request.urlretrieve(url, out_file_tmp)
os.rename(out_file_tmp, out_file)
else:
print('WARNING: skipping download of existing file ' + out_file)
def download_scan(scan_id, out_dir, file_types, use_v1_sens):
print('Downloading ScanNet ' + RELEASE_NAME + ' scan ' + scan_id + ' ...')
if not os.path.isdir(out_dir):
os.makedirs(out_dir)
for ft in file_types:
v1_sens = use_v1_sens and ft == '.sens'
url = BASE_URL + RELEASE + '/' + scan_id + '/' + scan_id + ft if not v1_sens else BASE_URL + RELEASES[V1_IDX] + '/' + scan_id + '/' + scan_id + ft
out_file = out_dir + '/' + scan_id + ft
download_file(url, out_file)
print('Downloaded scan ' + scan_id)
def download_task_data(out_dir):
print('Downloading ScanNet v1 task data...')
files = [
LABEL_MAP_FILES[V1_IDX], 'obj_classification/data.zip',
'obj_classification/trained_models.zip', 'voxel_labeling/data.zip',
'voxel_labeling/trained_models.zip'
]
for file in files:
url = BASE_URL + RELEASES_TASKS[V1_IDX] + '/' + file
localpath = os.path.join(out_dir, file)
localdir = os.path.dirname(localpath)
if not os.path.isdir(localdir):
os.makedirs(localdir)
download_file(url, localpath)
print('Downloaded task data.')
def download_tfrecords(in_dir, out_dir):
print('Downloading tf records (302 GB)...')
if not os.path.exists(out_dir):
os.makedirs(out_dir)
split_to_num_shards = {'train': 100, 'val': 25, 'test': 10}
for folder_name in ['hires_tfrecords', 'lores_tfrecords']:
folder_dir = '%s/%s' % (in_dir, folder_name)
save_dir = '%s/%s' % (out_dir, folder_name)
if not os.path.exists(save_dir):
os.makedirs(save_dir)
for split, num_shards in split_to_num_shards.items():
for i in range(num_shards):
file_name = '%s-%05d-of-%05d.tfrecords' % (split, i, num_shards)
url = '%s/%s' % (folder_dir, file_name)
localpath = '%s/%s/%s' % (out_dir, folder_name, file_name)
download_file(url, localpath)
def download_label_map(out_dir):
print('Downloading ScanNet ' + RELEASE_NAME + ' label mapping file...')
files = [ LABEL_MAP_FILE ]
for file in files:
url = BASE_URL + RELEASE_TASKS + '/' + file
localpath = os.path.join(out_dir, file)
localdir = os.path.dirname(localpath)
if not os.path.isdir(localdir):
os.makedirs(localdir)
download_file(url, localpath)
print('Downloaded ScanNet ' + RELEASE_NAME + ' label mapping file.')
def main():
parser = argparse.ArgumentParser(description='Downloads ScanNet public data release.')
parser.add_argument('-o', '--out_dir', required=True, help='directory in which to download')
parser.add_argument('--task_data', action='store_true', help='download task data (v1)')
parser.add_argument('--label_map', action='store_true', help='download label map file')
parser.add_argument('--v1', action='store_true', help='download ScanNet v1 instead of v2')
parser.add_argument('--id', help='specific scan id to download')
parser.add_argument('--preprocessed_frames', action='store_true', help='download preprocessed subset of ScanNet frames (' + PREPROCESSED_FRAMES_FILE[1] + ')')
parser.add_argument('--test_frames_2d', action='store_true', help='download 2D test frames (' + TEST_FRAMES_FILE[1] + '; also included with whole dataset download)')
parser.add_argument('--data_efficient', action='store_true', help='download data efficient task files; also included with whole dataset download)')
parser.add_argument('--tf_semantic', action='store_true', help='download google tensorflow records for 3D segmentation / detection')
parser.add_argument('--grit', action='store_true', help='download ScanNet files for General Robust Image Task')
parser.add_argument('--type', help='specific file type to download (.aggregation.json, .sens, .txt, _vh_clean.ply, _vh_clean_2.0.010000.segs.json, _vh_clean_2.ply, _vh_clean.segs.json, _vh_clean.aggregation.json, _vh_clean_2.labels.ply, _2d-instance.zip, _2d-instance-filt.zip, _2d-label.zip, _2d-label-filt.zip)')
args = parser.parse_args()
print('By pressing any key to continue you confirm that you have agreed to the ScanNet terms of use as described at:')
print(TOS_URL)
print('***')
print('Press any key to continue, or CTRL-C to exit.')
key = input('')
if args.v1:
global RELEASE
global RELEASE_TASKS
global RELEASE_NAME
global LABEL_MAP_FILE
RELEASE = RELEASES[V1_IDX]
RELEASE_TASKS = RELEASES_TASKS[V1_IDX]
RELEASE_NAME = RELEASES_NAMES[V1_IDX]
LABEL_MAP_FILE = LABEL_MAP_FILES[V1_IDX]
assert((not args.tf_semantic) and (not args.grit)), "Task files specified invalid for v1"
release_file = BASE_URL + RELEASE + '.txt'
release_scans = get_release_scans(release_file)
file_types = FILETYPES;
release_test_file = BASE_URL + RELEASE + '_test.txt'
release_test_scans = get_release_scans(release_test_file)
file_types_test = FILETYPES_TEST;
out_dir_scans = os.path.join(args.out_dir, 'scans')
out_dir_test_scans = os.path.join(args.out_dir, 'scans_test')
out_dir_tasks = os.path.join(args.out_dir, 'tasks')
if args.type: # download file type
file_type = args.type
if file_type not in FILETYPES:
print('ERROR: Invalid file type: ' + file_type)
return
file_types = [file_type]
if file_type in FILETYPES_TEST:
file_types_test = [file_type]
else:
file_types_test = []
if args.task_data: # download task data
download_task_data(out_dir_tasks)
elif args.label_map: # download label map file
download_label_map(args.out_dir)
elif args.preprocessed_frames: # download preprocessed scannet_frames_25k.zip file
if args.v1:
print('ERROR: Preprocessed frames only available for ScanNet v2')
print('You are downloading the preprocessed subset of frames ' + PREPROCESSED_FRAMES_FILE[0] + ' which requires ' + PREPROCESSED_FRAMES_FILE[1] + ' of space.')
download_file(os.path.join(BASE_URL, RELEASE_TASKS, PREPROCESSED_FRAMES_FILE[0]), os.path.join(out_dir_tasks, PREPROCESSED_FRAMES_FILE[0]))
elif args.test_frames_2d: # download test scannet_frames_test.zip file
if args.v1:
print('ERROR: 2D test frames only available for ScanNet v2')
print('You are downloading the 2D test set ' + TEST_FRAMES_FILE[0] + ' which requires ' + TEST_FRAMES_FILE[1] + ' of space.')
download_file(os.path.join(BASE_URL, RELEASE_TASKS, TEST_FRAMES_FILE[0]), os.path.join(out_dir_tasks, TEST_FRAMES_FILE[0]))
elif args.data_efficient: # download data efficient task files
print('You are downloading the data efficient task files' + ' which requires ' + DATA_EFFICIENT_FILES[-1] + ' of space.')
for k in range(len(DATA_EFFICIENT_FILES)-1):
download_file(os.path.join(BASE_URL, RELEASE_TASKS, DATA_EFFICIENT_FILES[k]), os.path.join(out_dir_tasks, DATA_EFFICIENT_FILES[k]))
elif args.tf_semantic: # download google tf records
download_tfrecords(os.path.join(BASE_URL, RELEASE_TASKS, 'tf3d'), os.path.join(out_dir_tasks, 'tf3d'))
elif args.grit: # download GRIT file
download_file(os.path.join(BASE_URL, RELEASE_TASKS, GRIT_FILES[0]), os.path.join(out_dir_tasks, GRIT_FILES[0]))
elif args.id: # download single scan
scan_id = args.id
is_test_scan = scan_id in release_test_scans
if scan_id not in release_scans and (not is_test_scan or args.v1):
print('ERROR: Invalid scan id: ' + scan_id)
else:
out_dir = os.path.join(out_dir_scans, scan_id) if not is_test_scan else os.path.join(out_dir_test_scans, scan_id)
scan_file_types = file_types if not is_test_scan else file_types_test
use_v1_sens = not is_test_scan
if not is_test_scan and not args.v1 and '.sens' in scan_file_types:
print('Note: ScanNet v2 uses the same .sens files as ScanNet v1: Press \'n\' to exclude downloading .sens files for each scan')
key = input('')
if key.strip().lower() == 'n':
scan_file_types.remove('.sens')
download_scan(scan_id, out_dir, scan_file_types, use_v1_sens)
else: # download entire release
if len(file_types) == len(FILETYPES):
print('WARNING: You are downloading the entire ScanNet ' + RELEASE_NAME + ' release which requires ' + RELEASE_SIZE + ' of space.')
else:
print('WARNING: You are downloading all ScanNet ' + RELEASE_NAME + ' scans of type ' + file_types[0])
print('Note that existing scan directories will be skipped. Delete partially downloaded directories to re-download.')
print('***')
print('Press any key to continue, or CTRL-C to exit.')
key = input('')
if not args.v1 and '.sens' in file_types:
print('Note: ScanNet v2 uses the same .sens files as ScanNet v1: Press \'n\' to exclude downloading .sens files for each scan')
key = input('')
if key.strip().lower() == 'n':
file_types.remove('.sens')
download_release(release_scans, out_dir_scans, file_types, use_v1_sens=True)
if not args.v1:
download_label_map(args.out_dir)
download_release(release_test_scans, out_dir_test_scans, file_types_test, use_v1_sens=False)
download_file(os.path.join(BASE_URL, RELEASE_TASKS, TEST_FRAMES_FILE[0]), os.path.join(out_dir_tasks, TEST_FRAMES_FILE[0]))
for k in range(len(DATA_EFFICIENT_FILES)-1):
download_file(os.path.join(BASE_URL, RELEASE_TASKS, DATA_EFFICIENT_FILES[k]), os.path.join(out_dir_tasks, DATA_EFFICIENT_FILES[k]))
if __name__ == "__main__": main()
================================================
FILE: data_scripts/scannet_wrangling_scripts/env.yml
================================================
name: scannet_extraction
dependencies:
- python=3.9.7
- numpy
- imageio
- pillow
- tqdm
- pip
- pip:
- opencv-python
- pypng
================================================
FILE: data_scripts/scannet_wrangling_scripts/reader.py
================================================
import argparse
from concurrent.futures import process
import os, sys
from tqdm import tqdm
from multiprocessing.pool import Pool
from functools import partial
from multiprocessing import Manager
from SensorData import SensorData
# params
parser = argparse.ArgumentParser()
# data paths
parser.add_argument('--scans_folder', required=True, help='dataset root')
parser.add_argument('--scan_list_file', required=False, default=None, help='scan list file')
parser.add_argument('--single_debug_scan_id', required=False, default=None, help='single scan to debug')
parser.add_argument('--output_path', required=True, help='path to output folder')
parser.add_argument('--export_depth_images', dest='export_depth_images', action='store_true')
parser.add_argument('--export_color_images', dest='export_color_images', action='store_true')
parser.add_argument('--export_poses', dest='export_poses', action='store_true')
parser.add_argument('--export_intrinsics', dest='export_intrinsics', action='store_true')
parser.add_argument('--num_workers', type=int, default=1)
parser.add_argument('--rgb_resize', nargs='+', type=int, default=None, help='width height')
parser.add_argument('--depth_resize', nargs='+', type=int, default=None, help='width height')
parser.set_defaults(export_depth_images=False, export_color_images=False, export_poses=False, export_intrinsics=False)
opt = parser.parse_args()
print(opt)
def process_scan(opt, scan_job, count=None, progress=None):
filename = scan_job[0]
output_path = scan_job[1]
scan_name = scan_job[2]
if not os.path.exists(output_path):
os.makedirs(output_path)
# load the data
sys.stdout.write('loading %s...' % opt.scans_folder)
sd = SensorData(filename)
sys.stdout.write('loaded!\n')
if opt.export_depth_images:
sd.export_depth_images(os.path.join(output_path, 'sensor_data'), image_size=opt.depth_resize)
if opt.export_color_images:
sd.export_color_images(os.path.join(output_path, 'sensor_data'), image_size=opt.rgb_resize)
if opt.export_poses:
sd.export_poses(os.path.join(output_path, 'sensor_data'))
if opt.export_intrinsics:
sd.export_intrinsics(output_path, scan_name)
if progress is not None:
progress.value += 1
print(f"Completed scan {filename}, {progress.value} of total {count}.")
def main():
if opt.single_debug_scan_id is not None:
scans = [opt.single_debug_scan_id]
else:
f = open(opt.scan_list_file, "r")
scans = f.readlines()
scans = [scan.strip() for scan in scans]
input_files = [os.path.join(opt.scans_folder, f"{scan}/{scan}.sens") for
scan in scans]
output_dirs = [os.path.join(opt.output_path, scan) for
scan in scans]
scan_jobs = list(zip(input_files, output_dirs, scans))
if opt.num_workers == 1:
for scan_job in tqdm(scan_jobs):
process_scan(opt, scan_job)
else:
pool = Pool(opt.num_workers)
manager = Manager()
count = len(scan_jobs)
progress = manager.Value('i', 0)
pool.map(
partial(
process_scan,
opt,
count=count,
progress=progress
),
scan_jobs,
)
if __name__ == '__main__':
main()
================================================
FILE: data_scripts/scannet_wrangling_scripts/splits/scannetv2_test.txt
================================================
scene0707_00
scene0708_00
scene0709_00
scene0710_00
scene0711_00
scene0712_00
scene0713_00
scene0714_00
scene0715_00
scene0716_00
scene0717_00
scene0718_00
scene0719_00
scene0720_00
scene0721_00
scene0722_00
scene0723_00
scene0724_00
scene0725_00
scene0726_00
scene0727_00
scene0728_00
scene0729_00
scene0730_00
scene0731_00
scene0732_00
scene0733_00
scene0734_00
scene0735_00
scene0736_00
scene0737_00
scene0738_00
scene0739_00
scene0740_00
scene0741_00
scene0742_00
scene0743_00
scene0744_00
scene0745_00
scene0746_00
scene0747_00
scene0748_00
scene0749_00
scene0750_00
scene0751_00
scene0752_00
scene0753_00
scene0754_00
scene0755_00
scene0756_00
scene0757_00
scene0758_00
scene0759_00
scene0760_00
scene0761_00
scene0762_00
scene0763_00
scene0764_00
scene0765_00
scene0766_00
scene0767_00
scene0768_00
scene0769_00
scene0770_00
scene0771_00
scene0772_00
scene0773_00
scene0774_00
scene0775_00
scene0776_00
scene0777_00
scene0778_00
scene0779_00
scene0780_00
scene0781_00
scene0782_00
scene0783_00
scene0784_00
scene0785_00
scene0786_00
scene0787_00
scene0788_00
scene0789_00
scene0790_00
scene0791_00
scene0792_00
scene0793_00
scene0794_00
scene0795_00
scene0796_00
scene0797_00
scene0798_00
scene0799_00
scene0800_00
scene0801_00
scene0802_00
scene0803_00
scene0804_00
scene0805_00
scene0806_00
================================================
FILE: data_scripts/scannet_wrangling_scripts/splits/scannetv2_train.txt
================================================
scene0191_00
scene0191_01
scene0191_02
scene0119_00
scene0230_00
scene0528_00
scene0528_01
scene0705_00
scene0705_01
scene0705_02
scene0415_00
scene0415_01
scene0415_02
scene0007_00
scene0141_00
scene0141_01
scene0141_02
scene0515_00
scene0515_01
scene0515_02
scene0447_00
scene0447_01
scene0447_02
scene0531_00
scene0503_00
scene0285_00
scene0069_00
scene0584_00
scene0584_01
scene0584_02
scene0581_00
scene0581_01
scene0581_02
scene0620_00
scene0620_01
scene0263_00
scene0263_01
scene0481_00
scene0481_01
scene0020_00
scene0020_01
scene0291_00
scene0291_01
scene0291_02
scene0469_00
scene0469_01
scene0469_02
scene0659_00
scene0659_01
scene0024_00
scene0024_01
scene0024_02
scene0564_00
scene0117_00
scene0027_00
scene0027_01
scene0027_02
scene0028_00
scene0330_00
scene0418_00
scene0418_01
scene0418_02
scene0233_00
scene0233_01
scene0673_00
scene0673_01
scene0673_02
scene0673_03
scene0673_04
scene0673_05
scene0585_00
scene0585_01
scene0362_00
scene0362_01
scene0362_02
scene0362_03
scene0035_00
scene0035_01
scene0358_00
scene0358_01
scene0358_02
scene0037_00
scene0194_00
scene0321_00
scene0293_00
scene0293_01
scene0623_00
scene0623_01
scene0592_00
scene0592_01
scene0569_00
scene0569_01
scene0413_00
scene0313_00
scene0313_01
scene0313_02
scene0480_00
scene0480_01
scene0401_00
scene0517_00
scene0517_01
scene0517_02
scene0032_00
scene0032_01
scene0613_00
scene0613_01
scene0613_02
scene0306_00
scene0306_01
scene0052_00
scene0052_01
scene0052_02
scene0053_00
scene0444_00
scene0444_01
scene0055_00
scene0055_01
scene0055_02
scene0560_00
scene0589_00
scene0589_01
scene0589_02
scene0610_00
scene0610_01
scene0610_02
scene0364_00
scene0364_01
scene0383_00
scene0383_01
scene0383_02
scene0006_00
scene0006_01
scene0006_02
scene0275_00
scene0451_00
scene0451_01
scene0451_02
scene0451_03
scene0451_04
scene0451_05
scene0135_00
scene0065_00
scene0065_01
scene0065_02
scene0104_00
scene0674_00
scene0674_01
scene0448_00
scene0448_01
scene0448_02
scene0502_00
scene0502_01
scene0502_02
scene0440_00
scene0440_01
scene0440_02
scene0071_00
scene0072_00
scene0072_01
scene0072_02
scene0509_00
scene0509_01
scene0509_02
scene0649_00
scene0649_01
scene0602_00
scene0694_00
scene0694_01
scene0101_00
scene0101_01
scene0101_02
scene0101_03
scene0101_04
scene0101_05
scene0218_00
scene0218_01
scene0579_00
scene0579_01
scene0579_02
scene0039_00
scene0039_01
scene0493_00
scene0493_01
scene0242_00
scene0242_01
scene0242_02
scene0083_00
scene0083_01
scene0127_00
scene0127_01
scene0662_00
scene0662_01
scene0662_02
scene0018_00
scene0087_00
scene0087_01
scene0087_02
scene0332_00
scene0332_01
scene0332_02
scene0628_00
scene0628_01
scene0628_02
scene0134_00
scene0134_01
scene0134_02
scene0238_00
scene0238_01
scene0092_00
scene0092_01
scene0092_02
scene0092_03
scene0092_04
scene0022_00
scene0022_01
scene0467_00
scene0392_00
scene0392_01
scene0392_02
scene0424_00
scene0424_01
scene0424_02
scene0646_00
scene0646_01
scene0646_02
scene0098_00
scene0098_01
scene0044_00
scene0044_01
scene0044_02
scene0510_00
scene0510_01
scene0510_02
scene0571_00
scene0571_01
scene0166_00
scene0166_01
scene0166_02
scene0563_00
scene0172_00
scene0172_01
scene0388_00
scene0388_01
scene0215_00
scene0215_01
scene0252_00
scene0287_00
scene0668_00
scene0572_00
scene0572_01
scene0572_02
scene0026_00
scene0224_00
scene0113_00
scene0113_01
scene0551_00
scene0381_00
scene0381_01
scene0381_02
scene0371_00
scene0371_01
scene0460_00
scene0118_00
scene0118_01
scene0118_02
scene0417_00
scene0008_00
scene0634_00
scene0521_00
scene0123_00
scene0123_01
scene0123_02
scene0045_00
scene0045_01
scene0511_00
scene0511_01
scene0114_00
scene0114_01
scene0114_02
scene0070_00
scene0029_00
scene0029_01
scene0029_02
scene0129_00
scene0103_00
scene0103_01
scene0002_00
scene0002_01
scene0132_00
scene0132_01
scene0132_02
scene0124_00
scene0124_01
scene0143_00
scene0143_01
scene0143_02
scene0604_00
scene0604_01
scene0604_02
scene0507_00
scene0105_00
scene0105_01
scene0105_02
scene0428_00
scene0428_01
scene0311_00
scene0140_00
scene0140_01
scene0182_00
scene0182_01
scene0182_02
scene0142_00
scene0142_01
scene0399_00
scene0399_01
scene0012_00
scene0012_01
scene0012_02
scene0060_00
scene0060_01
scene0370_00
scene0370_01
scene0370_02
scene0310_00
scene0310_01
scene0310_02
scene0661_00
scene0650_00
scene0152_00
scene0152_01
scene0152_02
scene0158_00
scene0158_01
scene0158_02
scene0482_00
scene0482_01
scene0600_00
scene0600_01
scene0600_02
scene0393_00
scene0393_01
scene0393_02
scene0562_00
scene0174_00
scene0174_01
scene0157_00
scene0157_01
scene0161_00
scene0161_01
scene0161_02
scene0159_00
scene0254_00
scene0254_01
scene0115_00
scene0115_01
scene0115_02
scene0162_00
scene0163_00
scene0163_01
scene0523_00
scene0523_01
scene0523_02
scene0459_00
scene0459_01
scene0175_00
scene0085_00
scene0085_01
scene0279_00
scene0279_01
scene0279_02
scene0201_00
scene0201_01
scene0201_02
scene0283_00
scene0456_00
scene0456_01
scene0429_00
scene0043_00
scene0043_01
scene0419_00
scene0419_01
scene0419_02
scene0368_00
scene0368_01
scene0348_00
scene0348_01
scene0348_02
scene0442_00
scene0178_00
scene0380_00
scene0380_01
scene0380_02
scene0165_00
scene0165_01
scene0165_02
scene0181_00
scene0181_01
scene0181_02
scene0181_03
scene0333_00
scene0614_00
scene0614_01
scene0614_02
scene0404_00
scene0404_01
scene0404_02
scene0185_00
scene0126_00
scene0126_01
scene0126_02
scene0519_00
scene0236_00
scene0236_01
scene0189_00
scene0075_00
scene0267_00
scene0192_00
scene0192_01
scene0192_02
scene0281_00
scene0420_00
scene0420_01
scene0420_02
scene0195_00
scene0195_01
scene0195_02
scene0597_00
scene0597_01
scene0597_02
scene0041_00
scene0041_01
scene0111_00
scene0111_01
scene0111_02
scene0666_00
scene0666_01
scene0666_02
scene0200_00
scene0200_01
scene0200_02
scene0536_00
scene0536_01
scene0536_02
scene0390_00
scene0280_00
scene0280_01
scene0280_02
scene0344_00
scene0344_01
scene0205_00
scene0205_01
scene0205_02
scene0484_00
scene0484_01
scene0009_00
scene0009_01
scene0009_02
scene0302_00
scene0302_01
scene0209_00
scene0209_01
scene0209_02
scene0210_00
scene0210_01
scene0395_00
scene0395_01
scene0395_02
scene0683_00
scene0601_00
scene0601_01
scene0214_00
scene0214_01
scene0214_02
scene0477_00
scene0477_01
scene0439_00
scene0439_01
scene0468_00
scene0468_01
scene0468_02
scene0546_00
scene0466_00
scene0466_01
scene0220_00
scene0220_01
scene0220_02
scene0122_00
scene0122_01
scene0130_00
scene0110_00
scene0110_01
scene0110_02
scene0327_00
scene0156_00
scene0266_00
scene0266_01
scene0001_00
scene0001_01
scene0228_00
scene0199_00
scene0219_00
scene0464_00
scene0232_00
scene0232_01
scene0232_02
scene0299_00
scene0299_01
scene0530_00
scene0363_00
scene0453_00
scene0453_01
scene0570_00
scene0570_01
scene0570_02
scene0183_00
scene0239_00
scene0239_01
scene0239_02
scene0373_00
scene0373_01
scene0241_00
scene0241_01
scene0241_02
scene0188_00
scene0622_00
scene0622_01
scene0244_00
scene0244_01
scene0691_00
scene0691_01
scene0206_00
scene0206_01
scene0206_02
scene0247_00
scene0247_01
scene0061_00
scene0061_01
scene0082_00
scene0250_00
scene0250_01
scene0250_02
scene0501_00
scene0501_01
scene0501_02
scene0320_00
scene0320_01
scene0320_02
scene0320_03
scene0631_00
scene0631_01
scene0631_02
scene0255_00
scene0255_01
scene0255_02
scene0047_00
scene0265_00
scene0265_01
scene0265_02
scene0004_00
scene0336_00
scene0336_01
scene0058_00
scene0058_01
scene0260_00
scene0260_01
scene0260_02
scene0243_00
scene0603_00
scene0603_01
scene0093_00
scene0093_01
scene0093_02
scene0109_00
scene0109_01
scene0434_00
scene0434_01
scene0434_02
scene0290_00
scene0627_00
scene0627_01
scene0470_00
scene0470_01
scene0137_00
scene0137_01
scene0137_02
scene0270_00
scene0270_01
scene0270_02
scene0271_00
scene0271_01
scene0504_00
scene0274_00
scene0274_01
scene0274_02
scene0036_00
scene0036_01
scene0276_00
scene0276_01
scene0272_00
scene0272_01
scene0499_00
scene0698_00
scene0698_01
scene0051_00
scene0051_01
scene0051_02
scene0051_03
scene0108_00
scene0245_00
scene0369_00
scene0369_01
scene0369_02
scene0284_00
scene0289_00
scene0289_01
scene0286_00
scene0286_01
scene0286_02
scene0286_03
scene0031_00
scene0031_01
scene0031_02
scene0545_00
scene0545_01
scene0545_02
scene0557_00
scene0557_01
scene0557_02
scene0533_00
scene0533_01
scene0116_00
scene0116_01
scene0116_02
scene0611_00
scene0611_01
scene0688_00
scene0294_00
scene0294_01
scene0294_02
scene0295_00
scene0295_01
scene0296_00
scene0296_01
scene0596_00
scene0596_01
scene0596_02
scene0532_00
scene0532_01
scene0637_00
scene0638_00
scene0121_00
scene0121_01
scene0121_02
scene0040_00
scene0040_01
scene0197_00
scene0197_01
scene0197_02
scene0410_00
scene0410_01
scene0305_00
scene0305_01
scene0615_00
scene0615_01
scene0703_00
scene0703_01
scene0555_00
scene0297_00
scene0297_01
scene0297_02
scene0582_00
scene0582_01
scene0582_02
scene0023_00
scene0094_00
scene0013_00
scene0013_01
scene0013_02
scene0136_00
scene0136_01
scene0136_02
scene0407_00
scene0407_01
scene0062_00
scene0062_01
scene0062_02
scene0386_00
scene0318_00
scene0554_00
scene0554_01
scene0497_00
scene0213_00
scene0258_00
scene0323_00
scene0323_01
scene0324_00
scene0324_01
scene0016_00
scene0016_01
scene0016_02
scene0681_00
scene0398_00
scene0398_01
scene0227_00
scene0090_00
scene0066_00
scene0262_00
scene0262_01
scene0155_00
scene0155_01
scene0155_02
scene0352_00
scene0352_01
scene0352_02
scene0038_00
scene0038_01
scene0038_02
scene0335_00
scene0335_01
scene0335_02
scene0261_00
scene0261_01
scene0261_02
scene0261_03
scene0640_00
scene0640_01
scene0640_02
scene0080_00
scene0080_01
scene0080_02
scene0403_00
scene0403_01
scene0282_00
scene0282_01
scene0282_02
scene0682_00
scene0173_00
scene0173_01
scene0173_02
scene0522_00
scene0687_00
scene0345_00
scene0345_01
scene0612_00
scene0612_01
scene0411_00
scene0411_01
scene0411_02
scene0625_00
scene0625_01
scene0211_00
scene0211_01
scene0211_02
scene0211_03
scene0676_00
scene0676_01
scene0179_00
scene0498_00
scene0498_01
scene0498_02
scene0547_00
scene0547_01
scene0547_02
scene0269_00
scene0269_01
scene0269_02
scene0366_00
scene0680_00
scene0680_01
scene0588_00
scene0588_01
scene0588_02
scene0588_03
scene0346_00
scene0346_01
scene0359_00
scene0359_01
scene0014_00
scene0120_00
scene0120_01
scene0212_00
scene0212_01
scene0212_02
scene0176_00
scene0049_00
scene0259_00
scene0259_01
scene0586_00
scene0586_01
scene0586_02
scene0309_00
scene0309_01
scene0125_00
scene0455_00
scene0177_00
scene0177_01
scene0177_02
scene0326_00
scene0372_00
scene0171_00
scene0171_01
scene0374_00
scene0654_00
scene0654_01
scene0445_00
scene0445_01
scene0475_00
scene0475_01
scene0475_02
scene0349_00
scene0349_01
scene0234_00
scene0669_00
scene0669_01
scene0375_00
scene0375_01
scene0375_02
scene0387_00
scene0387_01
scene0387_02
scene0312_00
scene0312_01
scene0312_02
scene0384_00
scene0385_00
scene0385_01
scene0385_02
scene0000_00
scene0000_01
scene0000_02
scene0376_00
scene0376_01
scene0376_02
scene0301_00
scene0301_01
scene0301_02
scene0322_00
scene0542_00
scene0079_00
scene0079_01
scene0099_00
scene0099_01
scene0476_00
scene0476_01
scene0476_02
scene0394_00
scene0394_01
scene0147_00
scene0147_01
scene0067_00
scene0067_01
scene0067_02
scene0397_00
scene0397_01
scene0337_00
scene0337_01
scene0337_02
scene0431_00
scene0223_00
scene0223_01
scene0223_02
scene0010_00
scene0010_01
scene0402_00
scene0268_00
scene0268_01
scene0268_02
scene0679_00
scene0679_01
scene0405_00
scene0128_00
scene0408_00
scene0408_01
scene0190_00
scene0107_00
scene0076_00
scene0167_00
scene0361_00
scene0361_01
scene0361_02
scene0216_00
scene0202_00
scene0303_00
scene0303_01
scene0303_02
scene0446_00
scene0446_01
scene0089_00
scene0089_01
scene0089_02
scene0360_00
scene0150_00
scene0150_01
scene0150_02
scene0421_00
scene0421_01
scene0421_02
scene0454_00
scene0626_00
scene0626_01
scene0626_02
scene0186_00
scene0186_01
scene0538_00
scene0479_00
scene0479_01
scene0479_02
scene0656_00
scene0656_01
scene0656_02
scene0656_03
scene0525_00
scene0525_01
scene0525_02
scene0308_00
scene0396_00
scene0396_01
scene0396_02
scene0624_00
scene0292_00
scene0292_01
scene0632_00
scene0253_00
scene0021_00
scene0325_00
scene0325_01
scene0437_00
scene0437_01
scene0438_00
scene0590_00
scene0590_01
scene0400_00
scene0400_01
scene0541_00
scene0541_01
scene0541_02
scene0677_00
scene0677_01
scene0677_02
scene0443_00
scene0315_00
scene0288_00
scene0288_01
scene0288_02
scene0422_00
scene0672_00
scene0672_01
scene0184_00
scene0449_00
scene0449_01
scene0449_02
scene0048_00
scene0048_01
scene0138_00
scene0452_00
scene0452_01
scene0452_02
scene0667_00
scene0667_01
scene0667_02
scene0463_00
scene0463_01
scene0078_00
scene0078_01
scene0078_02
scene0636_00
scene0457_00
scene0457_01
scene0457_02
scene0465_00
scene0465_01
scene0577_00
scene0151_00
scene0151_01
scene0339_00
scene0573_00
scene0573_01
scene0154_00
scene0096_00
scene0096_01
scene0096_02
scene0235_00
scene0168_00
scene0168_01
scene0168_02
scene0594_00
scene0587_00
scene0587_01
scene0587_02
scene0587_03
scene0229_00
scene0229_01
scene0229_02
scene0512_00
scene0106_00
scene0106_01
scene0106_02
scene0472_00
scene0472_01
scene0472_02
scene0489_00
scene0489_01
scene0489_02
scene0425_00
scene0425_01
scene0641_00
scene0526_00
scene0526_01
scene0317_00
scene0317_01
scene0544_00
scene0017_00
scene0017_01
scene0017_02
scene0042_00
scene0042_01
scene0042_02
scene0576_00
scene0576_01
scene0576_02
scene0347_00
scene0347_01
scene0347_02
scene0436_00
scene0226_00
scene0226_01
scene0485_00
scene0486_00
scene0487_00
scene0487_01
scene0619_00
scene0097_00
scene0367_00
scene0367_01
scene0491_00
scene0492_00
scene0492_01
scene0005_00
scene0005_01
scene0543_00
scene0543_01
scene0543_02
scene0657_00
scene0341_00
scene0341_01
scene0534_00
scene0534_01
scene0319_00
scene0273_00
scene0273_01
scene0225_00
scene0198_00
scene0003_00
scene0003_01
scene0003_02
scene0409_00
scene0409_01
scene0331_00
scene0331_01
scene0505_00
scene0505_01
scene0505_02
scene0505_03
scene0505_04
scene0506_00
scene0057_00
scene0057_01
scene0074_00
scene0074_01
scene0074_02
scene0091_00
scene0112_00
scene0112_01
scene0112_02
scene0240_00
scene0102_00
scene0102_01
scene0513_00
scene0514_00
scene0514_01
scene0537_00
scene0516_00
scene0516_01
scene0495_00
scene0617_00
scene0133_00
scene0520_00
scene0520_01
scene0635_00
scene0635_01
scene0054_00
scene0473_00
scene0473_01
scene0524_00
scene0524_01
scene0379_00
scene0471_00
scene0471_01
scene0471_02
scene0566_00
scene0248_00
scene0248_01
scene0248_02
scene0529_00
scene0529_01
scene0529_02
scene0391_00
scene0264_00
scene0264_01
scene0264_02
scene0675_00
scene0675_01
scene0350_00
scene0350_01
scene0350_02
scene0450_00
scene0068_00
scene0068_01
scene0237_00
scene0237_01
scene0365_00
scene0365_01
scene0365_02
scene0605_00
scene0605_01
scene0539_00
scene0539_01
scene0539_02
scene0540_00
scene0540_01
scene0540_02
scene0170_00
scene0170_01
scene0170_02
scene0433_00
scene0340_00
scene0340_01
scene0340_02
scene0160_00
scene0160_01
scene0160_02
scene0160_03
scene0160_04
scene0059_00
scene0059_01
scene0059_02
scene0056_00
scene0056_01
scene0478_00
scene0478_01
scene0548_00
scene0548_01
scene0548_02
scene0204_00
scene0204_01
scene0204_02
scene0033_00
scene0145_00
scene0483_00
scene0508_00
scene0508_01
scene0508_02
scene0180_00
scene0148_00
scene0556_00
scene0556_01
scene0416_00
scene0416_01
scene0416_02
scene0416_03
scene0416_04
scene0073_00
scene0073_01
scene0073_02
scene0073_03
scene0034_00
scene0034_01
scene0034_02
scene0639_00
scene0561_00
scene0561_01
scene0298_00
scene0692_00
scene0692_01
scene0692_02
scene0692_03
scene0692_04
scene0642_00
scene0642_01
scene0642_02
scene0642_03
scene0630_00
scene0630_01
scene0630_02
scene0630_03
scene0630_04
scene0630_05
scene0630_06
scene0706_00
scene0567_00
scene0567_01
================================================
FILE: data_scripts/scannet_wrangling_scripts/splits/scannetv2_val.txt
================================================
scene0568_00
scene0568_01
scene0568_02
scene0304_00
scene0488_00
scene0488_01
scene0412_00
scene0412_01
scene0217_00
scene0019_00
scene0019_01
scene0414_00
scene0575_00
scene0575_01
scene0575_02
scene0426_00
scene0426_01
scene0426_02
scene0426_03
scene0549_00
scene0549_01
scene0578_00
scene0578_01
scene0578_02
scene0665_00
scene0665_01
scene0050_00
scene0050_01
scene0050_02
scene0257_00
scene0025_00
scene0025_01
scene0025_02
scene0583_00
scene0583_01
scene0583_02
scene0701_00
scene0701_01
scene0701_02
scene0580_00
scene0580_01
scene0565_00
scene0169_00
scene0169_01
scene0655_00
scene0655_01
scene0655_02
scene0063_00
scene0221_00
scene0221_01
scene0591_00
scene0591_01
scene0591_02
scene0678_00
scene0678_01
scene0678_02
scene0462_00
scene0427_00
scene0595_00
scene0193_00
scene0193_01
scene0164_00
scene0164_01
scene0164_02
scene0164_03
scene0598_00
scene0598_01
scene0598_02
scene0599_00
scene0599_01
scene0599_02
scene0328_00
scene0300_00
scene0300_01
scene0354_00
scene0458_00
scene0458_01
scene0423_00
scene0423_01
scene0423_02
scene0307_00
scene0307_01
scene0307_02
scene0606_00
scene0606_01
scene0606_02
scene0432_00
scene0432_01
scene0608_00
scene0608_01
scene0608_02
scene0651_00
scene0651_01
scene0651_02
scene0430_00
scene0430_01
scene0689_00
scene0357_00
scene0357_01
scene0574_00
scene0574_01
scene0574_02
scene0329_00
scene0329_01
scene0329_02
scene0153_00
scene0153_01
scene0616_00
scene0616_01
scene0671_00
scene0671_01
scene0618_00
scene0382_00
scene0382_01
scene0490_00
scene0621_00
scene0607_00
scene0607_01
scene0149_00
scene0695_00
scene0695_01
scene0695_02
scene0695_03
scene0389_00
scene0377_00
scene0377_01
scene0377_02
scene0342_00
scene0139_00
scene0629_00
scene0629_01
scene0629_02
scene0496_00
scene0633_00
scene0633_01
scene0518_00
scene0652_00
scene0406_00
scene0406_01
scene0406_02
scene0144_00
scene0144_01
scene0494_00
scene0278_00
scene0278_01
scene0316_00
scene0609_00
scene0609_01
scene0609_02
scene0609_03
scene0084_00
scene0084_01
scene0084_02
scene0696_00
scene0696_01
scene0696_02
scene0351_00
scene0351_01
scene0643_00
scene0644_00
scene0645_00
scene0645_01
scene0645_02
scene0081_00
scene0081_01
scene0081_02
scene0647_00
scene0647_01
scene0535_00
scene0353_00
scene0353_01
scene0353_02
scene0559_00
scene0559_01
scene0559_02
scene0593_00
scene0593_01
scene0246_00
scene0653_00
scene0653_01
scene0064_00
scene0064_01
scene0356_00
scene0356_01
scene0356_02
scene0030_00
scene0030_01
scene0030_02
scene0222_00
scene0222_01
scene0338_00
scene0338_01
scene0338_02
scene0378_00
scene0378_01
scene0378_02
scene0660_00
scene0553_00
scene0553_01
scene0553_02
scene0527_00
scene0663_00
scene0663_01
scene0663_02
scene0664_00
scene0664_01
scene0664_02
scene0334_00
scene0334_01
scene0334_02
scene0046_00
scene0046_01
scene0046_02
scene0203_00
scene0203_01
scene0203_02
scene0088_00
scene0088_01
scene0088_02
scene0088_03
scene0086_00
scene0086_01
scene0086_02
scene0670_00
scene0670_01
scene0256_00
scene0256_01
scene0256_02
scene0249_00
scene0441_00
scene0658_00
scene0704_00
scene0704_01
scene0187_00
scene0187_01
scene0131_00
scene0131_01
scene0131_02
scene0207_00
scene0207_01
scene0207_02
scene0461_00
scene0011_00
scene0011_01
scene0343_00
scene0251_00
scene0077_00
scene0077_01
scene0684_00
scene0684_01
scene0550_00
scene0686_00
scene0686_01
scene0686_02
scene0208_00
scene0500_00
scene0500_01
scene0552_00
scene0552_01
scene0648_00
scene0648_01
scene0435_00
scene0435_01
scene0435_02
scene0435_03
scene0690_00
scene0690_01
scene0693_00
scene0693_01
scene0693_02
scene0700_00
scene0700_01
scene0700_02
scene0699_00
scene0231_00
scene0231_01
scene0231_02
scene0697_00
scene0697_01
scene0697_02
scene0697_03
scene0474_00
scene0474_01
scene0474_02
scene0474_03
scene0474_04
scene0474_05
scene0355_00
scene0355_01
scene0146_00
scene0146_01
scene0146_02
scene0196_00
scene0702_00
scene0702_01
scene0702_02
scene0314_00
scene0277_00
scene0277_01
scene0277_02
scene0095_00
scene0095_01
scene0015_00
scene0100_00
scene0100_01
scene0100_02
scene0558_00
scene0558_01
scene0558_02
scene0685_00
scene0685_01
scene0685_02
================================================
FILE: data_splits/7Scenes/dvmvs_split/dvmvs_test_split.txt
================================================
redkitchen/seq-01
redkitchen/seq-07
chess/seq-01
chess/seq-02
heads/seq-02
fire/seq-01
fire/seq-02
office/seq-01
office/seq-03
pumpkin/seq-03
pumpkin/seq-06
stairs/seq-02
stairs/seq-06
================================================
FILE: data_splits/7Scenes/dvmvs_split/test_eight_view_deepvmvs.txt
================================================
stairs/seq-06 000018 000000 000002 000010 000007 000015 000012 000005
stairs/seq-06 000029 000000 000018 000025 000007 000010 000017 000015
stairs/seq-06 000037 000018 000029 000000 000010 000032 000025 000020
stairs/seq-06 000043 000037 000018 000029 000000 000013 000039 000030
stairs/seq-06 000051 000043 000018 000029 000037 000000 000039 000040
stairs/seq-06 000058 000051 000018 000029 000037 000043 000000 000027
stairs/seq-06 000066 000058 000018 000029 000037 000043 000051 000000
stairs/seq-06 000074 000043 000066 000058 000051 000037 000029 000018
stairs/seq-06 000079 000051 000074 000066 000058 000043 000037 000029
stairs/seq-06 000082 000051 000079 000074 000066 000058 000043 000037
stairs/seq-06 000085 000058 000082 000079 000074 000043 000066 000051
stairs/seq-06 000091 000079 000085 000082 000037 000043 000051 000074
stairs/seq-06 000103 000091 000082 000085 000079 000037 000043 000029
stairs/seq-06 000110 000018 000103 000091 000037 000085 000082 000000
stairs/seq-06 000117 000091 000110 000103 000000 000018 000085 000029
stairs/seq-06 000124 000103 000117 000110 000000 000018 000091 000029
stairs/seq-06 000133 000117 000124 000000 000018 000110 000103 000029
stairs/seq-06 000142 000117 000133 000124 000000 000018 000110 000029
stairs/seq-06 000154 000124 000000 000133 000142 000018 000117 000029
stairs/seq-06 000167 000018 000000 000142 000133 000124 000154 000117
stairs/seq-06 000177 000000 000018 000154 000124 000133 000142 000029
stairs/seq-06 000184 000154 000018 000142 000000 000167 000133 000124
stairs/seq-06 000196 000142 000000 000177 000154 000184 000167 000133
stairs/seq-06 000211 000154 000177 000184 000142 000133 000167 000124
stairs/seq-06 000220 000154 000184 000196 000177 000211 000142 000167
stairs/seq-06 000241 000177 000154 000167 000184 000196 000211 000142
stairs/seq-06 000248 000241 000184 000167 000177 000117 000154 000037
stairs/seq-06 000257 000241 000177 000037 000248 000167 000043 000029
stairs/seq-06 000264 000241 000167 000248 000257 000177 000037 000043
stairs/seq-06 000271 000257 000241 000264 000248 000177 000085 000082
stairs/seq-06 000276 000264 000257 000271 000248 000241 000082 000085
stairs/seq-06 000294 000271 000276 000264 000257 000248 000082 000079
stairs/seq-06 000298 000294 000257 000264 000271 000276 000248 000082
stairs/seq-06 000301 000298 000294 000276 000271 000264 000257 000079
stairs/seq-06 000305 000301 000271 000276 000294 000298 000264 000257
stairs/seq-06 000311 000305 000271 000276 000294 000298 000301 000264
stairs/seq-06 000319 000298 000305 000311 000301 000294 000276 000271
stairs/seq-06 000328 000294 000305 000311 000301 000298 000319 000276
stairs/seq-06 000338 000298 000311 000319 000305 000301 000328 000294
stairs/seq-06 000346 000328 000338 000319 000301 000305 000311 000298
stairs/seq-06 000356 000338 000346 000328 000319 000311 000305 000301
stairs/seq-06 000370 000356 000338 000346 000328 000319 000311 000305
stairs/seq-06 000378 000370 000346 000356 000338 000328 000319 000311
stairs/seq-06 000384 000378 000356 000370 000346 000338 000328 000319
stairs/seq-06 000396 000384 000370 000378 000356 000346 000338 000328
stairs/seq-06 000412 000396 000378 000384 000370 000356 000346 000338
stairs/seq-06 000424 000412 000384 000396 000378 000370 000346 000356
stairs/seq-06 000434 000424 000396 000412 000384 000378 000370 000356
stairs/seq-06 000446 000434 000412 000424 000396 000384 000378 000370
stairs/seq-06 000456 000446 000424 000434 000412 000396 000384 000378
stairs/seq-06 000464 000456 000434 000446 000424 000412 000396 000384
stairs/seq-06 000480 000464 000446 000456 000434 000424 000396 000384
stairs/seq-06 000491 000480 000456 000464 000446 000434 000424 000396
stairs/seq-06 000497 000434 000464 000480 000456 000446 000424 000491
stairs/seq-02 000037 000000 000011 000032 000025 000020 000027 000017
stairs/seq-02 000048 000000 000037 000033 000029 000043 000042 000028
stairs/seq-02 000060 000037 000000 000048 000028 000033 000045 000057
stairs/seq-02 000079 000060 000037 000048 000000 000052 000051 000072
stairs/seq-02 000089 000079 000037 000048 000060 000000 000061 000074
stairs/seq-02 000099 000089 000037 000048 000060 000079 000000 000070
stairs/seq-02 000114 000099 000037 000048 000060 000079 000089 000000
stairs/seq-02 000137 000079 000114 000099 000089 000060 000048 000037
stairs/seq-02 000142 000089 000137 000114 000099 000079 000060 000048
stairs/seq-02 000151 000089 000142 000137 000114 000099 000079 000048
stairs/seq-02 000169 000099 000151 000142 000137 000114 000089 000079
stairs/seq-02 000179 000099 000169 000151 000142 000137 000114 000089
stairs/seq-02 000186 000137 000179 000169 000151 000142 000099 000114
stairs/seq-02 000193 000137 000186 000179 000169 000151 000142 000099
stairs/seq-02 000201 000151 000179 000186 000193 000169 000142 000137
stairs/seq-02 000227 000151 000179 000193 000186 000201 000169 000142
stairs/seq-02 000234 000169 000193 000201 000227 000186 000179 000151
stairs/seq-02 000243 000186 000201 000227 000193 000234 000179 000169
stairs/seq-02 000258 000193 000227 000234 000201 000243 000186 000179
stairs/seq-02 000266 000201 000234 000243 000193 000258 000186 000227
stairs/seq-02 000273 000227 000243 000258 000234 000266 000186 000193
stairs/seq-02 000280 000273 000201 000266 000227 000258 000234 000243
stairs/seq-02 000288 000280 000201 000273 000193 000266 000227 000258
stairs/seq-02 000309 000288 000201 000280 000273 000193 000266 000186
stairs/seq-02 000318 000273 000280 000288 000309 000193 000186 000201
stairs/seq-02 000328 000186 000318 000309 000288 000280 000193 000179
stairs/seq-02 000337 000179 000328 000318 000309 000288 000186 000280
stairs/seq-02 000343 000169 000337 000328 000318 000309 000179 000186
stairs/seq-02 000351 000169 000151 000337 000328 000179 000343 000142
stairs/seq-02 000364 000351 000343 000337 000169 000328 000179 000142
stairs/seq-02 000378 000364 000343 000351 000337 000169 000137 000328
stairs/seq-02 000387 000378 000337 000343 000351 000364 000328 000137
stairs/seq-02 000398 000387 000364 000378 000351 000343 000337 000114
stairs/seq-02 000408 000378 000351 000364 000387 000398 000343 000114
stairs/seq-02 000417 000351 000387 000398 000408 000378 000364 000343
stairs/seq-02 000427 000378 000398 000408 000417 000387 000364 000351
stairs/seq-02 000442 000387 000408 000417 000398 000427 000378 000364
stairs/seq-02 000448 000387 000417 000427 000408 000398 000442 000378
stairs/seq-02 000452 000408 000427 000448 000442 000417 000398 000387
stairs/seq-02 000459 000408 000442 000448 000452 000417 000398 000427
stairs/seq-02 000470 000459 000448 000452 000442 000427 000417 000408
stairs/seq-02 000479 000470 000452 000459 000448 000442 000417 000427
stairs/seq-02 000487 000479 000459 000470 000452 000448 000442 000417
stairs/seq-02 000492 000487 000470 000479 000459 000452 000448 000442
stairs/seq-02 000497 000492 000479 000487 000470 000459 000452 000448
pumpkin/seq-06 000024 000000 000016 000008 000011 000021 000013 000019
pumpkin/seq-06 000040 000000 000024 000027 000012 000026 000025 000014
pumpkin/seq-06 000052 000024 000040 000000 000025 000044 000051 000048
pumpkin/seq-06 000064 000052 000024 000040 000000 000042 000037 000054
pumpkin/seq-06 000075 000064 000024 000040 000052 000000 000063 000072
pumpkin/seq-06 000086 000075 000024 000040 000052 000064 000000 000079
pumpkin/seq-06 000100 000086 000024 000040 000052 000064 000075 000000
pumpkin/seq-06 000113 000064 000100 000086 000075 000052 000040 000024
pumpkin/seq-06 000129 000075 000113 000100 000086 000064 000052 000040
pumpkin/seq-06 000151 000075 000129 000113 000100 000086 000064 000052
pumpkin/seq-06 000166 000086 000151 000129 000113 000100 000075 000064
pumpkin/seq-06 000181 000086 000166 000151 000129 000113 000100 000075
pumpkin/seq-06 000194 000100 000181 000166 000151 000129 000113 000086
pumpkin/seq-06 000229 000151 000166 000181 000194 000113 000129 000100
pumpkin/seq-06 000240 000113 000229 000181 000166 000151 000100 000194
pumpkin/seq-06 000249 000113 000240 000229 000100 000151 000166 000129
pumpkin/seq-06 000259 000100 000113 000240 000249 000129 000229 000151
pumpkin/seq-06 000267 000100 000113 000249 000259 000240 000129 000086
pumpkin/seq-06 000284 000100 000267 000259 000249 000113 000129 000086
pumpkin/seq-06 000291 000249 000259 000267 000100 000113 000166 000129
pumpkin/seq-06 000294 000113 000151 000284 000129 000291 000259 000166
pumpkin/seq-06 000317 000113 000294 000291 000284 000129 000151 000100
pumpkin/seq-06 000334 000100 000129 000294 000291 000113 000317 000284
pumpkin/seq-06 000345 000317 000334 000294 000291 000100 000086 000113
pumpkin/seq-06 000354 000334 000345 000317 000294 000086 000291 000100
pumpkin/seq-06 000364 000086 000294 000317 000334 000345 000354 000291
pumpkin/seq-06 000374 000364 000345 000354 000334 000317 000294 000086
pumpkin/seq-06 000385 000374 000354 000364 000345 000334 000317 000294
pumpkin/seq-06 000395 000385 000345 000354 000364 000374 000334 000317
pumpkin/seq-06 000405 000395 000385 000345 000354 000364 000374 000334
pumpkin/seq-06 000416 000395 000405 000374 000354 000385 000364 000345
pumpkin/seq-06 000425 000405 000374 000416 000395 000385 000364 000354
pumpkin/seq-06 000433 000405 000425 000416 000395 000385 000374 000364
pumpkin/seq-06 000443 000433 000416 000425 000405 000395 000385 000374
pumpkin/seq-06 000452 000443 000425 000433 000416 000405 000395 000385
pumpkin/seq-06 000459 000452 000433 000443 000425 000416 000405 000395
pumpkin/seq-06 000466 000459 000443 000452 000433 000425 000416 000405
pumpkin/seq-06 000475 000466 000452 000459 000443 000433 000425 000416
pumpkin/seq-06 000483 000475 000459 000466 000452 000443 000433 000425
pumpkin/seq-06 000496 000483 000466 000475 000459 000452 000443 000433
pumpkin/seq-06 000501 000496 000475 000483 000466 000459 000452 000443
pumpkin/seq-06 000507 000501 000483 000496 000475 000466 000459 000452
pumpkin/seq-06 000512 000507 000496 000501 000483 000475 000466 000459
pumpkin/seq-06 000516 000512 000501 000507 000496 000466 000459 000475
pumpkin/seq-06 000520 000516 000501 000512 000507 000496 000466 000459
pumpkin/seq-06 000526 000520 000501 000516 000512 000507 000496 000459
pumpkin/seq-06 000532 000501 000512 000520 000516 000507 000526 000459
pumpkin/seq-06 000538 000512 000520 000526 000516 000532 000507 000501
pumpkin/seq-06 000544 000512 000526 000532 000538 000520 000516 000507
pumpkin/seq-06 000552 000532 000544 000538 000526 000520 000516 000512
pumpkin/seq-06 000561 000544 000552 000538 000532 000526 000520 000516
pumpkin/seq-06 000568 000561 000532 000538 000544 000552 000526 000520
pumpkin/seq-06 000575 000561 000568 000552 000544 000538 000532 000526
pumpkin/seq-06 000584 000568 000575 000561 000544 000538 000552 000532
pumpkin/seq-06 000595 000575 000584 000561 000568 000552 000544 000538
pumpkin/seq-06 000616 000552 000575 000584 000568 000561 000595 000544
pumpkin/seq-06 000628 000561 000584 000595 000575 000568 000616 000552
pumpkin/seq-06 000640 000568 000595 000616 000584 000575 000628 000561
pumpkin/seq-06 000652 000628 000616 000640 000595 000584 000575 000568
pumpkin/seq-06 000668 000652 000628 000640 000616 000595 000584 000575
pumpkin/seq-06 000683 000668 000640 000652 000628 000616 000595 000584
pumpkin/seq-06 000697 000683 000652 000668 000640 000628 000616 000595
pumpkin/seq-06 000711 000697 000668 000683 000652 000640 000628 000616
pumpkin/seq-06 000725 000711 000683 000697 000668 000652 000640 000628
pumpkin/seq-06 000745 000725 000697 000711 000683 000668 000652 000640
pumpkin/seq-06 000755 000745 000711 000725 000697 000683 000668 000652
pumpkin/seq-06 000765 000755 000725 000745 000711 000697 000683 000668
pumpkin/seq-06 000772 000697 000745 000755 000765 000711 000683 000725
pumpkin/seq-06 000778 000765 000772 000755 000697 000745 000683 000711
pumpkin/seq-06 000784 000755 000765 000772 000778 000683 000697 000668
pumpkin/seq-06 000793 000755 000765 000778 000772 000784 000683 000652
pumpkin/seq-06 000804 000793 000765 000784 000778 000772 000652 000755
pumpkin/seq-06 000813 000772 000784 000793 000804 000778 000765 000652
pumpkin/seq-06 000822 000772 000793 000804 000813 000784 000778 000765
pumpkin/seq-06 000830 000822 000804 000813 000784 000793 000778 000772
pumpkin/seq-06 000838 000822 000813 000830 000793 000804 000784 000778
pumpkin/seq-06 000847 000838 000793 000804 000813 000822 000830 000784
pumpkin/seq-06 000857 000847 000804 000813 000822 000830 000838 000793
pumpkin/seq-06 000865 000838 000857 000847 000822 000830 000813 000804
pumpkin/seq-06 000873 000822 000847 000857 000838 000865 000830 000813
pumpkin/seq-06 000880 000830 000857 000865 000873 000847 000838 000822
pumpkin/seq-06 000890 000838 000865 000873 000880 000857 000847 000830
pumpkin/seq-06 000901 000847 000873 000880 000890 000865 000857 000838
pumpkin/seq-06 000911 000865 000880 000890 000873 000901 000857 000847
pumpkin/seq-06 000920 000873 000890 000901 000880 000911 000865 000857
pumpkin/seq-06 000933 000880 000901 000911 000890 000920 000873 000865
pumpkin/seq-06 000943 000933 000911 000920 000901 000890 000880 000873
pumpkin/seq-06 000953 000943 000920 000933 000911 000901 000890 000880
pumpkin/seq-06 000963 000953 000933 000943 000920 000911 000901 000890
pumpkin/seq-06 000976 000963 000943 000953 000933 000920 000911 000901
pumpkin/seq-06 000990 000976 000953 000963 000943 000933 000920 000911
pumpkin/seq-06 000997 000990 000963 000976 000953 000943 000933 000920
chess/seq-01 000028 000000 000019 000013 000011 000001 000010 000009
chess/seq-01 000040 000000 000028 000010 000023 000011 000036 000039
chess/seq-01 000050 000028 000040 000000 000034 000019 000039 000026
chess/seq-01 000058 000050 000028 000040 000000 000043 000055 000044
chess/seq-01 000068 000058 000028 000040 000050 000000 000046 000049
chess/seq-01 000078 000068 000028 000040 000050 000058 000000 000069
chess/seq-01 000087 000078 000028 000040 000050 000058 000068 000000
chess/seq-01 000095 000058 000087 000078 000068 000050 000040 000028
chess/seq-01 000104 000068 000095 000087 000078 000058 000050 000040
chess/seq-01 000112 000068 000104 000095 000087 000078 000058 000050
chess/seq-01 000121 000078 000112 000104 000095 000087 000068 000058
chess/seq-01 000130 000078 000121 000112 000104 000095 000087 000068
chess/seq-01 000139 000087 000130 000121 000112 000104 000095 000078
chess/seq-01 000147 000104 000121 000130 000139 000112 000095 000087
chess/seq-01 000158 000112 000130 000139 000147 000121 000104 000095
chess/seq-01 000176 000112 000139 000147 000158 000130 000121 000104
chess/seq-01 000187 000121 000147 000158 000176 000139 000130 000112
chess/seq-01 000202 000139 000158 000176 000147 000187 000130 000121
chess/seq-01 000211 000147 000176 000187 000158 000202 000139 000130
chess/seq-01 000221 000147 000187 000202 000176 000211 000158 000139
chess/seq-01 000233 000158 000202 000211 000187 000221 000176 000147
chess/seq-01 000247 000233 000211 000221 000202 000187 000176 000158
chess/seq-01 000258 000247 000221 000233 000211 000202 000187 000176
chess/seq-01 000271 000202 000233 000247 000221 000211 000258 000187
chess/seq-01 000279 000211 000247 000258 000233 000221 000271 000202
chess/seq-01 000287 000271 000279 000258 000247 000233 000221 000211
chess/seq-01 000295 000279 000287 000271 000258 000247 000233 000221
chess/seq-01 000305 000295 000279 000287 000271 000258 000247 000233
chess/seq-01 000312 000305 000287 000295 000279 000271 000258 000247
chess/seq-01 000319 000312 000295 000305 000287 000279 000271 000258
chess/seq-01 000327 000319 000305 000312 000295 000287 000279 000271
chess/seq-01 000335 000327 000312 000319 000305 000295 000287 000279
chess/seq-01 000341 000335 000319 000327 000312 000305 000295 000287
chess/seq-01 000348 000341 000327 000335 000319 000312 000305 000295
chess/seq-01 000353 000348 000335 000341 000327 000319 000312 000305
chess/seq-01 000358 000353 000341 000348 000335 000327 000319 000312
chess/seq-01 000362 000358 000348 000353 000341 000335 000327 000319
chess/seq-01 000367 000362 000353 000358 000348 000341 000335 000327
chess/seq-01 000372 000367 000358 000362 000353 000348 000341 000335
chess/seq-01 000379 000372 000362 000367 000358 000353 000348 000341
chess/seq-01 000386 000379 000367 000372 000362 000358 000353 000348
chess/seq-01 000393 000386 000372 000379 000367 000362 000358 000353
chess/seq-01 000402 000393 000379 000386 000372 000367 000362 000358
chess/seq-01 000413 000402 000386 000393 000379 000372 000367 000362
chess/seq-01 000416 000413 000393 000402 000386 000379 000372 000367
chess/seq-01 000441 000416 000372 000413 000393 000386 000379 000402
chess/seq-01 000450 000416 000413 000441 000386 000393 000372 000402
chess/seq-01 000456 000450 000367 000441 000416 000386 000393 000372
chess/seq-01 000463 000456 000367 000450 000441 000372 000386 000362
chess/seq-01 000468 000367 000450 000456 000463 000362 000372 000358
chess/seq-01 000473 000362 000468 000463 000456 000367 000358 000353
chess/seq-01 000480 000348 000473 000468 000463 000358 000353 000362
chess/seq-01 000487 000480 000468 000473 000348 000341 000463 000353
chess/seq-01 000492 000487 000468 000480 000473 000341 000348 000353
chess/seq-01 000498 000492 000487 000480 000473 000341 000335 000348
chess/seq-01 000503 000498 000492 000487 000480 000341 000335 000473
chess/seq-01 000508 000503 000492 000498 000487 000480 000335 000341
chess/seq-01 000514 000508 000492 000498 000503 000487 000335 000327
chess/seq-01 000520 000487 000514 000508 000503 000498 000492 000319
chess/seq-01 000527 000492 000520 000514 000508 000503 000498 000327
chess/seq-01 000533 000503 000514 000520 000527 000508 000498 000492
chess/seq-01 000540 000503 000520 000527 000533 000514 000508 000498
chess/seq-01 000546 000508 000527 000533 000520 000540 000514 000503
chess/seq-01 000552 000514 000533 000540 000527 000520 000546 000508
chess/seq-01 000559 000520 000540 000546 000552 000527 000514 000533
chess/seq-01 000566 000552 000546 000559 000520 000514 000527 000540
chess/seq-01 000573 000546 000552 000559 000566 000520 000503 000514
chess/seq-01 000580 000573 000546 000566 000559 000552 000498 000503
chess/seq-01 000586 000552 000566 000573 000580 000559 000546 000498
chess/seq-01 000592 000552 000573 000580 000586 000566 000559 000546
chess/seq-01 000598 000559 000580 000586 000566 000573 000592 000552
chess/seq-01 000607 000592 000598 000586 000566 000573 000580 000559
chess/seq-01 000615 000580 000592 000598 000586 000607 000573 000566
chess/seq-01 000621 000586 000592 000607 000598 000615 000580 000573
chess/seq-01 000629 000615 000621 000607 000598 000592 000586 000580
chess/seq-01 000635 000629 000607 000621 000615 000598 000592 000586
chess/seq-01 000642 000621 000635 000629 000615 000607 000598 000592
chess/seq-01 000648 000642 000629 000635 000621 000615 000607 000598
chess/seq-01 000654 000648 000635 000642 000629 000621 000615 000607
chess/seq-01 000660 000654 000642 000648 000635 000629 000621 000615
chess/seq-01 000666 000660 000648 000654 000642 000635 000629 000621
chess/seq-01 000677 000666 000654 000660 000648 000642 000635 000629
chess/seq-01 000685 000677 000660 000666 000654 000648 000642 000635
chess/seq-01 000696 000685 000666 000677 000660 000654 000648 000642
chess/seq-01 000705 000696 000677 000685 000666 000660 000654 000648
chess/seq-01 000720 000705 000685 000696 000677 000666 000660 000654
chess/seq-01 000732 000720 000696 000705 000685 000677 000666 000660
chess/seq-01 000740 000732 000705 000720 000696 000685 000677 000666
chess/seq-01 000748 000740 000720 000732 000705 000696 000685 000677
chess/seq-01 000757 000748 000732 000740 000720 000705 000696 000685
chess/seq-01 000770 000748 000757 000740 000732 000720 000705 000696
chess/seq-01 000793 000770 000748 000757 000740 000732 000720 000705
chess/seq-01 000811 000793 000757 000770 000748 000740 000732 000720
chess/seq-01 000825 000811 000770 000793 000757 000748 000740 000732
chess/seq-01 000831 000825 000740 000811 000770 000757 000748 000793
chess/seq-01 000842 000825 000831 000811 000757 000748 000740 000793
chess/seq-01 000853 000842 000740 000831 000825 000748 000757 000811
chess/seq-01 000869 000853 000748 000842 000831 000757 000740 000732
chess/seq-01 000885 000869 000831 000853 000842 000748 000740 000732
chess/seq-01 000899 000885 000842 000869 000853 000732 000740 000748
chess/seq-01 000910 000853 000869 000885 000899 000732 000842 000740
chess/seq-01 000924 000853 000910 000899 000885 000869 000732 000720
chess/seq-01 000934 000869 000899 000910 000924 000885 000732 000720
chess/seq-01 000944 000934 000732 000924 000910 000899 000885 000869
chess/seq-01 000952 000910 000899 000934 000924 000885 000944 000720
chess/seq-01 000963 000952 000944 000934 000924 000899 000677 000910
chess/seq-01 000978 000963 000952 000944 000934 000677 000666 000685
chess/seq-01 000986 000963 000944 000952 000978 000677 000666 000660
chess/seq-01 000996 000952 000986 000978 000963 000660 000677 000666
heads/seq-02 000028 000000 000010 000018 000009 000007 000006 000025
heads/seq-02 000043 000000 000028 000035 000023 000016 000017 000014
heads/seq-02 000053 000028 000000 000043 000030 000029 000037 000047
heads/seq-02 000062 000053 000028 000043 000000 000037 000051 000052
heads/seq-02 000070 000062 000028 000043 000053 000000 000055 000063
heads/seq-02 000082 000070 000028 000043 000053 000062 000000 000072
heads/seq-02 000098 000082 000028 000043 000053 000062 000070 000000
heads/seq-02 000118 000062 000098 000082 000070 000053 000043 000028
heads/seq-02 000126 000070 000062 000098 000082 000118 000053 000043
heads/seq-02 000133 000070 000062 000098 000082 000126 000053 000118
heads/seq-02 000137 000062 000133 000126 000070 000082 000098 000118
heads/seq-02 000141 000062 000137 000133 000126 000070 000118 000082
heads/seq-02 000145 000133 000126 000137 000141 000062 000118 000070
heads/seq-02 000152 000137 000126 000141 000133 000145 000118 000062
heads/seq-02 000161 000137 000126 000145 000141 000152 000133 000118
heads/seq-02 000168 000133 000145 000152 000161 000141 000137 000126
heads/seq-02 000174 000137 000152 000161 000168 000145 000141 000133
heads/seq-02 000181 000174 000161 000168 000141 000145 000152 000137
heads/seq-02 000187 000145 000137 000174 000168 000181 000141 000161
heads/seq-02 000192 000187 000174 000181 000137 000168 000133 000141
heads/seq-02 000198 000174 000192 000187 000181 000133 000137 000126
heads/seq-02 000202 000126 000198 000192 000187 000181 000133 000137
heads/seq-02 000207 000187 000192 000198 000202 000126 000181 000118
heads/seq-02 000212 000192 000198 000202 000207 000118 000126 000098
heads/seq-02 000216 000212 000207 000202 000198 000098 000118 000082
heads/seq-02 000220 000212 000216 000207 000098 000202 000118 000082
heads/seq-02 000226 000216 000220 000212 000082 000098 000207 000118
heads/seq-02 000230 000220 000226 000216 000082 000098 000212 000118
heads/seq-02 000236 000230 000226 000220 000098 000216 000082 000212
heads/seq-02 000244 000236 000230 000226 000216 000220 000098 000082
heads/seq-02 000252 000244 000226 000230 000236 000220 000216 000082
heads/seq-02 000257 000252 000226 000230 000236 000244 000220 000082
heads/seq-02 000262 000236 000252 000230 000257 000244 000226 000070
heads/seq-02 000273 000244 000262 000257 000252 000070 000236 000082
heads/seq-02 000280 000252 000273 000262 000257 000082 000244 000236
heads/seq-02 000288 000244 000262 000273 000280 000257 000252 000226
heads/seq-02 000301 000288 000262 000280 000273 000257 000252 000226
heads/seq-02 000314 000288 000301 000280 000273 000262 000257 000252
heads/seq-02 000324 000262 000288 000301 000280 000314 000273 000257
heads/seq-02 000333 000324 000301 000314 000288 000280 000273 000262
heads/seq-02 000343 000333 000314 000324 000301 000288 000280 000273
heads/seq-02 000355 000343 000324 000333 000314 000301 000288 000280
heads/seq-02 000365 000343 000333 000355 000324 000314 000301 000288
heads/seq-02 000377 000343 000365 000355 000333 000324 000314 000301
heads/seq-02 000386 000365 000355 000377 000324 000343 000333 000314
heads/seq-02 000397 000386 000365 000377 000355 000343 000333 000324
heads/seq-02 000404 000397 000377 000386 000365 000355 000343 000333
heads/seq-02 000411 000404 000386 000397 000377 000365 000355 000343
heads/seq-02 000419 000411 000397 000404 000386 000377 000365 000355
heads/seq-02 000442 000411 000419 000404 000397 000386 000377 000365
heads/seq-02 000450 000442 000411 000419 000404 000397 000386 000377
heads/seq-02 000457 000450 000419 000442 000411 000404 000397 000386
heads/seq-02 000463 000457 000397 000450 000419 000411 000404 000442
heads/seq-02 000470 000397 000404 000457 000463 000411 000386 000450
heads/seq-02 000478 000470 000386 000463 000457 000397 000404 000377
heads/seq-02 000489 000404 000386 000470 000463 000397 000478 000377
heads/seq-02 000501 000397 000377 000478 000470 000489 000386 000463
heads/seq-02 000508 000470 000478 000489 000501 000386 000377 000397
heads/seq-02 000515 000478 000508 000501 000489 000377 000386 000470
heads/seq-02 000523 000478 000501 000508 000515 000489 000377 000365
heads/seq-02 000537 000478 000501 000515 000508 000523 000489 000377
heads/seq-02 000544 000537 000515 000523 000489 000508 000501 000478
heads/seq-02 000552 000537 000544 000523 000508 000515 000501 000489
heads/seq-02 000566 000544 000508 000552 000537 000515 000523 000501
heads/seq-02 000575 000566 000544 000552 000537 000508 000515 000523
heads/seq-02 000584 000575 000552 000566 000544 000537 000508 000515
heads/seq-02 000593 000537 000552 000575 000566 000544 000584 000508
heads/seq-02 000605 000584 000593 000575 000566 000552 000544 000537
heads/seq-02 000616 000605 000584 000593 000575 000552 000566 000544
heads/seq-02 000628 000566 000593 000605 000575 000584 000616 000552
heads/seq-02 000636 000575 000605 000616 000593 000628 000584 000566
heads/seq-02 000648 000636 000616 000628 000605 000593 000584 000575
heads/seq-02 000658 000636 000648 000628 000605 000616 000593 000584
heads/seq-02 000667 000658 000636 000648 000628 000616 000605 000593
heads/seq-02 000674 000667 000628 000636 000648 000658 000616 000605
heads/seq-02 000681 000674 000667 000658 000648 000636 000628 000616
heads/seq-02 000689 000667 000681 000674 000658 000648 000636 000628
heads/seq-02 000696 000681 000689 000674 000667 000658 000648 000636
heads/seq-02 000713 000689 000696 000681 000674 000667 000658 000648
heads/seq-02 000721 000674 000689 000696 000681 000713 000667 000658
heads/seq-02 000728 000674 000696 000713 000689 000681 000721 000667
heads/seq-02 000734 000674 000728 000721 000681 000689 000713 000667
heads/seq-02 000740 000728 000734 000721 000674 000667 000681 000689
heads/seq-02 000746 000667 000674 000734 000728 000740 000721 000658
heads/seq-02 000754 000728 000734 000740 000746 000667 000674 000658
heads/seq-02 000764 000667 000734 000746 000740 000754 000728 000658
heads/seq-02 000774 000728 000746 000754 000764 000740 000734 000628
heads/seq-02 000783 000740 000734 000764 000754 000746 000774 000566
heads/seq-02 000796 000754 000764 000774 000783 000746 000740 000566
heads/seq-02 000808 000746 000796 000783 000774 000764 000754 000537
heads/seq-02 000816 000754 000808 000796 000783 000774 000764 000544
heads/seq-02 000827 000764 000816 000808 000796 000783 000774 000552
heads/seq-02 000839 000774 000827 000816 000808 000796 000783 000566
heads/seq-02 000851 000783 000816 000827 000839 000808 000796 000774
heads/seq-02 000864 000808 000827 000839 000816 000851 000796 000783
heads/seq-02 000878 000808 000839 000851 000827 000816 000864 000796
heads/seq-02 000890 000864 000878 000851 000839 000827 000816 000808
heads/seq-02 000899 000890 000864 000878 000851 000839 000827 000816
heads/seq-02 000909 000899 000878 000890 000864 000827 000839 000851
heads/seq-02 000924 000899 000909 000890 000827 000878 000864 000839
heads/seq-02 000934 000924 000899 000909 000878 000890 000827 000816
heads/seq-02 000942 000934 000899 000924 000909 000878 000890 000827
heads/seq-02 000951 000942 000924 000934 000890 000909 000899 000878
heads/seq-02 000963 000951 000934 000942 000909 000924 000899 000890
heads/seq-02 000981 000909 000942 000951 000963 000934 000924 000899
heads/seq-02 000991 000924 000951 000963 000942 000981 000934 000909
heads/seq-02 000997 000991 000963 000981 000951 000942 000934 000924
fire/seq-02 000018 000000 000010 000011 000002 000006 000004 000017
fire/seq-02 000027 000000 000018 000023 000011 000026 000016 000006
fire/seq-02 000039 000018 000027 000000 000016 000022 000019 000037
fire/seq-02 000055 000039 000018 000027 000000 000054 000052 000025
fire/seq-02 000066 000055 000018 000027 000039 000000 000059 000042
fire/seq-02 000075 000066 000018 000027 000039 000055 000000 000047
fire/seq-02 000084 000075 000018 000027 000039 000055 000066 000000
fire/seq-02 000094 000066 000084 000075 000018 000055 000000 000027
fire/seq-02 000106 000066 000094 000084 000075 000000 000018 000055
fire/seq-02 000122 000066 000106 000094 000084 000075 000000 000018
fire/seq-02 000137 000075 000122 000106 000094 000084 000000 000066
fire/seq-02 000146 000075 000137 000122 000106 000094 000084 000000
fire/seq-02 000155 000084 000146 000137 000106 000094 000075 000066
fire/seq-02 000163 000066 000155 000146 000084 000075 000027 000055
fire/seq-02 000169 000055 000155 000066 000163 000039 000027 000146
fire/seq-02 000175 000169 000163 000155 000055 000066 000039 000075
fire/seq-02 000182 000175 000163 000169 000066 000055 000155 000075
fire/seq-02 000189 000182 000163 000169 000175 000055 000066 000027
fire/seq-02 000196 000189 000175 000182 000169 000055 000039 000163
fire/seq-02 000204 000196 000175 000182 000189 000169 000039 000055
fire/seq-02 000211 000204 000175 000182 000189 000196 000169 000039
fire/seq-02 000218 000211 000204 000175 000182 000189 000196 000169
fire/seq-02 000225 000218 000211 000182 000189 000196 000204 000175
fire/seq-02 000233 000218 000211 000189 000196 000204 000225 000182
fire/seq-02 000242 000225 000218 000196 000204 000211 000233 000189
fire/seq-02 000253 000233 000225 000211 000218 000242 000204 000196
fire/seq-02 000267 000242 000233 000253 000218 000225 000211 000204
fire/seq-02 000279 000233 000242 000225 000253 000218 000267 000211
fire/seq-02 000287 000233 000225 000218 000242 000253 000267 000279
fire/seq-02 000295 000225 000233 000287 000218 000242 000279 000211
fire/seq-02 000302 000295 000287 000225 000218 000233 000211 000279
fire/seq-02 000310 000295 000302 000287 000218 000211 000225 000279
fire/seq-02 000317 000211 000287 000302 000295 000310 000204 000218
fire/seq-02 000324 000287 000302 000310 000317 000295 000211 000204
fire/seq-02 000332 000295 000310 000317 000324 000302 000196 000189
fire/seq-02 000346 000302 000310 000324 000317 000332 000189 000295
fire/seq-02 000357 000332 000346 000324 000317 000310 000302 000182
fire/seq-02 000368 000357 000332 000346 000324 000317 000310 000182
fire/seq-02 000378 000368 000357 000346 000324 000332 000317 000310
fire/seq-02 000384 000378 000332 000346 000357 000368 000324 000317
fire/seq-02 000390 000384 000332 000346 000357 000368 000378 000324
fire/seq-02 000396 000346 000378 000384 000390 000368 000357 000332
fire/seq-02 000402 000368 000384 000390 000396 000378 000357 000346
fire/seq-02 000408 000378 000390 000396 000402 000384 000368 000357
fire/seq-02 000416 000384 000396 000402 000408 000390 000378 000368
fire/seq-02 000423 000390 000402 000408 000416 000396 000384 000378
fire/seq-02 000429 000390 000408 000416 000423 000402 000396 000384
fire/seq-02 000436 000402 000416 000423 000408 000429 000396 000390
fire/seq-02 000446 000402 000423 000429 000416 000436 000408 000396
fire/seq-02 000455 000446 000429 000436 000423 000416 000408 000402
fire/seq-02 000465 000416 000436 000446 000429 000423 000455 000408
fire/seq-02 000475 000455 000465 000446 000423 000436 000429 000416
fire/seq-02 000483 000465 000455 000475 000429 000446 000436 000423
fire/seq-02 000492 000483 000465 000475 000455 000446 000436 000429
fire/seq-02 000501 000492 000475 000483 000465 000455 000446 000436
fire/seq-02 000510 000501 000483 000492 000475 000465 000446 000455
fire/seq-02 000520 000501 000510 000492 000483 000475 000465 000446
fire/seq-02 000533 000520 000492 000510 000501 000483 000475 000446
fire/seq-02 000549 000533 000510 000520 000492 000501 000483 000475
fire/seq-02 000568 000549 000520 000533 000510 000492 000501 000483
fire/seq-02 000596 000549 000568 000533 000510 000520 000501 000492
fire/seq-02 000616 000510 000549 000568 000533 000520 000596 000501
fire/seq-02 000629 000616 000568 000596 000549 000533 000520 000510
fire/seq-02 000639 000533 000596 000616 000568 000629 000549 000520
fire/seq-02 000651 000549 000616 000629 000596 000639 000568 000533
fire/seq-02 000661 000639 000629 000651 000616 000596 000568 000549
fire/seq-02 000669 000596 000639 000651 000629 000616 000661 000568
fire/seq-02 000677 000669 000651 000661 000639 000629 000616 000596
fire/seq-02 000691 000661 000677 000669 000651 000639 000629 000616
fire/seq-02 000710 000677 000691 000669 000661 000651 000639 000629
fire/seq-02 000722 000710 000677 000691 000669 000661 000651 000639
fire/seq-02 000734 000722 000691 000710 000677 000669 000661 000651
fire/seq-02 000749 000734 000710 000722 000691 000677 000669 000661
fire/seq-02 000766 000749 000722 000734 000710 000691 000677 000669
fire/seq-02 000788 000766 000734 000749 000722 000710 000691 000677
fire/seq-02 000798 000788 000749 000766 000734 000722 000710 000691
fire/seq-02 000805 000788 000766 000798 000749 000734 000722 000710
fire/seq-02 000811 000798 000805 000788 000749 000766 000734 000722
fire/seq-02 000817 000811 000798 000805 000766 000788 000749 000734
fire/seq-02 000823 000766 000817 000811 000805 000798 000788 000651
fire/seq-02 000829 000651 000823 000817 000811 000805 000798 000661
fire/seq-02 000835 000805 000817 000823 000811 000829 000651 000639
fire/seq-02 000841 000817 000835 000829 000823 000811 000639 000651
fire/seq-02 000848 000841 000829 000817 000835 000823 000629 000639
fire/seq-02 000853 000829 000848 000841 000835 000510 000520 000533
fire/seq-02 000858 000835 000853 000848 000841 000520 000533 000829
fire/seq-02 000863 000841 000858 000853 000848 000533 000835 000549
fire/seq-02 000869 000841 000863 000858 000853 000848 000549 000568
fire/seq-02 000876 000841 000869 000863 000858 000853 000848 000568
fire/seq-02 000885 000853 000863 000869 000876 000858 000848 000841
fire/seq-02 000895 000853 000869 000876 000885 000863 000858 000848
fire/seq-02 000906 000863 000876 000885 000869 000895 000858 000853
fire/seq-02 000917 000863 000885 000895 000876 000906 000869 000858
fire/seq-02 000923 000869 000895 000906 000885 000876 000917 000863
fire/seq-02 000928 000923 000906 000917 000895 000885 000876 000869
fire/seq-02 000933 000928 000917 000923 000906 000895 000885 000876
fire/seq-02 000939 000933 000923 000928 000917 000906 000895 000885
fire/seq-02 000945 000939 000928 000933 000923 000917 000906 000895
fire/seq-02 000952 000945 000933 000939 000928 000923 000917 000906
fire/seq-02 000964 000952 000939 000945 000933 000928 000923 000917
fire/seq-02 000968 000964 000945 000952 000939 000933 000928 000923
fire/seq-02 000972 000968 000952 000964 000945 000939 000933 000928
fire/seq-02 000979 000972 000964 000968 000952 000945 000939 000933
fire/seq-02 000985 000979 000968 000972 000964 000952 000945 000939
fire/seq-02 000991 000985 000972 000979 000968 000964 000952 000945
fire/seq-02 000998 000991 000979 000985 000972 000968 000964 000952
office/seq-03 000015 000000 000006 000008 000013 000003 000009 000007
office/seq-03 000024 000000 000015 000001 000021 000020 000012 000014
office/seq-03 000032 000015 000000 000024 000001 000020 000005 000009
office/seq-03 000038 000032 000015 000024 000000 000020 000022 000011
office/seq-03 000048 000038 000015 000024 000032 000000 000037 000025
office/seq-03 000056 000048 000015 000024 000032 000038 000000 000025
office/seq-03 000063 000056 000015 000024 000032 000038 000048 000000
office/seq-03 000073 000038 000063 000056 000048 000032 000024 000015
office/seq-03 000083 000048 000073 000063 000056 000038 000032 000024
office/seq-03 000092 000048 000083 000073 000063 000056 000038 000032
office/seq-03 000105 000056 000092 000083 000073 000063 000048 000038
office/seq-03 000116 000056 000105 000092 000083 000073 000063 000048
office/seq-03 000125 000063 000116 000105 000092 000083 000073 000056
office/seq-03 000134 000083 000105 000116 000125 000092 000073 000063
office/seq-03 000143 000105 000116 000125 000134 000083 000092 000073
office/seq-03 000152 000116 000125 000134 000143 000083 000092 000105
office/seq-03 000158 000083 000152 000143 000134 000125 000073 000092
office/seq-03 000164 000083 000158 000152 000143 000134 000125 000073
office/seq-03 000170 000134 000164 000158 000152 000143 000083 000073
office/seq-03 000176 000134 000170 000164 000158 000152 000143 000083
office/seq-03 000182 000143 000158 000170 000164 000176 000152 000083
office/seq-03 000187 000158 000170 000176 000164 000182 000152 000143
office/seq-03 000191 000182 000176 000187 000164 000170 000158 000152
office/seq-03 000195 000191 000182 000187 000164 000176 000170 000158
office/seq-03 000200 000170 000182 000191 000187 000195 000176 000164
office/seq-03 000206 000191 000200 000195 000187 000182 000176 000170
office/seq-03 000211 000200 000206 000195 000182 000187 000191 000176
office/seq-03 000216 000206 000211 000200 000187 000191 000195 000182
office/seq-03 000221 000206 000216 000211 000200 000195 000191 000187
office/seq-03 000227 000195 000200 000216 000211 000206 000221 000191
office/seq-03 000233 000227 000206 000221 000216 000211 000200 000195
office/seq-03 000240 000233 000221 000227 000216 000211 000206 000200
office/seq-03 000259 000240 000227 000233 000221 000216 000211 000206
office/seq-03 000267 000259 000233 000240 000227 000221 000216 000211
office/seq-03 000275 000267 000240 000259 000233 000227 000221 000216
office/seq-03 000283 000275 000259 000267 000240 000233 000227 000221
office/seq-03 000293 000275 000283 000267 000233 000227 000259 000240
office/seq-03 000303 000293 000267 000283 000275 000227 000233 000221
office/seq-03 000315 000275 000283 000293 000303 000227 000221 000233
office/seq-03 000325 000315 000275 000303 000293 000283 000227 000221
office/seq-03 000334 000283 000293 000315 000303 000325 000227 000275
office/seq-03 000344 000334 000315 000325 000283 000303 000293 000227
office/seq-03 000360 000344 000325 000334 000303 000315 000293 000283
office/seq-03 000368 000303 000334 000344 000315 000325 000360 000293
office/seq-03 000375 000315 000303 000360 000334 000368 000325 000344
office/seq-03 000379 000325 000303 000368 000360 000315 000375 000344
office/seq-03 000384 000375 000379 000368 000303 000360 000315 000293
office/seq-03 000392 000379 000384 000375 000303 000368 000293 000315
office/seq-03 000399 000368 000375 000384 000379 000392 000303 000293
office/seq-03 000404 000392 000399 000384 000375 000379 000368 000303
office/seq-03 000410 000399 000404 000392 000379 000384 000375 000368
office/seq-03 000416 000379 000399 000404 000392 000410 000384 000375
office/seq-03 000429 000392 000404 000410 000399 000416 000384 000379
office/seq-03 000442 000429 000410 000416 000404 000392 000399 000384
office/seq-03 000453 000416 000442 000429 000410 000404 000399 000392
office/seq-03 000463 000442 000453 000429 000410 000416 000404 000399
office/seq-03 000477 000463 000410 000453 000416 000429 000442 000404
office/seq-03 000493 000416 000429 000463 000453 000442 000477 000410
office/seq-03 000504 000493 000463 000477 000453 000442 000429 000410
office/seq-03 000512 000504 000477 000493 000453 000463 000442 000404
office/seq-03 000522 000512 000463 000504 000493 000477 000410 000404
office/seq-03 000531 000522 000410 000416 000504 000493 000477 000404
office/seq-03 000539 000493 000410 000522 000531 000504 000512 000416
office/seq-03 000544 000504 000493 000531 000522 000539 000410 000416
office/seq-03 000550 000410 000544 000539 000531 000504 000493 000404
office/seq-03 000556 000404 000550 000544 000539 000410 000531 000493
office/seq-03 000562 000539 000544 000550 000556 000404 000410 000399
office/seq-03 000568 000404 000544 000556 000550 000562 000399 000539
office/seq-03 000573 000544 000550 000562 000556 000568 000404 000399
office/seq-03 000578 000544 000556 000568 000562 000573 000550 000404
office/seq-03 000583 000578 000556 000573 000568 000562 000550 000544
office/seq-03 000589 000583 000556 000578 000562 000568 000573 000550
office/seq-03 000596 000589 000562 000568 000573 000578 000583 000556
office/seq-03 000602 000589 000596 000578 000573 000583 000568 000562
office/seq-03 000606 000589 000602 000596 000583 000573 000578 000568
office/seq-03 000611 000596 000578 000583 000606 000589 000602 000573
office/seq-03 000615 000606 000611 000602 000596 000589 000583 000578
office/seq-03 000620 000589 000606 000611 000602 000596 000615 000583
office/seq-03 000627 000615 000620 000611 000606 000602 000596 000589
office/seq-03 000635 000627 000615 000620 000611 000606 000602 000596
office/seq-03 000642 000635 000620 000627 000615 000611 000606 000602
office/seq-03 000649 000642 000627 000635 000620 000615 000611 000606
office/seq-03 000654 000649 000635 000642 000627 000620 000615 000611
office/seq-03 000660 000654 000642 000649 000635 000627 000620 000615
office/seq-03 000667 000660 000649 000654 000642 000635 000627 000620
office/seq-03 000676 000667 000654 000660 000649 000642 000635 000627
office/seq-03 000684 000676 000660 000667 000654 000649 000642 000635
office/seq-03 000689 000684 000667 000676 000660 000654 000649 000642
office/seq-03 000694 000689 000676 000684 000667 000660 000654 000649
office/seq-03 000700 000694 000684 000689 000676 000667 000660 000654
office/seq-03 000705 000700 000689 000694 000684 000676 000667 000660
office/seq-03 000711 000705 000694 000700 000689 000684 000676 000667
office/seq-03 000718 000711 000700 000705 000694 000689 000684 000676
office/seq-03 000726 000718 000705 000711 000700 000694 000689 000684
office/seq-03 000737 000726 000711 000718 000705 000700 000694 000689
office/seq-03 000746 000737 000718 000726 000711 000705 000700 000694
office/seq-03 000755 000746 000726 000737 000718 000711 000705 000700
office/seq-03 000765 000755 000737 000746 000726 000718 000711 000705
office/seq-03 000776 000765 000746 000755 000737 000726 000718 000711
office/seq-03 000787 000776 000755 000765 000746 000737 000726 000718
office/seq-03 000798 000787 000765 000776 000755 000746 000737 000726
office/seq-03 000807 000798 000776 000787 000765 000755 000746 000737
office/seq-03 000817 000807 000787 000798 000776 000765 000755 000746
office/seq-03 000828 000817 000798 000807 000787 000776 000765 000755
office/seq-03 000842 000828 000807 000817 000798 000787 000776 000765
office/seq-03 000850 000842 000817 000828 000807 000798 000787 000776
office/seq-03 000857 000850 000828 000842 000817 000807 000798 000787
office/seq-03 000865 000807 000798 000787 000857 000850 000817 000776
office/seq-03 000876 000865 000787 000857 000798 000807 000776 000850
office/seq-03 000888 000876 000776 000865 000857 000787 000798 000765
office/seq-03 000902 000787 000765 000876 000865 000888 000776 000857
office/seq-03 000912 000765 000902 000888 000876 000865 000776 000755
office/seq-03 000920 000746 000912 000902 000888 000876 000755 000765
office/seq-03 000933 000755 000888 000912 000902 000920 000746 000737
office/seq-03 000950 000933 000888 000920 000912 000902 000737 000746
office/seq-03 000966 000950 000933 000920 000902 000737 000912 000726
office/seq-03 000985 000950 000933 000966 000912 000920 000718 000726
pumpkin/seq-03 000017 000000 000012 000013 000009 000008 000003 000002
pumpkin/seq-03 000026 000000 000017 000010 000005 000016 000023 000022
pumpkin/seq-03 000032 000017 000026 000000 000020 000007 000006 000021
pumpkin/seq-03 000038 000032 000017 000026 000000 000019 000022 000009
pumpkin/seq-03 000044 000038 000017 000026 000032 000000 000040 000021
pumpkin/seq-03 000051 000044 000017 000026 000032 000038 000000 000028
pumpkin/seq-03 000058 000051 000017 000026 000032 000038 000044 000000
pumpkin/seq-03 000066 000038 000058
gitextract_6sfl0utb/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── configs/
│ ├── data/
│ │ ├── 7scenes_default.yaml
│ │ ├── 7scenes_dense.yaml
│ │ ├── colmap_dense.yaml
│ │ ├── neucon_arkit_default.yaml
│ │ ├── neucon_arkit_dense.yaml
│ │ ├── scannet_default_test.yaml
│ │ ├── scannet_default_train.yaml
│ │ ├── scannet_default_val.yaml
│ │ ├── scannet_dense_test.yaml
│ │ ├── scannet_dense_val.yaml
│ │ ├── scanniverse_dense.yaml
│ │ ├── vdr_default.yaml
│ │ ├── vdr_dense.yaml
│ │ ├── vdr_dense_offline.yaml
│ │ └── vdr_dense_rerun.yaml
│ └── models/
│ ├── dot_product_model.yaml
│ └── hero_model.yaml
├── data_scripts/
│ ├── 7scenes_preprocessing.py
│ ├── IOS_LOGGER_ARKIT_README.md
│ ├── generate_test_tuples.py
│ ├── generate_train_tuples.py
│ ├── ios_logger_preprocessing.py
│ ├── precompute_valid_frames.py
│ └── scannet_wrangling_scripts/
│ ├── LICENSE
│ ├── README.md
│ ├── SensorData.py
│ ├── download_scannet.py
│ ├── env.yml
│ ├── reader.py
│ └── splits/
│ ├── scannetv2_test.txt
│ ├── scannetv2_train.txt
│ └── scannetv2_val.txt
├── data_splits/
│ ├── 7Scenes/
│ │ └── dvmvs_split/
│ │ ├── dvmvs_test_split.txt
│ │ └── test_eight_view_deepvmvs.txt
│ ├── ScanNetv2/
│ │ ├── dvmvs_split/
│ │ │ ├── dvmvs_train.txt
│ │ │ ├── dvmvs_val.txt
│ │ │ ├── test_eight_view_deepvmvs.txt
│ │ │ └── test_eight_view_deepvmvs_dense.txt
│ │ └── standard_split/
│ │ ├── scannetv2_test.txt
│ │ ├── scannetv2_train.txt
│ │ ├── scannetv2_val.txt
│ │ ├── test_eight_view_deepvmvs.txt
│ │ ├── test_eight_view_deepvmvs_dense.txt
│ │ ├── test_eight_view_deepvmvs_offline.txt
│ │ ├── train_eight_view_deepvmvs.txt
│ │ └── val_eight_view_deepvmvs.txt
│ ├── arkit/
│ │ ├── scans.txt
│ │ ├── test_eight_view_deepvmvs.txt
│ │ └── test_eight_view_deepvmvs_dense.txt
│ └── vdr/
│ ├── scans.txt
│ ├── test_eight_view_deepvmvs.txt
│ ├── test_eight_view_deepvmvs_dense.txt
│ └── test_eight_view_deepvmvs_dense_offline.txt
├── experiment_modules/
│ └── depth_model.py
├── losses.py
├── modules/
│ ├── cost_volume.py
│ ├── layers.py
│ └── networks.py
├── options.py
├── pc_fusion.py
├── pixi.toml
├── requirements.txt
├── rerun_visualize_live_meshing.py
├── simplerecon_env.yml
├── sr_datasets/
│ ├── arkit_dataset.py
│ ├── colmap_dataset.py
│ ├── generic_mvs_dataset.py
│ ├── scannet_dataset.py
│ ├── scanniverse_dataset.py
│ ├── seven_scenes_dataset.py
│ └── vdr_dataset.py
├── test.py
├── tools/
│ ├── fusers_helper.py
│ ├── keyframe_buffer.py
│ ├── mesh_renderer.py
│ ├── torch_point_cloud_fusion.py
│ └── tsdf.py
├── train.py
├── utils/
│ ├── dataset_utils.py
│ ├── generic_utils.py
│ ├── geometry_utils.py
│ ├── metrics_utils.py
│ └── visualization_utils.py
├── visualization_scripts/
│ ├── generate_gt_min_max_cache.py
│ ├── load_meshes_and_include_normals.py
│ └── visualize_scene_depth_output.py
├── visualize_live_meshing.py
└── weights/
└── strip_checkpoint.py
SYMBOL INDEX (370 symbols across 37 files)
FILE: data_scripts/7scenes_preprocessing.py
function mkdir (line 34) | def mkdir(directory):
function process_scene (line 62) | def process_scene(ds):
FILE: data_scripts/generate_test_tuples.py
function compute_offline_tuple (line 65) | def compute_offline_tuple(
function default_dvmvs_tuples (line 159) | def default_dvmvs_tuples(scan, poses, dists_to_last_valid, n_measurement...
function offline_dvmvs_tuples (line 214) | def offline_dvmvs_tuples(scan, poses, n_measurement_frames):
function dense_dvmvs_tuples (line 268) | def dense_dvmvs_tuples(scan, poses, n_measurement_frames):
function offline_dense_dvmvs_tuples (line 345) | def offline_dense_dvmvs_tuples(scan, poses, n_measurement_frames):
function crawl_subprocess_long (line 384) | def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
function crawl (line 530) | def crawl(opts_temp_filepath, opts, scans):
FILE: data_scripts/generate_train_tuples.py
function gather_pairs_train (line 55) | def gather_pairs_train(poses, used_pairs,
function crawl_subprocess_short (line 140) | def crawl_subprocess_short(opts_temp_filepath, scan, count, progress):
function crawl_subprocess_long (line 221) | def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
function crawl (line 378) | def crawl(opts_temp_filepath, opts, scans):
FILE: data_scripts/precompute_valid_frames.py
function process_scan (line 45) | def process_scan(opts_temp_filepath, scan, count, progress):
function multi_process_scans (line 92) | def multi_process_scans(opts_temp_filepath, opts, scans):
FILE: data_scripts/scannet_wrangling_scripts/SensorData.py
function print_array_on_one_line (line 16) | def print_array_on_one_line():
class RGBDFrame (line 23) | class RGBDFrame():
method load (line 25) | def load(self, file_handle):
method decompress_depth (line 35) | def decompress_depth(self, compression_type):
method decompress_depth_zlib (line 42) | def decompress_depth_zlib(self):
method decompress_color (line 46) | def decompress_color(self, compression_type):
method dump_color_to_file (line 52) | def dump_color_to_file(self, compression_type, filepath):
method decompress_color_jpeg (line 61) | def decompress_color_jpeg(self):
class SensorData (line 65) | class SensorData:
method __init__ (line 67) | def __init__(self, filename):
method load (line 72) | def load(self, filename):
method export_depth_images (line 98) | def export_depth_images(self, output_path, image_size=None, frame_skip...
method export_color_images (line 117) | def export_color_images(self, output_path, image_size=None, frame_skip...
method save_mat_to_file (line 133) | def save_mat_to_file(self, matrix, filename):
method export_poses (line 139) | def export_poses(self, output_path, frame_skip=1):
method export_intrinsics (line 147) | def export_intrinsics(self, output_path, scan_name):
FILE: data_scripts/scannet_wrangling_scripts/download_scannet.py
function get_release_scans (line 33) | def get_release_scans(release_file):
function download_release (line 42) | def download_release(release_scans, out_dir, file_types, use_v1_sens):
function download_file (line 52) | def download_file(url, out_file):
function download_scan (line 66) | def download_scan(scan_id, out_dir, file_types, use_v1_sens):
function download_task_data (line 78) | def download_task_data(out_dir):
function download_tfrecords (line 94) | def download_tfrecords(in_dir, out_dir):
function download_label_map (line 112) | def download_label_map(out_dir):
function main (line 125) | def main():
FILE: data_scripts/scannet_wrangling_scripts/reader.py
function process_scan (line 30) | def process_scan(opt, scan_job, count=None, progress=None):
function main (line 54) | def main():
FILE: experiment_modules/depth_model.py
class DepthModel (line 21) | class DepthModel(pl.LightningModule):
method __init__ (line 68) | def __init__(self, opts):
method compute_matching_feats (line 191) | def compute_matching_feats(
method forward (line 247) | def forward(
method compute_losses (line 409) | def compute_losses(self, cur_data, src_data, outputs):
method step (line 502) | def step(self, phase, batch, batch_idx):
method training_step (line 607) | def training_step(self, batch, batch_idx):
method validation_step (line 611) | def validation_step(self, batch, batch_idx):
method configure_optimizers (line 615) | def configure_optimizers(self):
FILE: losses.py
class MSGradientLoss (line 11) | class MSGradientLoss(nn.Module):
method __init__ (line 12) | def __init__(self, num_scales: int = 4):
method forward (line 17) | def forward(self, depth_gt: Tensor, depth_pred: Tensor) -> Tensor:
class ScaleInvariantLoss (line 39) | class ScaleInvariantLoss(jit.ScriptModule):
method __init__ (line 40) | def __init__(self, si_lambda: float = 0.85):
method forward (line 46) | def forward(self, log_depth_gt: Tensor, log_depth_pred: Tensor) -> Ten...
class NormalsLoss (line 57) | class NormalsLoss(nn.Module):
method forward (line 58) | def forward(self, normals_gt_b3hw: Tensor, normals_pred_b3hw: Tensor) ...
class MVDepthLoss (line 79) | class MVDepthLoss(nn.Module):
method __init__ (line 80) | def __init__(self, height, width):
method get_valid_mask (line 90) | def get_valid_mask(
method get_error_for_pair (line 136) | def get_error_for_pair(self,
method forward (line 175) | def forward(
FILE: modules/cost_volume.py
class CostVolumeManager (line 13) | class CostVolumeManager(nn.Module):
method __init__ (line 27) | def __init__(
method initialise_for_projection (line 58) | def initialise_for_projection(self):
method get_mask (line 77) | def get_mask(self, pix_coords_bk2hw):
method generate_depth_planes (line 100) | def generate_depth_planes(self, batch_size: int,
method warp_features (line 139) | def warp_features(
method build_cost_volume (line 237) | def build_cost_volume(
method indices_to_disparity (line 338) | def indices_to_disparity(self, indices, depth_planes_bdhw):
method forward (line 345) | def forward(
class FeatureVolumeManager (line 383) | class FeatureVolumeManager(CostVolumeManager):
method __init__ (line 398) | def __init__(self,
method build_cost_volume (line 451) | def build_cost_volume(self,
method to_fast (line 739) | def to_fast(self) -> 'FastFeatureVolumeManager':
class FastFeatureVolumeManager (line 749) | class FastFeatureVolumeManager(FeatureVolumeManager):
method __init__ (line 759) | def __init__(self,
method warp_features (line 812) | def warp_features(
method build_cost_volume (line 967) | def build_cost_volume(
FILE: modules/layers.py
function conv3x3 (line 7) | def conv3x3(
function conv1x1 (line 20) | def conv1x1(in_planes: int, out_planes: int, stride: int = 1, bias: bool...
class BasicBlock (line 24) | class BasicBlock(nn.Module):
method __init__ (line 27) | def __init__(
method forward (line 68) | def forward(self, x: Tensor) -> Tensor:
class TensorFormatter (line 87) | class TensorFormatter(nn.Module):
method __init__ (line 95) | def __init__(self):
method _expand_batch_with_channels (line 101) | def _expand_batch_with_channels(self, x):
method _reduce_batch_to_channels (line 109) | def _reduce_batch_to_channels(self, x):
method forward (line 117) | def forward(self, x, apply_func):
FILE: modules/networks.py
function double_basic_block (line 13) | def double_basic_block(num_ch_in, num_ch_out, num_repeats=2):
class DepthDecoderPP (line 20) | class DepthDecoderPP(nn.Module):
method __init__ (line 21) | def __init__(
method forward (line 75) | def forward(self, input_features):
class CVEncoder (line 99) | class CVEncoder(nn.Module):
method __init__ (line 100) | def __init__(self, num_ch_cv, num_ch_enc, num_ch_outs):
method forward (line 120) | def forward(self, x, img_feats):
class MLP (line 129) | class MLP(nn.Module):
method __init__ (line 130) | def __init__(self, channel_list, disable_final_activation = False):
method forward (line 146) | def forward(self, x):
class ResnetMatchingEncoder (line 149) | class ResnetMatchingEncoder(nn.Module):
method __init__ (line 152) | def __init__(
method forward (line 204) | def forward(self, input_image):
class UNetMatchingEncoder (line 207) | class UNetMatchingEncoder(nn.Module):
method __init__ (line 208) | def __init__(self):
method forward (line 226) | def forward(self, x):
FILE: options.py
class Options (line 10) | class Options():
class OptionsHandler (line 220) | class OptionsHandler():
method __init__ (line 256) | def __init__(self, required_flags=[]):
method parse_and_merge_options (line 271) | def parse_and_merge_options(self, config_filepaths=None, ignore_cl_arg...
method populate_argparse (line 336) | def populate_argparse(self):
method check_required_items (line 350) | def check_required_items(self):
method merge_config_options (line 356) | def merge_config_options(self, config_options):
method merge_cl_args (line 364) | def merge_cl_args(self, cl_args):
method pretty_print_options (line 384) | def pretty_print_options(self):
method load_options_from_yaml (line 393) | def load_options_from_yaml(config_filepath):
method save_options_as_yaml (line 398) | def save_options_as_yaml(config_filepath, options):
function handle_backwards_compat (line 402) | def handle_backwards_compat(opts):
FILE: pc_fusion.py
function main (line 34) | def main(opts):
FILE: rerun_visualize_live_meshing.py
function to_device (line 32) | def to_device(input_dict, key_ignores=[], device="cuda"):
function log_source_data (line 42) | def log_source_data(src_entity_path: str, src_data: Dict[str, Any]) -> N...
function log_camera (line 55) | def log_camera(
function log_image (line 76) | def log_image(
function log_rerun (line 92) | def log_rerun(
function main (line 168) | def main(opts):
FILE: sr_datasets/arkit_dataset.py
class ARKitDataset (line 16) | class ARKitDataset(GenericMVSDataset):
method __init__ (line 28) | def __init__(self,
method get_sub_folder_dir (line 125) | def get_sub_folder_dir(split):
method get_frame_id_string (line 128) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 137) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 145) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method get_color_filepath (line 240) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 265) | def get_high_res_color_filepath(self, scan_id, frame_id):
method get_cached_depth_filepath (line 290) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 299) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_pose_filepath (line 307) | def get_pose_filepath(self, scan_id, frame_id):
method load_target_size_depth_and_mask (line 321) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 335) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method load_pose (line 350) | def load_pose(self, scan_id, frame_id):
method load_intrinsics (line 372) | def load_intrinsics(self, scan_id, frame_id, flip=None):
function process_data (line 421) | def process_data(data_path, data_source='ARKit',
function path_parser (line 467) | def path_parser(root_path, data_source='TagBA'):
function load_camera_pose (line 484) | def load_camera_pose(cam_pose_dir, use_homogenous=True, data_source='Tag...
function load_camera_intrinsic (line 536) | def load_camera_intrinsic(cam_file, data_source='TagBA'):
function extract_frames (line 597) | def extract_frames(video_path, out_folder, size):
function sync_intrinsics_and_poses (line 608) | def sync_intrinsics_and_poses(cam_file, pose_file, out_file):
FILE: sr_datasets/colmap_dataset.py
class ColmapDataset (line 15) | class ColmapDataset(GenericMVSDataset):
method __init__ (line 48) | def __init__(
method get_sub_folder_dir (line 142) | def get_sub_folder_dir(split):
method get_frame_id_string (line 145) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 154) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 163) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method load_pose (line 233) | def load_pose(self, scan_id, frame_id):
method load_intrinsics (line 268) | def load_intrinsics(self, scan_id, frame_id=None, flip=None):
method load_capture_poses (line 398) | def load_capture_poses(self, scan_id):
method load_target_size_depth_and_mask (line 448) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 462) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method get_cached_depth_filepath (line 477) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 487) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_color_filepath (line 495) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 522) | def get_high_res_color_filepath(self, scan_id, frame_id):
method load_color (line 543) | def load_color(self, scan_id, frame_id):
method load_high_res_color (line 569) | def load_high_res_color(self, scan_id, frame_id):
FILE: sr_datasets/generic_mvs_dataset.py
class GenericMVSDataset (line 15) | class GenericMVSDataset(Dataset):
method __init__ (line 43) | def __init__(self,
method __len__ (line 197) | def __len__(self):
method get_sub_folder_dir (line 201) | def get_sub_folder_dir(split):
method get_valid_frame_path (line 205) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 211) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method get_color_filepath (line 233) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 249) | def get_high_res_color_filepath(self, scan_id, frame_id):
method get_cached_depth_filepath (line 266) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 281) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_pose_filepath (line 297) | def get_pose_filepath(self, scan_id, frame_id):
method get_frame_id_string (line 310) | def get_frame_id_string(self, frame_id):
method get_gt_mesh_path (line 319) | def get_gt_mesh_path(dataset_path, split, scan_id):
method load_intrinsics (line 325) | def load_intrinsics(self, scan_id, frame_id=None, flip=None):
method load_target_size_depth_and_mask (line 347) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 368) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method load_pose (line 386) | def load_pose(self, scan_id, frame_id):
method load_color (line 402) | def load_color(self, scan_id, frame_id):
method load_high_res_color (line 425) | def load_high_res_color(self, scan_id, frame_id):
method get_frame (line 451) | def get_frame(self, scan_id, frame_id, load_depth, flip=False):
method stack_src_data (line 587) | def stack_src_data(self, src_data):
method __getitem__ (line 602) | def __getitem__(self, idx):
FILE: sr_datasets/scannet_dataset.py
class ScannetDataset (line 11) | class ScannetDataset(GenericMVSDataset):
method __init__ (line 77) | def __init__(
method get_sub_folder_dir (line 165) | def get_sub_folder_dir(split):
method get_frame_id_string (line 172) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 181) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 190) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method get_gt_mesh_path (line 292) | def get_gt_mesh_path(dataset_path, split, scan_id):
method get_color_filepath (line 304) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 330) | def get_high_res_color_filepath(self, scan_id, frame_id):
method get_cached_depth_filepath (line 357) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 379) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_pose_filepath (line 399) | def get_pose_filepath(self, scan_id, frame_id):
method load_intrinsics (line 416) | def load_intrinsics(self, scan_id, frame_id=None, flip=False):
method load_target_size_depth_and_mask (line 474) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 517) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method load_pose (line 549) | def load_pose(self, scan_id, frame_id):
FILE: sr_datasets/scanniverse_dataset.py
class ScanniverseDataset (line 14) | class ScanniverseDataset(GenericMVSDataset):
method __init__ (line 27) | def __init__(
method get_sub_folder_dir (line 128) | def get_sub_folder_dir(split):
method load_capture_metadata (line 131) | def load_capture_metadata(self, scan_id):
method get_frame_id_string (line 239) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 248) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 256) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method get_color_filepath (line 331) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 369) | def get_high_res_color_filepath(self, scan_id, frame_id):
method get_cached_depth_filepath (line 387) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 397) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method load_pose (line 405) | def load_pose(self, scan_id, frame_id):
method load_intrinsics (line 447) | def load_intrinsics(self, scan_id, frame_id, flip=None):
method load_target_size_depth_and_mask (line 514) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 528) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
FILE: sr_datasets/seven_scenes_dataset.py
class SevenScenesDataset (line 12) | class SevenScenesDataset(GenericMVSDataset):
method __init__ (line 47) | def __init__(
method get_sub_folder_dir (line 135) | def get_sub_folder_dir(split):
method get_frame_id_string (line 139) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 148) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 157) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method get_color_filepath (line 254) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 281) | def get_high_res_color_filepath(self, scan_id, frame_id):
method get_cached_depth_filepath (line 308) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 328) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_pose_filepath (line 347) | def get_pose_filepath(self, scan_id, frame_id):
method load_intrinsics (line 362) | def load_intrinsics(self, scan_id=None, frame_id=None, flip=None):
method load_target_size_depth_and_mask (line 410) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 452) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method load_pose (line 485) | def load_pose(self, scan_id, frame_id):
FILE: sr_datasets/vdr_dataset.py
class VDRDataset (line 17) | class VDRDataset(GenericMVSDataset):
method __init__ (line 29) | def __init__(
method get_sub_folder_dir (line 78) | def get_sub_folder_dir(split):
method get_frame_id_string (line 81) | def get_frame_id_string(self, frame_id):
method get_valid_frame_path (line 90) | def get_valid_frame_path(self, split, scan):
method get_valid_frame_ids (line 98) | def get_valid_frame_ids(self, split, scan, store_computed=True):
method load_pose (line 168) | def load_pose(self, scan_id, frame_id):
method load_intrinsics (line 207) | def load_intrinsics(self, scan_id, frame_id, flip=None):
method load_capture_metadata (line 266) | def load_capture_metadata(self, scan_id):
method get_cached_depth_filepath (line 294) | def get_cached_depth_filepath(self, scan_id, frame_id):
method get_cached_confidence_filepath (line 327) | def get_cached_confidence_filepath(self, scan_id, frame_id):
method get_full_res_depth_filepath (line 361) | def get_full_res_depth_filepath(self, scan_id, frame_id):
method get_full_res_confidence_filepath (line 383) | def get_full_res_confidence_filepath(self, scan_id, frame_id):
method load_full_res_depth_and_mask (line 404) | def load_full_res_depth_and_mask(self, scan_id, frame_id):
method load_target_size_depth_and_mask (line 444) | def load_target_size_depth_and_mask(self, scan_id, frame_id):
method get_color_filepath (line 513) | def get_color_filepath(self, scan_id, frame_id):
method get_high_res_color_filepath (line 541) | def get_high_res_color_filepath(self, scan_id, frame_id):
FILE: test.py
function main (line 128) | def main(opts):
FILE: tools/fusers_helper.py
class DepthFuser (line 11) | class DepthFuser():
method __init__ (line 12) | def __init__(
class OurFuser (line 22) | class OurFuser(DepthFuser):
method __init__ (line 34) | def __init__(
method fuse_frames (line 64) | def fuse_frames(self, depths_b1hw, K_b44,
method export_mesh (line 73) | def export_mesh(self, path, export_single_mesh=True):
method get_mesh (line 80) | def get_mesh(self, export_single_mesh=True, convert_to_trimesh=True):
class Open3DFuser (line 84) | class Open3DFuser(DepthFuser):
method __init__ (line 90) | def __init__(
method fuse_frames (line 116) | def fuse_frames(
method export_mesh (line 177) | def export_mesh(self, path, use_marching_cubes_mask=None):
method get_mesh (line 180) | def get_mesh(self, export_single_mesh=None, convert_to_trimesh=False):
function get_fuser (line 188) | def get_fuser(opts, scan):
FILE: tools/keyframe_buffer.py
class DVMVS_Config (line 12) | class DVMVS_Config:
function is_pose_available (line 24) | def is_pose_available(pose):
function is_valid_pair (line 33) | def is_valid_pair(
function pose_distance (line 54) | def pose_distance(reference_pose, measurement_pose):
class KeyframeBuffer (line 72) | class KeyframeBuffer:
method __init__ (line 73) | def __init__(
method calculate_penalty (line 89) | def calculate_penalty(self, t_score, R_score):
method try_new_keyframe (line 99) | def try_new_keyframe(self, pose, image, dist_to_last_valid=None, index...
method get_best_measurement_frames (line 163) | def get_best_measurement_frames(self, n_requested_measurement_frames):
class SimpleBuffer (line 189) | class SimpleBuffer:
method __init__ (line 190) | def __init__(
method try_new_keyframe (line 200) | def try_new_keyframe(self, pose, image, index=None):
method get_measurement_frames (line 241) | def get_measurement_frames(self):
class OfflineKeyframeBuffer (line 245) | class OfflineKeyframeBuffer:
method __init__ (line 246) | def __init__(
method calculate_penalty (line 263) | def calculate_penalty(self, t_score, R_score):
method try_new_keyframe (line 273) | def try_new_keyframe(self, pose, image, index=None):
method get_best_measurement_frames (line 332) | def get_best_measurement_frames(self, n_requested_measurement_frames):
method get_best_measurement_frames_for_0index (line 357) | def get_best_measurement_frames_for_0index(self, n_requested_measureme...
FILE: tools/mesh_renderer.py
class Renderer (line 26) | class Renderer():
method __init__ (line 32) | def __init__(self, height=480, width=640, flat_render=False):
method render (line 37) | def render(self, height, width,
method __call__ (line 66) | def __call__(self, height, width, intrinsics, pose, meshes):
method fix_pose (line 69) | def fix_pose(self, pose):
method mesh_opengl (line 81) | def mesh_opengl(self, mesh, mesh_material=None):
method delete (line 87) | def delete(self):
method render_mesh (line 90) | def render_mesh(
method render_mesh_cull_composite (line 134) | def render_mesh_cull_composite(self, alpha, **kwargs):
function render_colour (line 143) | def render_colour(renderer, meshes, world_T_cam, K, height=256, width=320):
class SmoothBirdsEyeCamera (line 155) | class SmoothBirdsEyeCamera():
method __init__ (line 160) | def __init__(
method get_bird_eye_trans (line 178) | def get_bird_eye_trans(self,
function camera_marker (line 265) | def camera_marker(
function get_image_box (line 428) | def get_image_box(
function create_light_array (line 496) | def create_light_array(light_type, center_loc,
function transform_trimesh (line 523) | def transform_trimesh(mesh, transform):
FILE: tools/torch_point_cloud_fusion.py
function process_depth (line 12) | def process_depth(ref_depth, ref_image, src_depths, src_images, ref_P, s...
function process_scene (line 100) | def process_scene(depth_preds, images, poses, K, z_thresh, n_consistent_...
FILE: tools/tsdf.py
class TSDF (line 11) | class TSDF:
method __init__ (line 19) | def __init__(
method from_file (line 37) | def from_file(cls, tsdf_file):
method from_mesh (line 52) | def from_mesh(cls, mesh: trimesh.Trimesh, voxel_size: float):
method from_bounds (line 70) | def from_bounds(cls, bounds: dict, voxel_size: float):
method generate_voxel_coords (line 98) | def generate_voxel_coords(cls,
method cuda (line 111) | def cuda(self):
method cpu (line 118) | def cpu(self):
method to_mesh (line 125) | def to_mesh(self, scale_to_world=True, export_single_mesh=False):
method save (line 159) | def save(self, savepath, filename, save_mesh=True):
class TSDFFuser (line 171) | class TSDFFuser:
method __init__ (line 175) | def __init__(self, tsdf, min_depth=0.5, max_depth=5.0, use_gpu=True):
method voxel_coords (line 198) | def voxel_coords(self):
method tsdf_values (line 202) | def tsdf_values(self):
method tsdf_weights (line 206) | def tsdf_weights(self):
method voxel_size (line 210) | def voxel_size(self):
method shape (line 214) | def shape(self):
method truncation (line 218) | def truncation(self):
method project_to_camera (line 221) | def project_to_camera(self, cam_T_world_T_b44, K_b44):
method integrate_depth (line 238) | def integrate_depth(
FILE: train.py
function main (line 34) | def main(opts):
FILE: utils/dataset_utils.py
function get_dataset (line 8) | def get_dataset(dataset_name,
FILE: utils/generic_utils.py
function copy_code_state (line 15) | def copy_code_state(path):
function readlines (line 36) | def readlines(filepath):
function normalize_depth_single (line 42) | def normalize_depth_single(depth_11hw, mask_11hw, robust=False):
function normalize_depth (line 73) | def normalize_depth(depth_b1hw: torch.Tensor,
function pyrdown (line 88) | def pyrdown(input_tensor: torch.Tensor, num_scales: int = 4):
function upsample (line 96) | def upsample(x):
function batched_trace (line 107) | def batched_trace(mat_bNN):
function tensor_B_to_bM (line 110) | def tensor_B_to_bM(tensor_BS, batch_size, num_views):
function tensor_bM_to_B (line 121) | def tensor_bM_to_B(tensor_bMS):
function combine_dims (line 132) | def combine_dims(x, dim_begin, dim_end):
function to_gpu (line 138) | def to_gpu(input_dict, key_ignores=[]):
function imagenet_normalize (line 147) | def imagenet_normalize(image):
function reverse_imagenet_normalize (line 153) | def reverse_imagenet_normalize(image):
function read_image_file (line 162) | def read_image_file(filepath,
function crop_image_to_target_ratio (line 210) | def crop_image_to_target_ratio(image, target_aspect_ratio=4.0/3.0):
function cache_model_outputs (line 241) | def cache_model_outputs(
FILE: utils/geometry_utils.py
function to_homogeneous (line 12) | def to_homogeneous(input_tensor: Tensor, dim: int = 0) -> Tensor:
class BackprojectDepth (line 22) | class BackprojectDepth(jit.ScriptModule):
method __init__ (line 28) | def __init__(self, height: int, width: int):
method forward (line 51) | def forward(self, depth_b1hw: Tensor, invK_b44: Tensor) -> Tensor:
class Project3D (line 62) | class Project3D(jit.ScriptModule):
method __init__ (line 66) | def __init__(self, eps: float = 1e-8):
method forward (line 72) | def forward(self, points_b4N: Tensor,
class NormalGenerator (line 92) | class NormalGenerator(jit.ScriptModule):
method __init__ (line 93) | def __init__(self, height: int, width: int,
method forward (line 108) | def forward(self, depth_b1hw: Tensor, invK_b44: Tensor) -> Tensor:
function get_angle_dif (line 135) | def get_angle_dif(matA_b33, matB_b33):
function get_camera_rays (line 143) | def get_camera_rays(
function pose_distance (line 178) | def pose_distance(pose_b44):
function qvec2rotmat (line 193) | def qvec2rotmat(qvec):
function rotx (line 213) | def rotx(t):
function roty (line 223) | def roty(t):
function rotz (line 233) | def rotz(t):
FILE: utils/metrics_utils.py
function compute_depth_metrics (line 7) | def compute_depth_metrics(gt, pred, mult_a=False):
function compute_depth_metrics_batched (line 51) | def compute_depth_metrics_batched(gt_bN, pred_bN, valid_masks_bN, mult_a...
class ResultsAverager (line 122) | class ResultsAverager():
method __init__ (line 126) | def __init__(self, exp_name, metrics_name):
method update_results (line 141) | def update_results(self, elem_metrics):
method print_sheets_friendly (line 163) | def print_sheets_friendly(
method output_json (line 200) | def output_json(self, filepath, print_running_metrics=False):
method pretty_print_results (line 236) | def pretty_print_results(
method compute_final_average (line 263) | def compute_final_average(self, ignore_nans=False):
FILE: utils/visualization_utils.py
function colormap_image (line 12) | def colormap_image(
function save_viz_video_frames (line 74) | def save_viz_video_frames(frame_list, path, fps=30):
function quick_viz_export (line 84) | def quick_viz_export(
FILE: visualization_scripts/generate_gt_min_max_cache.py
function main (line 26) | def main(opts):
FILE: visualization_scripts/visualize_scene_depth_output.py
function main (line 34) | def main(opts):
FILE: visualize_live_meshing.py
function main (line 27) | def main(opts):
Copy disabled (too large)
Download .json
Condensed preview — 92 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,104K chars).
[
{
"path": ".gitattributes",
"chars": 63,
"preview": "# GitHub syntax highlighting\npixi.lock linguist-language=YAML\n\n"
},
{
"path": ".gitignore",
"chars": 132,
"preview": "*.pyc\n.vscode/\ndebug_scripts/\nlogs/\nlogs\nmodels/*.ckpt\nweights/*.ckpt\n**__pycache__**\n# pixi environments\n.pixi\ndata/*\nO"
},
{
"path": "LICENSE",
"chars": 8466,
"preview": "Copyright © Niantic, Inc. 2022. Patent Pending.\n\nAll rights reserved.\n\n\n\n==============================================="
},
{
"path": "README.md",
"chars": 32984,
"preview": "# SimpleRecon: 3D Reconstruction Without 3D Convolutions\n\nThis is the reference PyTorch implementation for training and "
},
{
"path": "configs/data/7scenes_default.yaml",
"chars": 345,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/shared/datasets/7scenes/\ntuple_info_file_location: data_split"
},
{
"path": "configs/data/7scenes_dense.yaml",
"chars": 349,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/shared/datasets/7scenes/\ntuple_info_file_location: data_split"
},
{
"path": "configs/data/colmap_dense.yaml",
"chars": 355,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/mohameds/datasets/colmap/\ntuple_info_file_location: /mnt/res_"
},
{
"path": "configs/data/neucon_arkit_default.yaml",
"chars": 303,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/mohameds/datasets/arkit\ntuple_info_file_location: data_splits"
},
{
"path": "configs/data/neucon_arkit_dense.yaml",
"chars": 307,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/mohameds/datasets/arkit\ntuple_info_file_location: data_splits"
},
{
"path": "configs/data/scannet_default_test.yaml",
"chars": 387,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/scannet-data-png2/\ntuple_info_file_location: data_splits/ScanNetv2/st"
},
{
"path": "configs/data/scannet_default_train.yaml",
"chars": 341,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/scannet-data-png2/\ntuple_info_file_location: data_splits/ScanNetv2/st"
},
{
"path": "configs/data/scannet_default_val.yaml",
"chars": 337,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/scannet-data-png2/\ntuple_info_file_location: data_splits/ScanNetv2/st"
},
{
"path": "configs/data/scannet_dense_test.yaml",
"chars": 343,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/scannet-data-png2/\ntuple_info_file_location: data_splits/ScanNetv2/st"
},
{
"path": "configs/data/scannet_dense_val.yaml",
"chars": 341,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/scannet-data-png2/\ntuple_info_file_location: data_splits/ScanNetv2/st"
},
{
"path": "configs/data/scanniverse_dense.yaml",
"chars": 376,
"preview": "!!python/object:options.Options\ndataset_path: /mnt/res_nas/mohameds/datasets/scanniverse/\ntuple_info_file_location: /mnt"
},
{
"path": "configs/data/vdr_default.yaml",
"chars": 293,
"preview": "!!python/object:options.Options\ndataset_path: /media/data/mosayed/datasets/vdr\ntuple_info_file_location: data_splits/vdr"
},
{
"path": "configs/data/vdr_dense.yaml",
"chars": 297,
"preview": "!!python/object:options.Options\ndataset_path: /media/data/mosayed/datasets/vdr\ntuple_info_file_location: data_splits/vdr"
},
{
"path": "configs/data/vdr_dense_offline.yaml",
"chars": 313,
"preview": "!!python/object:options.Options\ndataset_path: /media/data/mosayed/datasets/vdr\ntuple_info_file_location: data_splits/vdr"
},
{
"path": "configs/data/vdr_dense_rerun.yaml",
"chars": 273,
"preview": "!!python/object:options.Options\ndataset_path: data/vdr\ntuple_info_file_location: data_splits/vdr/\ndataset_scan_split_fil"
},
{
"path": "configs/models/dot_product_model.yaml",
"chars": 402,
"preview": "!!python/object:options.Options\nfeature_volume_type: simple_cost_volume\nbatch_size: 16\ncost_volume_aggregation: dot\ncv_e"
},
{
"path": "configs/models/hero_model.yaml",
"chars": 395,
"preview": "!!python/object:options.Options\nfeature_volume_type: mlp_feature_volume\nbatch_size: 16\ncost_volume_aggregation: dot\ncv_e"
},
{
"path": "data_scripts/7scenes_preprocessing.py",
"chars": 4763,
"preview": "# Code from https://github.com/tsattler/visloc_pseudo_gt_limitations/\n\nimport os\nimport warnings\n\nimport numpy as np\nfro"
},
{
"path": "data_scripts/IOS_LOGGER_ARKIT_README.md",
"chars": 2414,
"preview": "# Running with NeuralRecon's demo data and data from ios-logger.\n\nDownload the demo scene out of ios-logger from here: h"
},
{
"path": "data_scripts/generate_test_tuples.py",
"chars": 22724,
"preview": "\n\"\"\"Script for generating DeeoVideoMVS multiview lists in the split folder \n indicated. It will export these frame tu"
},
{
"path": "data_scripts/generate_train_tuples.py",
"chars": 17353,
"preview": "\"\"\"Script for generating DeeoVideoMVS multiview lists in the split folder \n indicated. It will export these frame tup"
},
{
"path": "data_scripts/ios_logger_preprocessing.py",
"chars": 849,
"preview": "import os\nimport sys\nsys.path.append(\"/\".join(sys.path[0].split(\"/\")[:-1]))\nfrom datasets.arkit_dataset import process_d"
},
{
"path": "data_scripts/precompute_valid_frames.py",
"chars": 5619,
"preview": "\n\"\"\"Script for precomputing and storing a list of valid frames per scan. A valid \n frame is defined as one that has a"
},
{
"path": "data_scripts/scannet_wrangling_scripts/LICENSE",
"chars": 1192,
"preview": "The LICENSE applies only to reader.py and SensorData.py.\n\nCopyright 2017 \nAngela Dai, Angel X. Chang, Manolis Savva, Mac"
},
{
"path": "data_scripts/scannet_wrangling_scripts/README.md",
"chars": 4352,
"preview": "# Downloading and Extracting ScanNetv2\n\n\nDeveloped and tested with python 3.9.\n\nThe included license at LICENSE applies "
},
{
"path": "data_scripts/scannet_wrangling_scripts/SensorData.py",
"chars": 6516,
"preview": "\nimport os, struct\nimport numpy as np\nimport zlib\nimport imageio\nimport cv2\nimport png\nfrom PIL import Image\nfrom contex"
},
{
"path": "data_scripts/scannet_wrangling_scripts/download_scannet.py",
"chars": 12447,
"preview": "#!/usr/bin/env python\n# Downloads ScanNet public data release\n# Run with ./download-scannet.py (or python download-scann"
},
{
"path": "data_scripts/scannet_wrangling_scripts/env.yml",
"chars": 147,
"preview": "name: scannet_extraction\ndependencies:\n - python=3.9.7\n - numpy\n - imageio\n - pillow\n - tqdm\n - pip\n - pip:\n -"
},
{
"path": "data_scripts/scannet_wrangling_scripts/reader.py",
"chars": 3258,
"preview": "import argparse\nfrom concurrent.futures import process\nimport os, sys\nfrom tqdm import tqdm\nfrom multiprocessing.pool im"
},
{
"path": "data_scripts/scannet_wrangling_scripts/splits/scannetv2_test.txt",
"chars": 1300,
"preview": "scene0707_00\nscene0708_00\nscene0709_00\nscene0710_00\nscene0711_00\nscene0712_00\nscene0713_00\nscene0714_00\nscene0715_00\nsce"
},
{
"path": "data_scripts/scannet_wrangling_scripts/splits/scannetv2_train.txt",
"chars": 15613,
"preview": "scene0191_00\nscene0191_01\nscene0191_02\nscene0119_00\nscene0230_00\nscene0528_00\nscene0528_01\nscene0705_00\nscene0705_01\nsce"
},
{
"path": "data_scripts/scannet_wrangling_scripts/splits/scannetv2_val.txt",
"chars": 4056,
"preview": "scene0568_00\nscene0568_01\nscene0568_02\nscene0304_00\nscene0488_00\nscene0488_01\nscene0412_00\nscene0412_01\nscene0217_00\nsce"
},
{
"path": "data_splits/7Scenes/dvmvs_split/dvmvs_test_split.txt",
"chars": 185,
"preview": "redkitchen/seq-01\nredkitchen/seq-07\nchess/seq-01\nchess/seq-02\nheads/seq-02\nfire/seq-01\nfire/seq-02\noffice/seq-01\noffice/"
},
{
"path": "data_splits/7Scenes/dvmvs_split/test_eight_view_deepvmvs.txt",
"chars": 94671,
"preview": "stairs/seq-06 000018 000000 000002 000010 000007 000015 000012 000005\nstairs/seq-06 000029 000000 000018 000025 000007 0"
},
{
"path": "data_splits/ScanNetv2/dvmvs_split/dvmvs_train.txt",
"chars": 18083,
"preview": "scene0031_00\nscene0031_01\nscene0031_02\nscene0070_00\nscene0547_00\nscene0547_01\nscene0547_02\nscene0512_00\nscene0332_00\nsce"
},
{
"path": "data_splits/ScanNetv2/dvmvs_split/dvmvs_val.txt",
"chars": 1586,
"preview": "scene0690_00\nscene0690_01\nscene0453_00\nscene0453_01\nscene0603_00\nscene0603_01\nscene0672_00\nscene0672_01\nscene0364_00\nsce"
},
{
"path": "data_splits/ScanNetv2/dvmvs_split/test_eight_view_deepvmvs.txt",
"chars": 94671,
"preview": "stairs/seq-06 000018 000000 000003 000001 000016 000015 000007 000014\nstairs/seq-06 000029 000000 000018 000003 000008 0"
},
{
"path": "data_splits/ScanNetv2/dvmvs_split/test_eight_view_deepvmvs_dense.txt",
"chars": 842087,
"preview": "stairs/seq-06 000001 000000 000000 000000 000000 000000 000000 000000\nstairs/seq-06 000002 000000 000001 000000 000000 0"
},
{
"path": "data_splits/ScanNetv2/standard_split/scannetv2_test.txt",
"chars": 1300,
"preview": "scene0707_00\nscene0708_00\nscene0709_00\nscene0710_00\nscene0711_00\nscene0712_00\nscene0713_00\nscene0714_00\nscene0715_00\nsce"
},
{
"path": "data_splits/ScanNetv2/standard_split/scannetv2_train.txt",
"chars": 15613,
"preview": "scene0191_00\nscene0191_01\nscene0191_02\nscene0119_00\nscene0230_00\nscene0528_00\nscene0528_01\nscene0705_00\nscene0705_01\nsce"
},
{
"path": "data_splits/ScanNetv2/standard_split/scannetv2_val.txt",
"chars": 4056,
"preview": "scene0568_00\nscene0568_01\nscene0568_02\nscene0304_00\nscene0488_00\nscene0488_01\nscene0412_00\nscene0412_01\nscene0217_00\nsce"
},
{
"path": "data_splits/ScanNetv2/standard_split/test_eight_view_deepvmvs.txt",
"chars": 1765710,
"preview": "scene0718_00 000009 000000 000008 000004 000002 000003 000006 000007\nscene0718_00 000018 000000 000009 000008 000004 000"
},
{
"path": "data_splits/ScanNetv2/standard_split/test_eight_view_deepvmvs_offline.txt",
"chars": 1766331,
"preview": "scene0718_00 000009 000042 000000 000028 000050 000056 000061 000018\nscene0718_00 000018 000042 000028 000000 000050 000"
},
{
"path": "data_splits/ScanNetv2/standard_split/val_eight_view_deepvmvs.txt",
"chars": 6988665,
"preview": "scene0423_02 000417 000427 000436 000443 000454 000465 000474 000481\nscene0663_00 000501 000532 000580 000595 000613 000"
},
{
"path": "data_splits/arkit/scans.txt",
"chars": 20,
"preview": "neucon_demodata_b5f1"
},
{
"path": "data_splits/arkit/test_eight_view_deepvmvs.txt",
"chars": 87147,
"preview": "neucon_demodata_b5f1 00005 00000 00004 00001 00002 00003 00004 00001\nneucon_demodata_b5f1 00010 00000 00005 00004 00009 "
},
{
"path": "data_splits/arkit/test_eight_view_deepvmvs_dense.txt",
"chars": 365700,
"preview": "neucon_demodata_b5f1 00001 00000 00000 00000 00000 00000 00000 00000\nneucon_demodata_b5f1 00002 00000 00001 00001 00000 "
},
{
"path": "data_splits/vdr/scans.txt",
"chars": 17,
"preview": "living_room\nhouse"
},
{
"path": "data_splits/vdr/test_eight_view_deepvmvs.txt",
"chars": 33208,
"preview": "house 12 0 3 6 7 5 2 11\nhouse 17 0 12 10 3 13 11 1\nhouse 21 12 17 0 16 4 11 3\nhouse 25 21 12 17 0 1 16 3\nhouse 29 25 12 "
},
{
"path": "data_splits/vdr/test_eight_view_deepvmvs_dense.txt",
"chars": 93727,
"preview": "living_room 1 0 0 0 0 0 0 0\nliving_room 2 1 0 0 1 1 0 1\nliving_room 3 1 2 0 2 0 0 0\nliving_room 4 1 0 2 3 2 3 1\nliving_r"
},
{
"path": "data_splits/vdr/test_eight_view_deepvmvs_dense_offline.txt",
"chars": 94398,
"preview": "living_room 0 20 17 23 26 30 33 35\nliving_room 1 20 17 23 26 30 33 35\nliving_room 2 20 17 23 26 30 33 35\nliving_room 3 2"
},
{
"path": "experiment_modules/depth_model.py",
"chars": 30690,
"preview": "import logging\n\nimport pytorch_lightning as pl\nimport timm\nimport torch\nimport torch.nn.functional as F\nfrom losses impo"
},
{
"path": "losses.py",
"chars": 8068,
"preview": "import kornia\nimport torch\nimport torch.jit as jit\nimport torch.nn.functional as F\nfrom torch import Tensor, nn\n\nfrom ut"
},
{
"path": "modules/cost_volume.py",
"chars": 52342,
"preview": "import einops\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch import Tensor\n\nfrom modules."
},
{
"path": "modules/layers.py",
"chars": 4167,
"preview": "from typing import Callable, Optional\n\nimport torch.nn as nn\nfrom torch import Tensor\n\n\ndef conv3x3(\n in_plan"
},
{
"path": "modules/networks.py",
"chars": 7974,
"preview": "import antialiased_cnns\nfrom torchvision import models\nimport numpy as np\nimport timm\nimport torch\nfrom torch import nn\n"
},
{
"path": "options.py",
"chars": 15219,
"preview": "import argparse\nimport dataclasses\nimport os\nfrom dataclasses import dataclass\n\nimport yaml\n\n\n@dataclass\nclass Options()"
},
{
"path": "pc_fusion.py",
"chars": 7725,
"preview": "\"\"\" \n Fuses depth maps into point clouds using the PC fuser from \n https://github.com/alexrich021/3dvnet/blob/main"
},
{
"path": "pixi.toml",
"chars": 2525,
"preview": "[project]\nname = \"simplerecon\"\nversion = \"0.1.0\"\ndescription = \"Add a short description here\"\nauthors = [\"Pablo Vela <pa"
},
{
"path": "requirements.txt",
"chars": 307,
"preview": "torch==1.13.1\ntorchvision==0.14.1\nkornia==0.6.7\nantialiased-cnns\nefficientnet_pytorch\ntimm\ntrimesh\ntransforms3d\neinops\nm"
},
{
"path": "rerun_visualize_live_meshing.py",
"chars": 16199,
"preview": "import os\nimport pickle\nfrom pathlib import Path\n\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nimport"
},
{
"path": "simplerecon_env.yml",
"chars": 907,
"preview": "name: simplerecon\nchannels:\n - default\n - pytorch\n - conda-forge\ndependencies:\n - python=3.9.7\n - pytorch=1.10.0\n "
},
{
"path": "sr_datasets/arkit_dataset.py",
"chars": 26315,
"preview": "import json\nimport logging\nimport os\n\nimport numpy as np\nimport torch\nfrom sr_datasets.generic_mvs_dataset import Generi"
},
{
"path": "sr_datasets/colmap_dataset.py",
"chars": 22966,
"preview": "import functools\nimport logging\nimport os\n\nimport numpy as np\nimport torch\nfrom sr_datasets.generic_mvs_dataset import G"
},
{
"path": "sr_datasets/generic_mvs_dataset.py",
"chars": 26570,
"preview": "import logging\nimport os\nimport random\n\nimport numpy as np\nimport PIL.Image as pil\nimport torch\nfrom torch.utils.data im"
},
{
"path": "sr_datasets/scannet_dataset.py",
"chars": 23141,
"preview": "\nimport os\nimport numpy as np\nimport PIL.Image as pil\nimport torch\nfrom sr_datasets.generic_mvs_dataset import GenericMV"
},
{
"path": "sr_datasets/scanniverse_dataset.py",
"chars": 22134,
"preview": "import logging\nimport os\nimport re\nimport numpy as np\nimport PIL.Image as pil\nimport torch\nfrom scipy.spatial.transform "
},
{
"path": "sr_datasets/seven_scenes_dataset.py",
"chars": 20318,
"preview": "from doctest import debug_script\nfrom genericpath import exists\nimport os\nimport numpy as np\nimport PIL.Image as pil\nimp"
},
{
"path": "sr_datasets/vdr_dataset.py",
"chars": 22084,
"preview": "import functools\nimport json\nimport logging\nimport os\n\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nf"
},
{
"path": "test.py",
"chars": 21212,
"preview": "\"\"\" \n Predicts depth maps using a DepthModel model. Uses an MVS dataset from \n datasets.\n \n All results will"
},
{
"path": "tools/fusers_helper.py",
"chars": 7897,
"preview": "import numpy as np\nimport open3d as o3d\nimport torch\nimport trimesh\nfrom sr_datasets.scannet_dataset import ScannetDatas"
},
{
"path": "tools/keyframe_buffer.py",
"chars": 15064,
"preview": "\"\"\"\nMost of this is a modified version of code from the DeepVideoMVS repository \nat https://github.com/ardaduz/deep-vide"
},
{
"path": "tools/mesh_renderer.py",
"chars": 18727,
"preview": "import os\n\nos.environ[\"PYOPENGL_PLATFORM\"] = \"egl\"\n\nimport sys\nimport numpy as np\nimport pyrender\nimport trimesh\nimport "
},
{
"path": "tools/torch_point_cloud_fusion.py",
"chars": 4974,
"preview": "\"\"\"\n This is borrowed from https://github.com/alexrich021/3dvnet/blob/main/mv3d/eval/pointcloudfusion_custom.py\n\"\"\"\n\n"
},
{
"path": "tools/tsdf.py",
"chars": 12328,
"preview": "import os\nfrom typing import Tuple\n\nimport numpy as np\nimport torch\nimport torch.nn.functional as TF\nimport trimesh\nfrom"
},
{
"path": "train.py",
"chars": 6174,
"preview": "\"\"\" \n Trains a DepthModel model. Uses an MVS dataset from datasets.\n\n - Outputs logs and checkpoints to opts.log_d"
},
{
"path": "utils/dataset_utils.py",
"chars": 4794,
"preview": "from sr_datasets.colmap_dataset import ColmapDataset\nfrom sr_datasets.arkit_dataset import ARKitDataset\nfrom sr_datasets"
},
{
"path": "utils/generic_utils.py",
"chars": 9641,
"preview": "import logging\nimport os\nimport pickle\nfrom pathlib import Path\n\nimport kornia\nimport torch\nimport torchvision.transform"
},
{
"path": "utils/geometry_utils.py",
"chars": 7872,
"preview": "import kornia\nimport numpy as np\nimport torch\nimport torch.jit as jit\nimport torch.nn.functional as F\nfrom torch import "
},
{
"path": "utils/metrics_utils.py",
"chars": 9568,
"preview": "import json\n\nimport numpy as np\nimport torch\n\n\ndef compute_depth_metrics(gt, pred, mult_a=False):\n \"\"\"\n Computes e"
},
{
"path": "utils/visualization_utils.py",
"chars": 6260,
"preview": "import os\n\nimport matplotlib.pyplot as plt\nimport moviepy.editor as mpy\nimport numpy as np\nimport torch\nfrom PIL import "
},
{
"path": "visualization_scripts/generate_gt_min_max_cache.py",
"chars": 4462,
"preview": "\"\"\" \n Loops through an MVS dataset, and extracts smoothed max and min values \n across a scene. Saves those values "
},
{
"path": "visualization_scripts/load_meshes_and_include_normals.py",
"chars": 4075,
"preview": "\"\"\" \n Reads plys defined with pattern in scans_path_pattern. First computes \n normals for each scan using open3d, "
},
{
"path": "visualization_scripts/visualize_scene_depth_output.py",
"chars": 15614,
"preview": "\"\"\" \n Loops through precomputed saved depth maps and associated RGB and groundtruth images, \n and generates side b"
},
{
"path": "visualize_live_meshing.py",
"chars": 18120,
"preview": "import os\nimport pickle\nfrom pathlib import Path\n\nimport numpy as np\nimport pyrender\nimport torch\nimport torch.nn.functi"
},
{
"path": "weights/strip_checkpoint.py",
"chars": 737,
"preview": "# for importing options on checkpoint load.\nimport sys\nsys.path.append(\"/\".join(sys.path[0].split(\"/\")[:-1])) \n\nimport t"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the rerun-io/simplerecon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 92 files (49.9 MB), approximately 3.2M tokens, and a symbol index with 370 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.