Skip to content

Commit 0f9b909

Browse files
committedMay 30, 2024
add hypersim
1 parent b26dc96 commit 0f9b909

20 files changed

+14271
-20
lines changed
 

‎README.md

+37
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,43 @@ You will need to update the data configs to point to the location of your
2828
ScanNetv2 data. You can do this by setting `dataset_path: <YOUR_DATA_LOCATION>` in the six
2929
`configs/data/scannet_*.yaml` files.
3030

31+
# Hypersim
32+
33+
To Download the Hypersim dataset, please follow the the intructions in the [Hypersim Datatset](https://github.com/apple/ml-hypersim) repo.
34+
35+
Once the dataset has been downloaded and extracted, please update the `dataset_path` argument for Hypersim data configs in `configs/data/` to point to the extracted dataset.
36+
37+
Note that the depth maps provided as part of the dataset are not planar depths and need to be planarised. We have provided helper functions to planarise the depth maps (see `_get_prependicular_depths` method in `datasets/hypersim_dataset.py`). The planarised depth maps can be generated with the help of the `data_scripts/generate_hypersim_planar_depths.py` script:
38+
39+
```bash
40+
# train
41+
python ./data_scripts/generate_hypersim_planar_depths.py \
42+
--data_config configs/data/hypersim_default_train.yaml \
43+
--num_workers 8
44+
45+
# val
46+
python ./data_scripts/generate_hypersim_planar_depths.py \
47+
--data_config configs/data/hypersim_default_val.yaml \
48+
--num_workers 8
49+
```
50+
51+
Next, we need to generate the frame tuples similarly to ScanNetv2 dataset:
52+
53+
```bash
54+
# train
55+
python ./data_scripts/generate_train_tuples.py
56+
--data_config configs/data/hypersim_default_train.yaml
57+
--num_workers 8
58+
59+
# val
60+
python ./data_scripts/generate_val_tuples.py
61+
--data_config configs/data/hypersim_default_val.yaml
62+
--num_workers 8
63+
```
64+
65+
After the tuple generation, you should be ready to train on hypersim using the provided configs!
66+
67+
We provide the train and val splits we used for our experiments (see `data_splits/hypersim/bd_split/train_files_bd.json` and `data_splits/hypersim/bd_split/val_files_bd.json`)
3168
## 📦 Models
3269

3370
We provide the following pretrained models for you to try out - we suggest using the HyperSim trained model to obtain the best qualitative results.
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
!!python/object:options.Options
2+
dataset_path: /mnt/nas3/shared/datasets/hypersim
3+
tuple_info_file_location: data_splits/hypersim/standard_split/
4+
dataset_scan_split_file: data_splits/hypersim/standard_split/test_files_all.json
5+
dataset: hypersim
6+
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
7+
num_images_in_tuple: 8
8+
frame_tuple_type: default
9+
split: test
10+
use_min_max_depth: True
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
!!python/object:options.Options
2+
dataset_path: /mnt/nas3/shared/datasets/hypersim/
3+
tuple_info_file_location: data_splits/hypersim/bd_split/
4+
dataset_scan_split_file: data_splits/hypersim/bd_split/train_files_bd.json
5+
dataset: hypersim
6+
mv_tuple_file_suffix: _eight_view_deepvmvs_bd.txt
7+
num_images_in_tuple: 8
8+
frame_tuple_type: default
9+
split: train
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
!!python/object:options.Options
2+
dataset_path: /mnt/nas3/shared/datasets/hypersim/
3+
tuple_info_file_location: data_splits/hypersim/bd_split/
4+
dataset_scan_split_file: data_splits/hypersim/bd_split/val_files_bd.json
5+
dataset: hypersim
6+
mv_tuple_file_suffix: _eight_view_deepvmvs_bd.txt
7+
num_images_in_tuple: 8
8+
frame_tuple_type: default
9+
split: val
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
!!python/object:options.Options
2+
feature_volume_type: mlp_feature_volume
3+
batch_size: 12
4+
cost_volume_aggregation: dot
5+
cv_encoder_type: multi_scale_encoder
6+
depth_decoder_name: unet_pp
7+
gpus: 2
8+
image_encoder_name: efficientnet
9+
log_interval: 100
10+
val_interval: 400
11+
loss_type: log_l1
12+
lr: 0.0001
13+
wd: 0.0001
14+
matching_encoder_type: resnet
15+
name: implicit_depth
16+
num_sanity_val_steps: 0
17+
num_workers: 12
18+
precision: 16
19+
random_seed: 0
20+
full_depth_supervision: true
21+
lr_steps: [18000, 36000]
22+
max_steps: 50000
23+
lazy_load_weights_from_checkpoint: weights/regression.ckpt
24+
near_surface_ratio: 0.25
25+
bd_regularisation_weight: 0.5
26+
binary_loss_positive_weight: 1.0
27+
bd_edge_regularision: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
!!python/object:options.Options
2+
feature_volume_type: mlp_feature_volume
3+
batch_size: 12
4+
cost_volume_aggregation: dot
5+
cv_encoder_type: multi_scale_encoder
6+
depth_decoder_name: unet_pp
7+
gpus: 2
8+
image_encoder_name: efficientnet
9+
log_interval: 100
10+
val_interval: 400
11+
loss_type: log_l1
12+
lr: 0.0001
13+
wd: 0.0001
14+
matching_encoder_type: resnet
15+
name: hero_model_bd_temporal
16+
num_sanity_val_steps: 0
17+
num_workers: 12
18+
precision: 16
19+
random_seed: 0
20+
full_depth_supervision: true
21+
lr_steps: [18000, 36000]
22+
max_steps: 14000
23+
lazy_load_weights_from_checkpoint: sr_bd.ckpt
24+
near_surface_ratio: 0.25
25+
bd_regularisation_weight: 0.5
26+
binary_loss_positive_weight: 1.0
27+
bd_edge_regularision: false
28+
use_prior: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
!!python/object:options.Options
2+
feature_volume_type: mlp_feature_volume
3+
batch_size: 16
4+
cost_volume_aggregation: dot
5+
cv_encoder_type: multi_scale_encoder
6+
depth_decoder_name: unet_pp
7+
gpus: 2
8+
image_encoder_name: efficientnet
9+
log_interval: 100
10+
val_interval: 300
11+
loss_type: log_l1
12+
lr: 0.0001
13+
wd: 0.0001
14+
matching_encoder_type: resnet
15+
name: regression
16+
num_sanity_val_steps: 0
17+
num_workers: 12
18+
precision: 16
19+
random_seed: 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
"""Script for generating planar depth maps for the Hypersim Dataset
2+
3+
Run like so for generating/saving depth maps to dataset_path defined in the yaml:
4+
5+
python ./data_scripts/generate_hypersim_planar_depths.py
6+
--data_config configs/data/hypersim_default_train.yaml
7+
--num_workers 8
8+
9+
where hypersim_default_train.yaml looks like:
10+
!!python/object:options.Options
11+
dataset_path: HYPERSIM_PATH/
12+
tuple_info_file_location: $tuples_directory$
13+
dataset_scan_split_file: $train_split_list_location$
14+
dataset: hypersim
15+
mv_tuple_file_suffix: _eight_view_deepvmvs.txt
16+
num_images_in_tuple: 8
17+
frame_tuple_type: default
18+
split: train
19+
20+
For val, use configs/data/hypersim_default_val.yaml.
21+
22+
This script will save the planar depth maps in the following pattern:
23+
{dataset_path}/"data"
24+
/ {scene}
25+
/ "images"
26+
/ f"scene_{cam}_geometry_hdf5"
27+
/ f"frame.{int(frame_id):04d}.depth_meters_planar.hdf5"
28+
29+
"""
30+
import sys
31+
32+
sys.path.append("/".join(sys.path[0].split("/")[:-1]))
33+
34+
from functools import partial
35+
from multiprocessing import Manager
36+
from multiprocessing.pool import Pool
37+
38+
import options
39+
from utils.dataset_utils import get_dataset
40+
41+
42+
def crawl_subprocess(opts, scan, count, progress):
43+
"""
44+
Generates and saves planar depth maps to disk for a given scene
45+
46+
Args:
47+
scan: scan to operate on.
48+
count: total count of multi process scans.
49+
progress: a Pool() progress value for tracking progress. For debugging
50+
you can pass
51+
multiprocessing.Manager().Value('i', 0)
52+
for this.
53+
54+
"""
55+
56+
print(f"Generating planar depths for scene {scan}")
57+
58+
# get dataset
59+
dataset_class, _ = get_dataset(
60+
opts.dataset, opts.dataset_scan_split_file, opts.single_debug_scan_id, verbose=False
61+
)
62+
63+
ds = dataset_class(
64+
dataset_path=opts.dataset_path,
65+
mv_tuple_file_suffix=None,
66+
split=opts.split,
67+
tuple_info_file_location=opts.tuple_info_file_location,
68+
pass_frame_id=True,
69+
verbose_init=False,
70+
)
71+
72+
frame_ids = ds._get_frame_ids(opts.split, scan)
73+
for frame_ind in frame_ids:
74+
ds._save_prependicular_depths_to_disk(scan, frame_ind)
75+
76+
progress.value += 1
77+
print(f"Completed scan {scan}, {progress.value} of total {count}\r")
78+
79+
80+
def crawl(opts, scans):
81+
"""
82+
Multiprocessing helper for crawl_subprocess
83+
84+
Args:
85+
opts: options dataclass.
86+
scans: scans to multiprocess.
87+
88+
"""
89+
pool = Pool(opts.num_workers)
90+
manager = Manager()
91+
92+
count = len(scans)
93+
progress = manager.Value("i", 0)
94+
95+
crawler = crawl_subprocess
96+
97+
pool.imap_unordered(
98+
partial(crawler, opts, count=count, progress=progress),
99+
scans,
100+
)
101+
pool.close()
102+
# wait for all issued task to complete
103+
pool.join()
104+
105+
106+
if __name__ == "__main__":
107+
# load options file
108+
option_handler = options.OptionsHandler()
109+
option_handler.parse_and_merge_options(ignore_cl_args=False)
110+
option_handler.pretty_print_options()
111+
opts = option_handler.options
112+
113+
# get dataset
114+
dataset_class, scan_names = get_dataset(
115+
opts.dataset, opts.dataset_scan_split_file, opts.single_debug_scan_id, verbose=False
116+
)
117+
118+
if opts.single_debug_scan_id is not None:
119+
crawler = crawl_subprocess
120+
crawler(
121+
opts,
122+
opts.single_debug_scan_id,
123+
0,
124+
Manager().Value("i", 0),
125+
)
126+
else:
127+
crawl(opts, scan_names)

‎data_scripts/generate_train_tuples.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
import numpy as np
5050

5151
import options
52-
from tools.keyframe_buffer import DVMVS_Config, is_valid_pair
52+
from datasets.hypersim_dataset import HypersimDataset
53+
from tools.keyframe_buffer import DVMVS_Config, DVMVS_Hypersim_Config, is_valid_pair
5354
from utils.dataset_utils import get_dataset
5455

5556

@@ -177,6 +178,11 @@ def crawl_subprocess_short(opts_temp_filepath, scan, count, progress):
177178
verbose_init=False,
178179
)
179180

181+
if opts.dataset == "hypersim":
182+
keyframe_config = DVMVS_Hypersim_Config
183+
else:
184+
keyframe_config = DVMVS_Config
185+
180186
valid_frames = ds.get_valid_frame_ids(opts.split, scan)
181187

182188
frame_ind_to_frame_id = {}
@@ -197,8 +203,8 @@ def crawl_subprocess_short(opts_temp_filepath, scan, count, progress):
197203
poses,
198204
used_pairs,
199205
is_backward=multiplier[1],
200-
initial_pose_dist_min=(multiplier[0] * DVMVS_Config.train_minimum_pose_distance),
201-
initial_pose_dist_max=(multiplier[0] * DVMVS_Config.train_maximum_pose_distance),
206+
initial_pose_dist_min=(multiplier[0] * keyframe_config.train_minimum_pose_distance),
207+
initial_pose_dist_max=(multiplier[0] * keyframe_config.train_maximum_pose_distance),
202208
)
203209

204210
for pair in pairs:
@@ -267,6 +273,11 @@ def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
267273
verbose_init=False,
268274
)
269275

276+
if opts.dataset == "hypersim":
277+
keyframe_config = DVMVS_Hypersim_Config
278+
else:
279+
keyframe_config = DVMVS_Config
280+
270281
valid_frames = ds.get_valid_frame_ids(opts.split, scan)
271282

272283
frame_ind_to_frame_id = {}
@@ -289,7 +300,7 @@ def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
289300
for i in range(sequence_length):
290301
used_nodes[i] = 0
291302

292-
calculated_step = DVMVS_Config.train_crawl_step
303+
calculated_step = keyframe_config.train_crawl_step
293304
samples = []
294305
for offset, multiplier, is_backward in [
295306
(0 % calculated_step, 1.0, False),
@@ -338,10 +349,10 @@ def crawl_subprocess_long(opts_temp_filepath, scan, count, progress):
338349
check3 = is_valid_pair(
339350
poses[previous_index],
340351
poses[current_index],
341-
(multiplier * DVMVS_Config.train_minimum_pose_distance),
342-
(multiplier * DVMVS_Config.train_maximum_pose_distance),
352+
(multiplier * keyframe_config.train_minimum_pose_distance),
353+
(multiplier * keyframe_config.train_maximum_pose_distance),
343354
t_norm_threshold=(
344-
multiplier * DVMVS_Config.train_minimum_pose_distance * 0.5
355+
multiplier * keyframe_config.train_minimum_pose_distance * 0.5
345356
),
346357
)
347358

‎data_splits/hypersim/bd_split/train_eight_view_deepvmvs_bd.txt

+11,572
Large diffs are not rendered by default.

‎data_splits/hypersim/bd_split/train_files_bd.json

+1
Large diffs are not rendered by default.

‎data_splits/hypersim/bd_split/val_eight_view_deepvmvs_bd.txt

+1,543
Large diffs are not rendered by default.

‎data_splits/hypersim/bd_split/val_files_bd.json

+1
Large diffs are not rendered by default.

‎data_splits/hypersim/standard_split/test_files_all.json

+1
Large diffs are not rendered by default.

‎data_splits/hypersim/standard_split/train_files_all.json

+1
Large diffs are not rendered by default.

‎data_splits/hypersim/standard_split/val_files_all.json

+1
Large diffs are not rendered by default.

‎datasets/hypersim_dataset.py

+828
Large diffs are not rendered by default.

‎experiment_modules/depth_model.py

+22-13
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ def __init__(self, opts):
173173

174174
# all the losses
175175
self.si_loss = ScaleInvariantLoss()
176-
self.grad_loss = MSGradientLoss()
177176
self.abs_loss = nn.L1Loss()
177+
self.grad_loss = MSGradientLoss()
178178
self.normals_loss = NormalsLoss()
179179
self.mv_depth_loss = MVDepthLoss(
180180
self.run_opts.image_height // 2,
@@ -495,25 +495,34 @@ def compute_losses(self, cur_data, src_data, outputs):
495495
if not found_scale:
496496
raise Exception("Could not find a valid scale to compute si loss!")
497497

498-
grad_loss = self.grad_loss(depth_gt, depth_pred)
498+
if self.run_opts.dataset == "hypersim":
499+
grad_loss = 0
500+
else:
501+
grad_loss = self.grad_loss(depth_gt, depth_pred)
499502
abs_loss = self.abs_loss(depth_gt[mask_b], depth_pred[mask_b])
500503
si_loss = self.si_loss(log_depth_gt[mask_b], log_depth_pred[mask_b])
501504

502505
mask_b_limit = torch.logical_and(mask_b, depth_pred > 0.1)
503506
inv_abs_loss = self.abs_loss(1 / depth_gt[mask_b_limit], 1 / depth_pred[mask_b_limit])
504507

505508
log_l1_loss = self.abs_loss(log_depth_gt[mask_b], log_depth_pred[mask_b])
506-
normals_loss = self.normals_loss(normals_gt, normals_pred)
507-
508-
mv_loss = self.mv_depth_loss(
509-
depth_pred_b1hw=depth_pred,
510-
cur_depth_b1hw=depth_gt,
511-
src_depth_bk1hw=src_data["depth_b1hw"],
512-
cur_invK_b44=cur_data[f"invK_s0_b44"],
513-
src_K_bk44=src_data[f"K_s0_b44"],
514-
cur_world_T_cam_b44=cur_data["world_T_cam_b44"],
515-
src_cam_T_world_bk44=src_data["cam_T_world_b44"],
516-
)
509+
if self.run_opts.dataset == "hypersim":
510+
normals_loss = 0
511+
else:
512+
normals_loss = self.normals_loss(normals_gt, normals_pred)
513+
514+
if self.run_opts.dataset == "hypersim":
515+
mv_loss = 0
516+
else:
517+
mv_loss = self.mv_depth_loss(
518+
depth_pred_b1hw=depth_pred,
519+
cur_depth_b1hw=depth_gt,
520+
src_depth_bk1hw=src_data["depth_b1hw"],
521+
cur_invK_b44=cur_data[f"invK_s0_b44"],
522+
src_K_bk44=src_data[f"K_s0_b44"],
523+
cur_world_T_cam_b44=cur_data["world_T_cam_b44"],
524+
src_cam_T_world_bk44=src_data["cam_T_world_b44"],
525+
)
517526

518527
loss = ms_loss + 1.0 * grad_loss + 1.0 * normals_loss + 0.2 * mv_loss
519528

‎tools/keyframe_buffer.py

+13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ class DVMVS_Config:
2222
test_optimal_R_measure = 0.0
2323

2424

25+
class DVMVS_Hypersim_Config:
26+
# train tuple settings
27+
train_minimum_pose_distance = 0.125
28+
train_maximum_pose_distance = 2.5
29+
train_crawl_step = 3
30+
31+
# test tuple settings
32+
test_keyframe_buffer_size = 30
33+
test_keyframe_pose_distance = 0.1
34+
test_optimal_t_measure = 0.15
35+
test_optimal_R_measure = 0.0
36+
37+
2538
def is_pose_available(pose):
2639
is_nan = np.isnan(pose).any()
2740
is_inf = np.isinf(pose).any()

‎utils/dataset_utils.py

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
from datasets.scanniverse_dataset import ScanniverseDataset
77
from datasets.seven_scenes_dataset import SevenScenesDataset
88
from datasets.vdr_dataset import VDRDataset
9+
from datasets.scanniverse_dataset import ScanniverseDataset
10+
from datasets.hypersim_dataset import HypersimDataset
11+
12+
import json
913

1014

1115
def get_dataset(dataset_name, split_filepath, single_debug_scan_id=None, verbose=True):

0 commit comments

Comments
 (0)
Please sign in to comment.