Skip to content

Commit 39cd752

Browse files
committed
Add option to match only n consecutive images
1 parent cd1f7cd commit 39cd752

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed

bin/match_features

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,36 @@ def distance_from_exif(exif1, exif2):
3131
return 0
3232

3333

34-
def match_candidates_from_gps(images, exifs, data):
35-
'''Compute candidate matching pairs based on GPS position
34+
def timediff_from_exif(exif1, exif2):
35+
return np.fabs(exif1['capture_time'] - exif2['capture_time'])
36+
37+
38+
def match_candidates_from_metadata(images, exifs, data):
39+
'''Compute candidate matching pairs based on GPS and capture time
3640
'''
37-
max_distance = data.config.get('matching_gps_distance', 9999999)
38-
max_neighbors = data.config.get('matching_gps_neighbors', 0)
41+
max_distance = data.config['matching_gps_distance']
42+
max_neighbors = data.config['matching_gps_neighbors']
43+
max_time_neighbors = data.config['matching_time_neighbors']
3944

4045
pairs = set()
4146
for im1 in images:
4247
distances = []
48+
timediffs = []
4349
for im2 in images:
4450
if im1 != im2:
45-
d = distance_from_exif(exifs.get(im1), exifs.get(im2))
46-
if d <= max_distance:
47-
distances.append((d, im2))
48-
if max_neighbors:
49-
distances.sort()
51+
dx = distance_from_exif(exifs[im1], exifs[im2])
52+
dt = timediff_from_exif(exifs[im1], exifs[im2])
53+
if dx <= max_distance:
54+
distances.append((dx, im2))
55+
timediffs.append((dt, im2))
56+
distances.sort()
57+
timediffs.sort()
58+
59+
if max_neighbors or max_time_neighbors:
5060
distances = distances[:max_neighbors]
51-
for d, im2 in distances:
61+
timediffs = timediffs[:max_time_neighbors]
62+
63+
for d, im2 in distances + timediffs:
5264
if im1 < im2:
5365
pairs.add((im1, im2))
5466
else:
@@ -146,7 +158,7 @@ if __name__ == "__main__":
146158
f_pre[image] = f_pre[image][:preemptive_max,:]
147159

148160
exifs = { im: data.load_exif(im) for im in images }
149-
pairs = match_candidates_from_gps(images, exifs, data)
161+
pairs = match_candidates_from_metadata(images, exifs, data)
150162

151163
num_pairs = 0
152164
for im, c in pairs.items():

config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Metadata
22
use_exif_size: yes
3+
default_focal_prior: 0.85
34

45
# Params for features
56
feature_type: HAHOG # Feature type (AKAZE, SURF, SIFT)
@@ -45,6 +46,7 @@ flann_checks: 200 # Smaller -> Faster (but might lose good matches)
4546
# Params for preemtive matching
4647
matching_gps_distance: 150 # Maximum gps distance between two images for matching
4748
matching_gps_neighbors: 0 # Number of images to match selected by GPS distance. Set to 0 to use no limit
49+
matching_time_neighbors: 0 # Number of images to match selected by time taken. Set to 0 to use no limit
4850
preemptive_max: 200 # Number of features to use for preemptive matching
4951
preemptive_threshold: 0 # If number of matches passes the threshold -> full feature matching
5052

@@ -57,6 +59,8 @@ triangulation_threshold: 0.006 # Outlier threshold (in pixels) for accept
5759
triangulation_min_ray_angle: 1.0
5860
resection_threshold: 0.004 # Outlier threshold (in pixels) for camera resection.
5961
resection_min_inliers: 10 # Minimum number of resection inliers to accept it.
62+
retriangulation: no
63+
retriangulation_ratio: 1.25
6064

6165
# Params for track creation
6266
min_track_length: 2 # Minimum number of features/images per track

opensfm/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
# Params for preemtive matching
5151
matching_gps_distance: 150 # Maximum gps distance between two images for matching
5252
matching_gps_neighbors: 0 # Number of images to match selected by GPS distance. Set to 0 to use no limit
53+
matching_time_neighbors: 0 # Number of images to match selected by time taken. Set to 0 to use no limit
5354
preemptive_max: 200 # Number of features to use for preemptive matching
5455
preemptive_threshold: 0 # If number of matches passes the threshold -> full feature matching
5556
@@ -121,4 +122,4 @@ def load_config(filepath):
121122
for k, v in new_config.items():
122123
config[k] = v
123124

124-
return config
125+
return config

0 commit comments

Comments
 (0)