First of all, thanks for the great work. In the paper and project page the authors mention scaling PixSfM to thousands of images. I'm however running into issues doing the same with datasets ranging in the 1600-3000 image range. Two of the datasets in question can be found at: https://meganerf.cmusatyalab.org/#data
My code looks roughly like:
def main(hparams: Namespace) -> None:
output_path = Path(hparams.output_path)
output_path.mkdir(exist_ok=True, parents=True)
feature_conf = extract_features.confs['superpoint_max']
matcher_conf = match_features.confs['superglue']
images_path = Path(hparams.images_path)
images = sorted(images_path.iterdir())
references = [str(images[i].relative_to(images_path)) for i in range(len(images))]
print(len(references), 'mapping images')
features_path = output_path / 'features.h5'
sfm_pairs_path = output_path / 'pairs-sfm.txt'
matches_path = output_path / 'matches.h5'
extract_features.main(feature_conf, images_path, image_list=references, feature_path=features_path)
pairs_from_gps.main(sfm_pairs_path, images_path, references, 50) # Custom matcher that uses the GPS metadata to match only to the 50 closest pairs
match_features.main(matcher_conf, sfm_pairs_path, features=features_path, matches=matches_path)
sfm = PixSfM(conf={"dense_features": {"use_cache": True}})
ref_dir = output_path / 'ref'
refined, sfm_outputs = sfm.reconstruction(ref_dir, images_path, sfm_pairs_path, features_path, matches_path,
image_list=references)
And in particular the keypoint adjustment phase seems to be taking a very long time. Some examples so far:
1678 mapping images
[2022/02/04 18:28:11 pixsfm.features.models.s2dnet INFO] Loading S2DNet checkpoint at /home/ubuntu/pixel-perfect-sfm/pixsfm/features/models/checkpoints/s2dnet_weights.pth.
[2022/02/04 18:28:25 pixsfm INFO] Loaded dense extractor with configuration:
{'cache_format': 'chunked',
'device': 'auto',
'dtype': 'half',
'fast_image_load': False,
'l2_normalize': True,
'load_cache_on_init': False,
'max_edge': 1600,
'model': {'name': 's2dnet', 'num_layers': 1, 'checkpointing': None, 'output_dim': 128, 'pretrained': 's2dnet', 'remove_pooling_layers': False, 'combine': False},
'overwrite_cache': False,
'patch_size': 16,
'pyr_scales': [1.0],
'resize': 'LANCZOS',
'sparse': True,
'use_cache': True} [2022/02/04 18:29:52 pixsfm INFO] Building matching graph...
[2022/02/04 18:31:00 pixsfm INFO] Extracting dense features...
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1678/1678 [1:05:39<00:00, 2.35s/it]|
[2022/02/04 19:36:40 pixsfm INFO] Loading featuremaps from H5 File.
100%[████████████████████] 1678/1678 [00:51, 32.4514it/s]
[2022/02/04 19:37:32 pixsfm INFO] Computing tracks...
[2022/02/04 19:37:32 pixsfm INFO] # graph nodes: 6001799
[2022/02/04 19:37:38 pixsfm INFO] # graph edges: 87565132
[2022/02/04 19:39:26 pixsfm INFO] # tracks: 655998
[2022/02/04 19:39:31 pixsfm INFO] Start feature-metric keypoint adjustment.
[2022/02/04 19:39:35 pixsfm WARNING] 13887 / 115040 problems have more than 50 keypoints.
Maximum keypoints in a problem: 202
74%[███████████████ ] 4484836/6001799 [171:56:55, 7.24511it/s]
Another example seems to be getting slower over time:
[2022/02/05 12:35:10 pixsfm INFO] Loading featuremaps from H5 File.
1940 mapping images
[2022/02/05 11:47:44 pixsfm.features.models.s2dnet INFO] Loading S2DNet checkpoint at /data/hturki/pixel-perfect-sfm/pixsfm/features/models/checkpoints/s2dnet_weights.pth.
[2022/02/05 11:47:44 pixsfm.features.models.s2dnet INFO] Downloading S2DNet weights.
[2022/02/05 11:47:51 pixsfm INFO] Loaded dense extractor with configuration:
{'cache_format': 'chunked',
'device': 'auto',
'dtype': 'half',
'fast_image_load': False,
'l2_normalize': True,
'load_cache_on_init': False,
'max_edge': 1600,
'model': {'name': 's2dnet', 'num_layers': 1, 'checkpointing': None, 'output_dim': 128, 'pretrained': 's2dnet', 'remove_pooling_layers': False, 'combine': False},
'overwrite_cache': False,
'patch_size': 16,
'pyr_scales': [1.0],
'resize': 'LANCZOS',
'sparse': True,
'use_cache': True}
[2022/02/05 11:48:51 pixsfm INFO] Building matching graph...
[2022/02/05 11:50:23 pixsfm INFO] Extracting dense features...
100%[████████████████████] 1938/1938 [00:10, 183.748it/s]
[2022/02/05 12:35:21 pixsfm INFO] Computing tracks...
[2022/02/05 12:35:21 pixsfm INFO] # graph nodes: 6696955
[2022/02/05 12:35:28 pixsfm INFO] # graph edges: 84325871
[2022/02/05 12:38:06 pixsfm INFO] # tracks: 761986
[2022/02/05 12:38:13 pixsfm INFO] Start feature-metric keypoint adjustment.
[2022/02/05 12:38:19 pixsfm WARNING] 16060 / 125998 problems have more than 50 keypoints.
Maximum keypoints in a problem: 265
0%[ ] 59491/6696955 [01:18:26, 12.6392it/s]
10%[██ ] 729223/6696955 [23:18:52, 8.68822it/s]
10%[██ ] 729290/6696955 [23:19:05, 8.68761it/s]
25%[█████ ] 1718493/6696955 [70:43:00, 6.75028it/s]
27%[██████ ] 1830843/6696955 [76:13:28, 6.67195it/s]
41%[████████ ] 2765893/6696955 [121:42:58, 6.31225it/s]
49%[██████████ ] 3347643/6696955 [150:00:06, 6.19926it/s]
And same for a third example
3019 mapping images
[2022/02/06 12:12:32 pixsfm.features.models.s2dnet INFO] Loading S2DNet checkpoint at /home/cloudlet/hturki/pixel-perfect-sfm/pixsfm/features/models/checkpoints/s2dnet_weights.pth.
[2022/02/06 12:12:36 pixsfm INFO] Loaded dense extractor with configuration:
{'cache_format': 'chunked',
'device': 'auto',
'dtype': 'half',
'fast_image_load': False,
'l2_normalize': True,
'load_cache_on_init': False,
'max_edge': 1600,
'model': {'name': 's2dnet', 'num_layers': 1, 'checkpointing': None, 'output_dim': 128, 'pretrained': 's2dnet', 'remove_pooling_layers': False, 'combine': False},
'overwrite_cache': False,
'patch_size': 16,
'pyr_scales': [1.0],
'resize': 'LANCZOS',
'sparse': True,
'use_cache': True}
[2022/02/06 12:14:03 pixsfm INFO] Building matching graph...
[2022/02/06 12:16:14 pixsfm INFO] Extracting dense features...
5%|██████████▏ | 153/ 5%|██████████▎ | 154/ 5%|██████████▎ 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3019/3019 [1:08:49<00:00, 1.37s/it]
[2022/02/06 13:25:03 pixsfm INFO] Loading featuremaps from H5 File.
100%[████████████████████] 3019/3019 [00:17, 172.998it/s]
[2022/02/06 13:25:21 pixsfm INFO] Computing tracks...
[2022/02/06 13:25:21 pixsfm INFO] # graph nodes: 11090098
[2022/02/06 13:25:27 pixsfm INFO] # graph edges: 122388899
[2022/02/06 13:34:55 pixsfm INFO] # tracks: 834854
[2022/02/06 13:35:05 pixsfm INFO] Start feature-metric keypoint adjustment.
[2022/02/06 13:35:13 pixsfm WARNING] 41539 / 141697 problems have more than 50 keypoints.
Maximum keypoints in a problem: 1022
0%[ ] 28755/11090098 [12:26, 38.5155it/s]
0%[ ] 42692/11090098 [29:23, 24.2052it/s]
0%[ ] 62858/11090098 [50:21, 20.8059it/s]
16%[███ ] 1884721/11090098 [23:21:01, 22.4207it/s]
37%[████████ ] 4142028/11090098 [78:01:34, 14.7458it/s]
45%[█████████ ] 5016151/11090098 [114:52:32, 12.1294it/s]
46%[█████████ ] 5208388/11090098 [125:06:01, 11.5649it/s]
The specs for the machines across each of these runs varies a bit, but they're pretty powerful machines (>100GB of ram, dozens of cores, SSD mounts)
I've also tried running PixSfM on an even larger example (matching only against the 20 closest neighbors instead of 50), where keypoint adjustment throws an exception. I've trying reducing the output dim and patch size to no avail:
5871 mapping images
[2022/02/11 08:29:37 hloc INFO] Extracting local features with configuration:
{'model': {'max_keypoints': 4096, 'name': 'superpoint', 'nms_radius': 3},
'output': 'feats-superpoint-n4096-rmax1600',
'preprocessing': {'grayscale': True, 'resize_force': True, 'resize_max': 1600}}
Loaded SuperPoint model
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5871/5871 [16:57<00:00, 5.77it/s]
[2022/02/11 08:46:38 hloc INFO] Finished exporting features.
[2022/02/11 08:46:41 hloc INFO] Obtaining pairwise distances between 5871 images...
[2022/02/11 08:46:43 hloc INFO] Found 117230 pairs.
[2022/02/11 08:46:43 hloc INFO] Matching local features with configuration:
{'model': {'name': 'superglue',
'sinkhorn_iterations': 50,
'weights': 'outdoor'},
'output': 'matches-superglue'}
Loaded SuperGlue model ("outdoor" weights)
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 117230/117230 [6:16:43<00:00, 5.19it/s]
[2022/02/11 15:03:29 hloc INFO] Finished exporting matches.
[2022/02/11 15:03:31 pixsfm.features.models.s2dnet INFO] Loading S2DNet checkpoint at /compute/autobot-1-1/hturki/pixel-perfect-sfm/pixsfm/features/models/checkpoints/s2dnet_weights.pth.
[2022/02/11 15:03:31 pixsfm INFO] Loaded dense extractor with configuration:
{'cache_format': 'chunked',
'device': 'auto',
'dtype': 'half',
'fast_image_load': False,
'l2_normalize': True,
'load_cache_on_init': False,
'max_edge': 1600,
'model': {'name': 's2dnet', 'num_layers': 1, 'checkpointing': None, 'output_dim': 64, 'pretrained': 's2dnet', 'remove_pooling_layers': False, 'combine': False, 'patch_size': 8},
'overwrite_cache': False,
'patch_size': 8,
'pyr_scales': [1.0],
'resize': 'LANCZOS',
'sparse': True,
'use_cache': True} # Have also tried keeping everything in memory
[2022/02/11 15:04:33 pixsfm INFO] Building matching graph...
[2022/02/11 15:07:55 pixsfm INFO] Extracting dense features...
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5871/5871 [45:08<00:00, 2.17it/s]
[2022/02/11 15:53:04 pixsfm INFO] Computing tracks...
[2022/02/11 15:53:04 pixsfm INFO] # graph nodes: 21615817
[2022/02/11 15:53:12 pixsfm INFO] # graph edges: 106782076
[2022/02/11 15:55:08 pixsfm INFO] # tracks: 2955327
[2022/02/11 15:55:28 pixsfm INFO] Start feature-metric keypoint adjustment.
[2022/02/11 15:55:52 pixsfm WARNING] 206052 / 906513 problems have more than 20 keypoints.
Maximum keypoints in a problem: 487
0%[ ] 0/21615817 [00:00, -nanit/s][2022/02/11 15:56:13 pixsfm ERROR] Child process threw exception in problem 0.
Any thoughts on what I might be doing wrong, or is a week+ runtime to be expected no matter what? I've gotten suboptimal results on these (drone imagery-related) datasets using even commercial photogrammetry software, so excited to see if I can get better results with your featuremetric approach!