-
Notifications
You must be signed in to change notification settings - Fork 901
Expand file tree
/
Copy pathdetect_features.py
More file actions
114 lines (90 loc) · 3.53 KB
/
Copy pathdetect_features.py
File metadata and controls
114 lines (90 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import logging
from timeit import default_timer as timer
import numpy as np
from opensfm import bow
from opensfm import dataset
from opensfm import features
from opensfm import io
from opensfm import log
from opensfm.context import parallel_map
logger = logging.getLogger(__name__)
class Command:
name = 'detect_features'
help = 'Compute features for all images'
def add_arguments(self, parser):
parser.add_argument('dataset', help='dataset to process')
def run(self, args):
data = dataset.DataSet(args.dataset)
images = data.images()
arguments = [(image, data) for image in images]
start = timer()
processes = data.config['processes']
parallel_map(detect, arguments, processes, 1)
end = timer()
with open(data.profile_log(), 'a') as fout:
fout.write('detect_features: {0}\n'.format(end - start))
self.write_report(data, end - start)
def write_report(self, data, wall_time):
image_reports = []
for image in data.images():
try:
txt = data.load_report('features/{}.json'.format(image))
image_reports.append(io.json_loads(txt))
except IOError:
logger.warning('No feature report image {}'.format(image))
report = {
"wall_time": wall_time,
"image_reports": image_reports
}
data.save_report(io.json_dumps(report), 'features.json')
def detect(args):
image, data = args
log.setup()
need_words = data.config['matcher_type'] == 'WORDS' or data.config['matching_bow_neighbors'] > 0
has_words = not need_words or data.words_exist(image)
has_features = data.features_exist(image)
if has_features and has_words:
logger.info('Skip recomputing {} features for image {}'.format(
data.feature_type().upper(), image))
return
logger.info('Extracting {} features for image {}'.format(
data.feature_type().upper(), image))
start = timer()
if data.config["feature_type"] == "SIFT_GPU":
unmasked, keypoints = features.extract_features(
data.load_image(image), data.config)
p_unmasked, f_unmasked, c_unmasked = unmasked
else:
p_unmasked, f_unmasked, c_unmasked = features.extract_features(
data.load_image(image), data.config)
fmask = data.load_features_mask(image, p_unmasked)
if data.config["feature_type"] == "SIFT_GPU":
keypoints = keypoints[fmask]
p_unsorted = p_unmasked[fmask]
f_unsorted = f_unmasked[fmask]
c_unsorted = c_unmasked[fmask]
if len(p_unsorted) == 0:
logger.warning('No features found in image {}'.format(image))
return
size = p_unsorted[:, 2]
order = np.argsort(size)
p_sorted = p_unsorted[order, :]
f_sorted = f_unsorted[order, :]
c_sorted = c_unsorted[order, :]
if data.config["feature_type"] == "SIFT_GPU":
keypoints_sorted = keypoints[order]
data.save_gpu_features(image, keypoints_sorted)
data.save_features(image, p_sorted, f_sorted, c_sorted)
if need_words:
bows = bow.load_bows(data.config)
n_closest = data.config['bow_words_to_match']
closest_words = bows.map_to_words(
f_sorted, n_closest, data.config['bow_matcher_type'])
data.save_words(image, closest_words)
end = timer()
report = {
"image": image,
"num_features": len(p_sorted),
"wall_time": end - start,
}
data.save_report(io.json_dumps(report), 'features/{}.json'.format(image))