CMalone-Jupiter commited on
Commit
e4b6a37
·
verified ·
1 Parent(s): 33bb796

Upload folder using huggingface_hub

Browse files
FoL/__init__.py ADDED
File without changes
FoL/split_local_feats.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ sys.path.append(os.path.abspath(".")) # one level up
4
+ import numpy as np
5
+ from natsort import natsorted, index_natsorted
6
+ import torch
7
+ from tqdm import tqdm
8
+ from glob import glob
9
+
10
+ ################## set device based on cuda availability #################
11
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
12
+
13
+ print('CUDA availability: ' + str(torch.cuda.is_available()))
14
+
15
+ ####################### Functions for matching using numpy on CPU or Pytorch on GPU ###################
16
+
17
+ slice_size = 1000
18
+ # qry_set = '20210909_124816_v2'
19
+ qry_set = '20230509_115540_v2'
20
+ vpr_desc = 'FoL'
21
+ img_calib_file = f"./camera_calib.txt"
22
+ # User parameters
23
+ location = 'dalby-to-brigalow'
24
+
25
+ ################ Query filenames and directories #################################
26
+ qry_condition = ''
27
+ qry_camera_pos = 'front'
28
+
29
+ qry_root_directory = f"../../Datasets/dalby/{location}"
30
+ qry_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
31
+ qry_image_dir = f"{qry_root_directory}/{qry_set}/{qry_camera_pos}-imgs/"
32
+ save_dir = f"../../Datasets/dalby/{location}/vpr_ftrs/{qry_set}/{vpr_desc}/sliced/"
33
+
34
+ os.makedirs(save_dir, exist_ok=True)
35
+
36
+
37
+ qry_timestamps = [filename.split('.png')[0] for filename in natsorted(os.listdir(qry_image_dir)) if os.path.isfile(qry_image_dir+filename)]
38
+
39
+ # Get the two orderings
40
+ glob_sorted_paths = sorted(glob(f"{qry_image_dir}/*.png"))
41
+ glob_sorted_filenames = [os.path.basename(p) for p in glob_sorted_paths]
42
+
43
+ # Get the indices that would sort glob_sorted_filenames into natsorted order
44
+ qry_name_sort_idx = index_natsorted(glob_sorted_filenames)
45
+
46
+ print(f"Loading query features")
47
+
48
+ qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/queries_descriptors.npy")
49
+
50
+ print(f"Loading query local features")
51
+ qry_local_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/qry_local_feats.npy")
52
+ qry_ftrs = qry_ftrs[qry_name_sort_idx]
53
+ qry_local_ftrs = qry_local_ftrs[qry_name_sort_idx]
54
+
55
+ assert qry_ftrs.shape[0] == qry_local_ftrs.shape[0], f"There should be equal number of global ({qry_ftrs.shape[0]}) and local ({qry_local_ftrs.shape[0]}) features"
56
+
57
+ check_len_ftrs = 0
58
+ check_len_local_ftrs = 0
59
+ slice_num = 0
60
+ # f"{42:05d}"
61
+ print(f"Starting slice n dice")
62
+ for idx in tqdm(range(0, qry_ftrs.shape[0], slice_size)):
63
+ end_idx = idx+min(slice_size, qry_ftrs.shape[0]-idx)
64
+ qry_ftrs_slice = qry_ftrs[idx:end_idx]
65
+ qry_local_ftrs_slice = qry_local_ftrs[idx:end_idx]
66
+
67
+ np.save(f"{save_dir}/queries_descriptors_slice_{slice_num:05d}.npy", qry_ftrs_slice)
68
+ np.save(f"{save_dir}/qry_local_feats_slice_{slice_num:05d}.npy", qry_local_ftrs_slice)
69
+
70
+
71
+ check_len_ftrs += qry_ftrs_slice.shape[0]
72
+ check_len_local_ftrs += qry_local_ftrs_slice.shape[0]
73
+ slice_num += 1
74
+
75
+ print(f"Query descriptors: {qry_ftrs.shape[0]}, Slice query descriptors: {check_len_ftrs}")
76
+ print(f"Query local descriptors: {qry_local_ftrs.shape[0]}, Slice query local descriptors: {check_len_local_ftrs}")
77
+ print(f"Number of slices: {slice_num}")
localisation/VPR_eval-all-v2.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import matplotlib.pyplot as plt
3
+ import matplotlib.image as mpimg
4
+ import sys
5
+ sys.path.append(os.path.abspath(".")) # one level up
6
+ import numpy as np
7
+ import cv2
8
+ import open3d as o3d
9
+ from scipy.spatial.transform import Rotation
10
+ from utils.lidar import PointCloud
11
+ from utils.camera import ImageData
12
+ import utils.utils as utils
13
+ from natsort import natsorted, index_natsorted
14
+ import torch
15
+ from tqdm import tqdm
16
+ from glob import glob
17
+
18
+ ################## set device based on cuda availability #################
19
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
20
+
21
+ print('CUDA availability: ' + str(torch.cuda.is_available()))
22
+
23
+ ####################### Functions for matching using numpy on CPU or Pytorch on GPU ###################
24
+ def getMatchIndsCPU(ft_ref,ft_qry,topK=20,metric='cosine'):
25
+ """
26
+ metric: 'euclidean' or 'cosine'
27
+ """
28
+ # dMat = cdist(ft_ref,ft_qry,metric)
29
+
30
+ ft_qry_norm = ft_qry / np.linalg.norm(ft_qry, axis=1, keepdims=True) # Shape (M, N)
31
+ ft_ref_norm = ft_ref / np.linalg.norm(ft_ref, axis=1, keepdims=True) # Shape (C, N)
32
+
33
+ # Step 2: Compute cosine similarity
34
+ dMat = 1 - (ft_ref_norm @ ft_qry_norm.T)
35
+ mInds = np.argsort(dMat,axis=0)[:topK].squeeze() # shape: K x ft_qry.shape[0]
36
+ return mInds, dMat
37
+
38
+
39
+ def getMatchIndsGPU(ft_ref, ft_qry,topK=20, metric='cosine'):
40
+ # metric: 'euclidean' or 'cosine'
41
+ ft_qry_tensor = torch.Tensor(ft_qry).to(device)
42
+ ft_ref_tensor = torch.Tensor(ft_ref).to(device)
43
+
44
+ if metric == 'euclidean':
45
+ # Use torch's cdist for Euclidean distance
46
+ dMat = torch.cdist(ft_ref, ft_qry)
47
+
48
+ elif metric == 'cosine':
49
+ # # Normalize both the query and reference tensors
50
+ ft_qry_norm = ft_qry_tensor / ft_qry_tensor.norm(dim=1, keepdim=True)
51
+ ft_ref_norm = ft_ref_tensor / ft_ref_tensor.norm(dim=1, keepdim=True)
52
+ # Compute cosine similarity (1 - cosine similarity for distance)
53
+ dMat = 1 - ft_ref_norm @ ft_qry_norm.t()
54
+
55
+ # Get the indices of the top 5 closest matches
56
+ mInds = torch.argsort(dMat.cpu(), dim=0)[:topK].squeeze()
57
+
58
+ return mInds, dMat
59
+
60
+ qry_sets = [
61
+ '20210909_124816_v2',
62
+ ]
63
+
64
+ ref_sets = [
65
+ '20230509_115540_v2',
66
+ ]
67
+
68
+ # vpr_descs = [
69
+ # 'cosplace',
70
+ # 'boq',
71
+ # 'clique-mining',
72
+ # 'cricavpr',
73
+ # 'eigenplaces',
74
+ # 'mixvpr',
75
+ # 'megaloc',
76
+ # 'salad',
77
+ # 'supervlad',
78
+ # ]
79
+ vpr_descs = [
80
+ 'FoL',
81
+ ]
82
+
83
+
84
+ img_calib_file = f"./camera_calib.txt"
85
+
86
+ dist_tolerance = 10 # metres
87
+ # qry_idx = 4
88
+
89
+ # User parameters
90
+ location = 'dalby-to-brigalow'
91
+
92
+ ################ Reference filenames and directories #################################
93
+ ref_condition = ''
94
+ ref_camera_pos = 'front'
95
+
96
+ ref_timestamps = []
97
+ ref_utms = []
98
+ ref_img_filenames = []
99
+ ref_utm_filenames = []
100
+
101
+ for ref_set in ref_sets:
102
+ print(f"Loading {ref_set}")
103
+
104
+ ref_root_directory = f"../../Datasets/dalby/{location}"
105
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
106
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
107
+ ref_utm_dir = f"{ref_root_directory}/{ref_set}/utm/"
108
+
109
+
110
+ this_ref_timestamp = [filename.split('.png')[0] for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
111
+ ref_utms = ref_utms+[np.loadtxt(ref_utm_dir+filename) for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)][55::]
112
+ ref_img_filenames = [filename for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
113
+ ref_utm_filenames = np.array([filename for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)])[:len(os.listdir(ref_utm_dir))-55]
114
+ ref_timestamps = ref_timestamps+this_ref_timestamp
115
+
116
+ ref_utms = np.array(ref_utms)
117
+
118
+ for vpr_desc in vpr_descs:
119
+
120
+ all_results = []
121
+
122
+ first = True
123
+
124
+ print(f"Loading references")
125
+
126
+ for ref_set in ref_sets:
127
+ print(f"Loading {ref_set} {vpr_desc} descriptors")
128
+ ref_root_directory = f"../../Datasets/dalby/{location}"
129
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
130
+
131
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
132
+
133
+ # ref_name_sort_idx = index_natsorted(os.listdir(ref_image_dir))
134
+ # Get the two orderings
135
+ glob_sorted_paths = sorted(glob(f"{ref_image_dir}/*.png"))
136
+ glob_sorted_filenames = [os.path.basename(p) for p in glob_sorted_paths]
137
+
138
+ # Get the indices that would sort glob_sorted_filenames into natsorted order
139
+ ref_name_sort_idx = index_natsorted(glob_sorted_filenames)
140
+
141
+ ref_ftr = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/queries_descriptors.npy")
142
+ if first:
143
+ ref_ftrs = ref_ftr[ref_name_sort_idx]
144
+ first = False
145
+ else:
146
+ ref_ftrs = np.vstack((ref_ftrs, ref_ftr[ref_name_sort_idx])) # [ref_name_sort_idx]
147
+
148
+
149
+ for qry_set in qry_sets:
150
+
151
+ ################ Query filenames and directories #################################
152
+ qry_condition = ''
153
+ qry_camera_pos = 'front'
154
+
155
+ qry_root_directory = f"../../Datasets/dalby/{location}"
156
+ qry_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
157
+ qry_image_dir = f"{qry_root_directory}/{qry_set}/{qry_camera_pos}-imgs/"
158
+ qry_utm_dir = f"{qry_root_directory}/{qry_set}/utm/"
159
+
160
+
161
+ qry_timestamps = [filename.split('.png')[0] for filename in natsorted(os.listdir(qry_image_dir)) if os.path.isfile(qry_image_dir+filename)]
162
+ qry_utms = np.array([np.loadtxt(qry_utm_dir+filename) for filename in natsorted(os.listdir(qry_utm_dir)) if os.path.isfile(qry_utm_dir+filename)])
163
+ # qry_name_sort_idx = index_natsorted(os.listdir(qry_image_dir))
164
+ qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/queries_descriptors.npy")
165
+
166
+ # Get the two orderings
167
+ glob_sorted_paths = sorted(glob(f"{qry_image_dir}/*.png"))
168
+ glob_sorted_filenames = [os.path.basename(p) for p in glob_sorted_paths]
169
+
170
+ # Get the indices that would sort glob_sorted_filenames into natsorted order
171
+ qry_name_sort_idx = index_natsorted(glob_sorted_filenames)
172
+
173
+ qry_ftrs = qry_ftrs[qry_name_sort_idx]
174
+
175
+ # paths_sorted = sorted(glob(f"{qry_image_dir}/**/*", recursive=True))
176
+ # paths_natsorted = natsorted(os.listdir(qry_image_dir))
177
+ # paths_natsorted_idx = index_natsorted(os.listdir(qry_image_dir))
178
+
179
+ # # Compare just the filenames
180
+ # print(paths_sorted[:3])
181
+ # print((np.array(paths_sorted)[paths_natsorted_idx])[:3])
182
+ # print(paths_natsorted[:3])
183
+
184
+
185
+ # print(torch.cuda.memory_allocated()/1e9)
186
+ # print(torch.cuda.memory_reserved()/1e9)
187
+ mInds, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
188
+ mInds = mInds.numpy() # .cpu()
189
+ in_tol = []
190
+ dists = []
191
+ valid_qry = 0
192
+
193
+ qry_utm_timestamps, qry_utm_idxs = utils.get_all_corr_files(qry_timestamps, [qry_utm_dir,])
194
+ ref_utm_timestamp, ref_utm_idxs = utils.get_all_corr_files(ref_timestamps, [ref_utm_dir,])
195
+
196
+ for qry_idx in tqdm(range(len(qry_timestamps))):
197
+
198
+ qry_image_timestamp = qry_timestamps[qry_idx]
199
+ qry_image_filename = f"{qry_image_dir}/{qry_image_timestamp}.png"
200
+ qry_utm = qry_utms[qry_utm_idxs[qry_idx]]
201
+
202
+
203
+ diffs = ref_utms - qry_utm # shape (N, 2)
204
+ qry_dists = np.linalg.norm(diffs, axis=1) # shape (N,)
205
+ if qry_dists.min() > dist_tolerance:
206
+ continue
207
+ else:
208
+ valid_qry += 1
209
+
210
+ ref_utm = ref_utms[ref_utm_idxs[int(mInds[qry_idx])]]
211
+
212
+ diff = ref_utm - qry_utm # shape (N, 2)
213
+ dist = np.linalg.norm(diff) # shape (N,)
214
+ dists.append(dist)
215
+ if dist < dist_tolerance:
216
+ in_tol.append(1)
217
+ else:
218
+ in_tol.append(0)
219
+
220
+ # qry_image = ImageData(qry_image_filename, img_calib_file)
221
+
222
+ # fig, ax = plt.subplots(1, 2, figsize=(19.4, 6))
223
+ # ax[0].clear()
224
+ # ax[1].clear()
225
+
226
+ # ax[0].imshow(qry_image.image[:, :, ::-1])
227
+ # ax[0].set_title(f"{qry_image_timestamp}.png")
228
+ # ax[0].axis("off")
229
+
230
+ # # Show matching reference image
231
+ # # ref_img_timestamp = utils.get_corr_files(ref_timestamps[int(mInds[qry_idx])], [ref_image_dir,])
232
+ # ref_image = ImageData(f"{ref_image_dir}/{ref_timestamps[int(mInds[qry_idx])]}.png", img_calib_file)
233
+ # ax[1].imshow(ref_image.image[:, :, ::-1])
234
+ # ax[1].set_title(f"{ref_timestamps[int(mInds[qry_idx])]}\nDist={dist:.2f}m")
235
+
236
+ # ax[1].axis("off")
237
+ # fig.canvas.draw()
238
+
239
+ print(f"Recall for {qry_set} using {vpr_desc}: {np.sum(np.array(in_tol))/valid_qry:.02%}")
240
+ all_results.append(np.sum(np.array(in_tol))/valid_qry)
241
+ # plt.figure()
242
+ # plt.plot(np.clip(dists, 0, 30))
243
+ # plt.ylim((0,35))
244
+
245
+ print(f"All {vpr_desc} results:")
246
+ print(all_results)
localisation/VPR_eval-fol-mem.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ # import matplotlib.pyplot as plt
3
+ # import matplotlib.image as mpimg
4
+ import sys
5
+ sys.path.append(os.path.abspath(".")) # one level up
6
+ import numpy as np
7
+ import cv2
8
+ import open3d as o3d
9
+ from scipy.spatial.transform import Rotation
10
+ from utils.lidar import PointCloud
11
+ from utils.camera import ImageData
12
+ import utils.utils as utils
13
+ from FoL.reranking import run_rerank
14
+ from natsort import natsorted, index_natsorted
15
+ import torch
16
+ from tqdm import tqdm
17
+
18
+ ################## set device based on cuda availability #################
19
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
20
+
21
+ print('CUDA availability: ' + str(torch.cuda.is_available()))
22
+
23
+ ####################### Functions for matching using numpy on CPU or Pytorch on GPU ###################
24
+ def getMatchIndsCPU(ft_ref,ft_qry,topK=20,metric='cosine'):
25
+ """
26
+ metric: 'euclidean' or 'cosine'
27
+ """
28
+ # dMat = cdist(ft_ref,ft_qry,metric)
29
+
30
+ ft_qry_norm = ft_qry / np.linalg.norm(ft_qry, axis=1, keepdims=True) # Shape (M, N)
31
+ ft_ref_norm = ft_ref / np.linalg.norm(ft_ref, axis=1, keepdims=True) # Shape (C, N)
32
+
33
+ # Step 2: Compute cosine similarity
34
+ dMat = 1 - (ft_ref_norm @ ft_qry_norm.T)
35
+ mInds = np.argsort(dMat,axis=0)[:topK].squeeze() # shape: K x ft_qry.shape[0]
36
+ return mInds, dMat
37
+
38
+
39
+ def getMatchIndsGPU(ft_ref, ft_qry,topK=20, metric='cosine'):
40
+ # metric: 'euclidean' or 'cosine'
41
+ ft_qry_tensor = torch.Tensor(ft_qry).to(device)
42
+ ft_ref_tensor = torch.Tensor(ft_ref).to(device)
43
+
44
+ if metric == 'euclidean':
45
+ # Use torch's cdist for Euclidean distance
46
+ dMat = torch.cdist(ft_ref, ft_qry)
47
+
48
+ elif metric == 'cosine':
49
+ # # Normalize both the query and reference tensors
50
+ ft_qry_norm = ft_qry_tensor / ft_qry_tensor.norm(dim=1, keepdim=True)
51
+ ft_ref_norm = ft_ref_tensor / ft_ref_tensor.norm(dim=1, keepdim=True)
52
+ # Compute cosine similarity (1 - cosine similarity for distance)
53
+ dMat = 1 - ft_ref_norm @ ft_qry_norm.t()
54
+
55
+ # Get the indices of the top 5 closest matches
56
+ mInds = torch.argsort(dMat, dim=0)[:topK].squeeze()
57
+
58
+ return mInds, dMat
59
+
60
+ qry_sets = [
61
+ '20210909_124816_v2',
62
+ ]
63
+
64
+ ref_sets = [
65
+ '20230509_115540_v2',
66
+ ]
67
+
68
+ vpr_descs = [
69
+ 'FoL',
70
+ ]
71
+
72
+
73
+ img_calib_file = f"./camera_calib.txt"
74
+
75
+ dist_tolerance = 10 # metres
76
+ # qry_idx = 4
77
+
78
+ # User parameters
79
+ location = 'dalby-to-brigalow'
80
+
81
+ ################ Reference filenames and directories #################################
82
+ ref_condition = ''
83
+ ref_camera_pos = 'front'
84
+
85
+ ref_timestamps = []
86
+ ref_utms = []
87
+ ref_img_filenames = []
88
+ ref_utm_filenames = []
89
+
90
+ for ref_set in ref_sets:
91
+ print(f"Loading {ref_set}")
92
+
93
+ ref_root_directory = f"../../Datasets/dalby/{location}"
94
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
95
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
96
+ ref_utm_dir = f"{ref_root_directory}/{ref_set}/utm/"
97
+
98
+
99
+ this_ref_timestamp = [filename.split('.png')[0] for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
100
+ ref_utms = ref_utms+[np.loadtxt(ref_utm_dir+filename) for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)][55::]
101
+ ref_img_filenames = [filename for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
102
+ ref_utm_filenames = np.array([filename for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)])[:len(os.listdir(ref_utm_dir))-55]
103
+ ref_timestamps = ref_timestamps+this_ref_timestamp
104
+
105
+ ref_utms = np.array(ref_utms)
106
+
107
+ for vpr_desc in vpr_descs:
108
+
109
+ all_results = []
110
+
111
+ first = True
112
+
113
+ print(f"Loading references")
114
+
115
+ for ref_set in ref_sets:
116
+ print(f"Loading {ref_set} {vpr_desc} descriptors")
117
+ ref_root_directory = f"../../Datasets/dalby/{location}"
118
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
119
+
120
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
121
+
122
+ ref_name_sort_idx = index_natsorted(os.listdir(ref_image_dir))
123
+ ref_ftr = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/qry_feats.npy")
124
+ ref_local_ftr = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/qry_local_feats.npy")
125
+ if first:
126
+ ref_ftrs = ref_ftr[ref_name_sort_idx]
127
+ ref_local_ftrs = ref_local_ftr[ref_name_sort_idx]
128
+ first = False
129
+ else:
130
+ ref_ftrs = np.vstack((ref_ftrs, ref_ftr[ref_name_sort_idx]))
131
+ ref_local_ftrs = np.vstack((ref_local_ftrs, ref_local_ftr[ref_name_sort_idx]))
132
+
133
+
134
+ for qry_set in qry_sets:
135
+
136
+ ################ Query filenames and directories #################################
137
+ qry_condition = ''
138
+ qry_camera_pos = 'front'
139
+
140
+ qry_root_directory = f"../../Datasets/dalby/{location}"
141
+ qry_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
142
+ qry_image_dir = f"{qry_root_directory}/{qry_set}/{qry_camera_pos}-imgs/"
143
+ qry_utm_dir = f"{qry_root_directory}/{qry_set}/utm/"
144
+
145
+
146
+ qry_timestamps = [filename.split('.png')[0] for filename in natsorted(os.listdir(qry_image_dir)) if os.path.isfile(qry_image_dir+filename)]
147
+ qry_utms = np.array([np.loadtxt(qry_utm_dir+filename) for filename in natsorted(os.listdir(qry_utm_dir)) if os.path.isfile(qry_utm_dir+filename)])
148
+ qry_name_sort_idx = index_natsorted(os.listdir(qry_image_dir))
149
+ qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/qry_feats.npy")
150
+ qry_local_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/qry_local_feats.npy")
151
+ qry_ftrs = qry_ftrs[qry_name_sort_idx]
152
+ qry_local_ftrs = qry_local_ftrs[qry_name_sort_idx]
153
+
154
+ # mInds, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
155
+ # mInds = mInds.cpu().numpy()
156
+ mInds = run_rerank(qry_ftrs, ref_ftrs, qry_local_ftrs, ref_local_ftrs, recall_values=[1, 5, 10, 20])[:,0]
157
+ in_tol = []
158
+ dists = []
159
+ valid_qry = 0
160
+
161
+ qry_utm_timestamps, qry_utm_idxs = utils.get_all_corr_files(qry_timestamps, [qry_utm_dir,])
162
+ ref_utm_timestamp, ref_utm_idxs = utils.get_all_corr_files(ref_timestamps, [ref_utm_dir,])
163
+
164
+ for qry_idx in tqdm(range(len(qry_timestamps))):
165
+
166
+ qry_image_timestamp = qry_timestamps[qry_idx]
167
+ qry_image_filename = f"{qry_image_dir}/{qry_image_timestamp}.png"
168
+ qry_utm = qry_utms[qry_utm_idxs[qry_idx]]
169
+
170
+
171
+ diffs = ref_utms - qry_utm # shape (N, 2)
172
+ qry_dists = np.linalg.norm(diffs, axis=1) # shape (N,)
173
+ if qry_dists.min() > dist_tolerance:
174
+ continue
175
+ else:
176
+ valid_qry += 1
177
+
178
+ ref_utm = ref_utms[ref_utm_idxs[int(mInds[qry_idx])]]
179
+
180
+ diff = ref_utm - qry_utm # shape (N, 2)
181
+ dist = np.linalg.norm(diff) # shape (N,)
182
+ dists.append(dist)
183
+ if dist < dist_tolerance:
184
+ in_tol.append(1)
185
+ else:
186
+ in_tol.append(0)
187
+
188
+ # qry_image = ImageData(qry_image_filename, img_calib_file)
189
+
190
+ # fig, ax = plt.subplots(1, 2, figsize=(19.4, 6))
191
+ # ax[0].clear()
192
+ # ax[1].clear()
193
+
194
+ # ax[0].imshow(qry_image.image[:, :, ::-1])
195
+ # ax[0].set_title(f"{qry_image_timestamp}.png")
196
+ # ax[0].axis("off")
197
+
198
+ # # Show matching reference image
199
+ # # ref_img_timestamp = utils.get_corr_files(ref_timestamps[int(mInds[qry_idx])], [ref_image_dir,])
200
+ # ref_image = ImageData(f"{ref_image_dir}/{ref_timestamps[int(mInds[qry_idx])]}.png", img_calib_file)
201
+ # ax[1].imshow(ref_image.image[:, :, ::-1])
202
+ # ax[1].set_title(f"{ref_timestamps[int(mInds[qry_idx])]}\nDist={dist:.2f}m")
203
+
204
+ # ax[1].axis("off")
205
+ # fig.canvas.draw()
206
+
207
+ print(f"Recall for {qry_set} using {vpr_desc}: {np.sum(np.array(in_tol))/valid_qry:.02%}")
208
+ all_results.append(np.sum(np.array(in_tol))/valid_qry)
209
+ # plt.figure()
210
+ # plt.plot(np.clip(dists, 0, 30))
211
+ # plt.ylim((0,35))
212
+
213
+ print(f"All {vpr_desc} results:")
214
+ print(all_results)
localisation/VPR_eval-fol.py ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ # import matplotlib.pyplot as plt
3
+ # import matplotlib.image as mpimg
4
+ import sys
5
+ sys.path.append(os.path.abspath(".")) # one level up
6
+ import numpy as np
7
+ # import cv2
8
+ # import open3d as o3d
9
+ # from scipy.spatial.transform import Rotation
10
+ # from utils.lidar import PointCloud
11
+ # from utils.camera import ImageData
12
+ # import utils.utils as utils
13
+ from utils.utils import get_all_corr_files
14
+ from FoL.reranking import run_rerank
15
+ from natsort import natsorted, index_natsorted
16
+ import torch
17
+ from tqdm import tqdm
18
+ from glob import glob
19
+ from math import floor
20
+
21
+ ################## set device based on cuda availability #################
22
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
23
+
24
+ print('CUDA availability: ' + str(torch.cuda.is_available()))
25
+
26
+ ####################### Functions for matching using numpy on CPU or Pytorch on GPU ###################
27
+ def getMatchIndsCPU(ft_ref,ft_qry,topK=20,metric='cosine'):
28
+ """
29
+ metric: 'euclidean' or 'cosine'
30
+ """
31
+ # dMat = cdist(ft_ref,ft_qry,metric)
32
+
33
+ ft_qry_norm = ft_qry / np.linalg.norm(ft_qry, axis=1, keepdims=True) # Shape (M, N)
34
+ ft_ref_norm = ft_ref / np.linalg.norm(ft_ref, axis=1, keepdims=True) # Shape (C, N)
35
+
36
+ # Step 2: Compute cosine similarity
37
+ dMat = 1 - (ft_ref_norm @ ft_qry_norm.T)
38
+ mInds = np.argsort(dMat,axis=0)[:topK].squeeze() # shape: K x ft_qry.shape[0]
39
+ return mInds, dMat
40
+
41
+
42
+ def getMatchIndsGPU(ft_ref, ft_qry,topK=20, metric='cosine'):
43
+ # metric: 'euclidean' or 'cosine'
44
+ ft_qry_tensor = torch.Tensor(ft_qry).to(device)
45
+ ft_ref_tensor = torch.Tensor(ft_ref).to(device)
46
+
47
+ if metric == 'euclidean':
48
+ # Use torch's cdist for Euclidean distance
49
+ dMat = torch.cdist(ft_ref, ft_qry)
50
+
51
+ elif metric == 'cosine':
52
+ # # Normalize both the query and reference tensors
53
+ ft_qry_norm = ft_qry_tensor / ft_qry_tensor.norm(dim=1, keepdim=True)
54
+ ft_ref_norm = ft_ref_tensor / ft_ref_tensor.norm(dim=1, keepdim=True)
55
+ # Compute cosine similarity (1 - cosine similarity for distance)
56
+ dMat = 1 - ft_ref_norm @ ft_qry_norm.t()
57
+
58
+ # Get the indices of the top 5 closest matches
59
+ mInds = torch.argsort(dMat.cpu(), dim=0)[:topK].squeeze()
60
+
61
+ return mInds, dMat
62
+
63
+ qry_sets = [
64
+ '20210909_124816_v2',
65
+ ]
66
+
67
+ ref_sets = [
68
+ '20230509_115540_v2',
69
+ ]
70
+
71
+ vpr_descs = [
72
+ 'FoL',
73
+ ]
74
+
75
+
76
+ img_calib_file = f"./camera_calib.txt"
77
+
78
+ dist_tolerance = 10 # metres
79
+ # qry_idx = 4
80
+ slice_len = 1000
81
+
82
+ # User parameters
83
+ location = 'dalby-to-brigalow'
84
+
85
+ ################ Reference filenames and directories #################################
86
+ ref_condition = ''
87
+ ref_camera_pos = 'front'
88
+
89
+ ref_timestamps = []
90
+ ref_utms = []
91
+ ref_img_filenames = []
92
+ ref_utm_filenames = []
93
+
94
+ for ref_set in ref_sets:
95
+ print(f"Loading {ref_set}")
96
+
97
+ ref_root_directory = f"../../Datasets/dalby/{location}"
98
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
99
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
100
+ ref_utm_dir = f"{ref_root_directory}/{ref_set}/utm/"
101
+
102
+
103
+ this_ref_timestamp = [filename.split('.png')[0] for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
104
+ ref_utms = ref_utms+[np.loadtxt(ref_utm_dir+filename) for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)][55::]
105
+ ref_img_filenames = [filename for filename in natsorted(os.listdir(ref_image_dir)) if os.path.isfile(ref_image_dir+filename)]
106
+ ref_utm_filenames = np.array([filename for filename in natsorted(os.listdir(ref_utm_dir)) if os.path.isfile(ref_utm_dir+filename)])[:len(os.listdir(ref_utm_dir))-55]
107
+ ref_timestamps = ref_timestamps+this_ref_timestamp
108
+
109
+ ref_utms = np.array(ref_utms)
110
+
111
+ for vpr_desc in vpr_descs:
112
+
113
+ all_results = []
114
+
115
+ first = True
116
+
117
+ print(f"Loading references")
118
+
119
+ for ref_set in ref_sets:
120
+ print(f"Loading {ref_set} {vpr_desc} descriptors")
121
+ ref_root_directory = f"../../Datasets/dalby/{location}"
122
+ ref_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
123
+
124
+ ref_image_dir = f"{ref_root_directory}/{ref_set}/{ref_camera_pos}-imgs/"
125
+
126
+ # ref_name_sort_idx = index_natsorted(os.listdir(ref_image_dir))
127
+
128
+ if slice_len is None:
129
+
130
+ # Get the two orderings
131
+ glob_sorted_paths = sorted(glob(f"{ref_image_dir}/*.png"))
132
+ glob_sorted_filenames = [os.path.basename(p) for p in glob_sorted_paths]
133
+
134
+ # Get the indices that would sort glob_sorted_filenames into natsorted order
135
+ ref_name_sort_idx = index_natsorted(glob_sorted_filenames)
136
+
137
+ ref_ftr = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/queries_descriptors.npy")
138
+ ref_local_ftr = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/qry_local_feats.npy")
139
+ if first:
140
+ ref_ftrs = ref_ftr[ref_name_sort_idx]
141
+ ref_local_ftrs = ref_local_ftr[ref_name_sort_idx]
142
+ first = False
143
+ else:
144
+ ref_ftrs = np.vstack((ref_ftrs, ref_ftr[ref_name_sort_idx]))
145
+ ref_local_ftrs = np.vstack((ref_local_ftrs, ref_local_ftr[ref_name_sort_idx]))
146
+
147
+ else:
148
+ num_slices = floor(len(ref_img_filenames)/slice_len)
149
+ if len(ref_img_filenames) % slice_len > 0:
150
+ num_slices += 1
151
+
152
+ for idx in tqdm(range(num_slices)):
153
+ if idx == 0:
154
+ ref_ftrs = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")
155
+ ref_local_ftrs = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/qry_local_feats_slice_{idx:05d}.npy")
156
+ else:
157
+ ref_ftrs = np.vstack((ref_ftrs, np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")))
158
+ ref_local_ftrs = np.vstack((ref_local_ftrs, np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/qry_local_feats_slice_{idx:05d}.npy")))
159
+
160
+
161
+ print(f"Loaded ref ftr slices: {len(ref_ftrs)}")
162
+ print(f"Loaded ref local ftr slices: {len(ref_local_ftrs)}")
163
+
164
+
165
+ for qry_set in qry_sets:
166
+
167
+ ################ Query filenames and directories #################################
168
+ qry_condition = ''
169
+ qry_camera_pos = 'front'
170
+
171
+ qry_root_directory = f"../../Datasets/dalby/{location}"
172
+ qry_vpr_root = f"../../Datasets/dalby/{location}/vpr_ftrs/"
173
+ qry_image_dir = f"{qry_root_directory}/{qry_set}/{qry_camera_pos}-imgs/"
174
+ qry_utm_dir = f"{qry_root_directory}/{qry_set}/utm/"
175
+
176
+
177
+ qry_timestamps = [filename.split('.png')[0] for filename in natsorted(os.listdir(qry_image_dir)) if os.path.isfile(qry_image_dir+filename)]
178
+ qry_utms = np.array([np.loadtxt(qry_utm_dir+filename) for filename in natsorted(os.listdir(qry_utm_dir)) if os.path.isfile(qry_utm_dir+filename)])
179
+ # qry_name_sort_idx = index_natsorted(os.listdir(qry_image_dir))
180
+
181
+ # if slice_len is None:
182
+ # # Get the two orderings
183
+ # glob_sorted_paths = sorted(glob(f"{qry_image_dir}/*.png"))
184
+ # glob_sorted_filenames = [os.path.basename(p) for p in glob_sorted_paths]
185
+
186
+ # # Get the indices that would sort glob_sorted_filenames into natsorted order
187
+ # qry_name_sort_idx = index_natsorted(glob_sorted_filenames)
188
+
189
+ # qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/queries_descriptors.npy")
190
+ # qry_local_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/qry_local_feats.npy")
191
+ # qry_ftrs = qry_ftrs[qry_name_sort_idx]
192
+ # qry_local_ftrs = qry_local_ftrs[qry_name_sort_idx]
193
+
194
+ # mInds, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
195
+ # mInds = mInds.cpu().numpy()
196
+ if slice_len is None:
197
+ mInds = run_rerank(qry_ftrs, ref_ftrs, qry_local_ftrs, ref_local_ftrs, recall_values=[1, 5, 10, 20])[:,0] # 5, 10, 20
198
+ else:
199
+ print(f"Performing VPR on slices")
200
+ num_slices = floor(len(qry_timestamps)/slice_len)
201
+ if len(qry_timestamps) % slice_len > 0:
202
+ num_slices += 1
203
+
204
+ for idx in tqdm(range(num_slices)):
205
+ qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")
206
+ qry_local_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/sliced/qry_local_feats_slice_{idx:05d}.npy")
207
+ if idx == 0:
208
+ mInds = run_rerank(qry_ftrs, ref_ftrs, qry_local_ftrs, ref_local_ftrs, recall_values=[1, 5, 10, 20])[:,0]
209
+ else:
210
+ mInds_slice = run_rerank(qry_ftrs, ref_ftrs, qry_local_ftrs, ref_local_ftrs, recall_values=[1, 5, 10, 20])[:,0]
211
+ mInds = np.vstack((np.expand_dims(mInds, axis=1), np.expand_dims(mInds_slice, axis=1))).squeeze()
212
+
213
+ del qry_ftrs
214
+ del qry_local_ftrs
215
+
216
+ print(f"VPR on query slices: {len(mInds)}")
217
+
218
+ np.save(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/mInds.npy", mInds)
219
+
220
+
221
+ in_tol = []
222
+ dists = []
223
+ valid_qry = 0
224
+
225
+ qry_utm_timestamps, qry_utm_idxs = get_all_corr_files(qry_timestamps, [qry_utm_dir,])
226
+ ref_utm_timestamp, ref_utm_idxs = get_all_corr_files(ref_timestamps, [ref_utm_dir,])
227
+
228
+ for qry_idx in tqdm(range(len(qry_timestamps))):
229
+
230
+ qry_image_timestamp = qry_timestamps[qry_idx]
231
+ qry_image_filename = f"{qry_image_dir}/{qry_image_timestamp}.png"
232
+ qry_utm = qry_utms[qry_utm_idxs[qry_idx]]
233
+
234
+
235
+ diffs = ref_utms - qry_utm # shape (N, 2)
236
+ qry_dists = np.linalg.norm(diffs, axis=1) # shape (N,)
237
+ if qry_dists.min() > dist_tolerance:
238
+ continue
239
+ else:
240
+ valid_qry += 1
241
+
242
+ ref_utm = ref_utms[ref_utm_idxs[int(mInds[qry_idx])]]
243
+
244
+ diff = ref_utm - qry_utm # shape (N, 2)
245
+ dist = np.linalg.norm(diff) # shape (N,)
246
+ dists.append(dist)
247
+ if dist < dist_tolerance:
248
+ in_tol.append(1)
249
+ else:
250
+ in_tol.append(0)
251
+
252
+ # qry_image = ImageData(qry_image_filename, img_calib_file)
253
+
254
+ # fig, ax = plt.subplots(1, 2, figsize=(19.4, 6))
255
+ # ax[0].clear()
256
+ # ax[1].clear()
257
+
258
+ # ax[0].imshow(qry_image.image[:, :, ::-1])
259
+ # ax[0].set_title(f"{qry_image_timestamp}.png")
260
+ # ax[0].axis("off")
261
+
262
+ # # Show matching reference image
263
+ # # ref_img_timestamp = utils.get_corr_files(ref_timestamps[int(mInds[qry_idx])], [ref_image_dir,])
264
+ # ref_image = ImageData(f"{ref_image_dir}/{ref_timestamps[int(mInds[qry_idx])]}.png", img_calib_file)
265
+ # ax[1].imshow(ref_image.image[:, :, ::-1])
266
+ # ax[1].set_title(f"{ref_timestamps[int(mInds[qry_idx])]}\nDist={dist:.2f}m")
267
+
268
+ # ax[1].axis("off")
269
+ # fig.canvas.draw()
270
+
271
+ print(f"Recall for {qry_set} using {vpr_desc}: {np.sum(np.array(in_tol))/valid_qry:.02%}")
272
+ all_results.append(np.sum(np.array(in_tol))/valid_qry)
273
+ # plt.figure()
274
+ # plt.plot(np.clip(dists, 0, 30))
275
+ # plt.ylim((0,35))
276
+
277
+ print(f"All {vpr_desc} results:")
278
+ print(all_results)
279
+
280
+ # else:
281
+ # num_slices = floor(len(ref_img_filenames)/slice_len)
282
+ # if len(ref_img_filenames) % slice_len > 0:
283
+ # num_slices += 1
284
+
285
+ # for idx in range(num_slices):
286
+ # if idx == 0:
287
+ # ref_ftrs = np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")
288
+ # else:
289
+ # ref_ftrs = np.vstack((ref_ftrs, np.load(f"{ref_vpr_root}/{ref_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")))
290
+
291
+
292
+ # print(f"Loaded ref ftr slices: {len(ref_ftrs)}")
293
+
294
+
295
+
296
+
297
+ # if slice_len is None:
298
+ # mInds, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
299
+ # mInds = mInds.cpu().numpy()
300
+ # else:
301
+ # print(f"Performing VPR on slices")
302
+ # num_slices = floor(len(qry_timestamps)/slice_len)
303
+ # if len(qry_timestamps) % slice_len > 0:
304
+ # num_slices += 1
305
+
306
+ # for idx in tqdm(range(num_slices)):
307
+ # qry_ftrs = np.load(f"{qry_vpr_root}/{qry_set}/{vpr_desc}/sliced/queries_descriptors_slice_{idx:05d}.npy")
308
+ # if idx == 0:
309
+ # mInds, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
310
+ # mInds = mInds.cpu().numpy()
311
+ # else:
312
+ # mInds_slice, dMat = getMatchIndsGPU(ref_ftrs,qry_ftrs,topK=1)
313
+ # mInds_slice = mInds_slice.cpu().numpy()
314
+ # mInds = np.vstack((np.expand_dims(mInds, axis=1), np.expand_dims(mInds_slice, axis=1))).squeeze()
315
+
316
+ # print(f"VPR on query slices: {len(mInds)}")
submit-job.sh ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ #PBS -N vpr-extract
4
+ #PBS -l select=1:ncpus=10:mem=100gb:ngpus=1:gpu_id=A100
5
+ #PBS -l walltime=06:00:00
6
+ #PBS -m abe
7
+ #PBS -M cj.malone@qut.edu.au
8
+ #PBS -j oe
9
+
10
+ micromamba activate fred
11
+
12
+
13
+ # Move to repo
14
+ cd "$HOME/cloned_repos/python-FRED/" || exit 1
15
+
16
+ # Run Python script
17
+ python localisation/VPR_eval-fol.py
18
+ # python FoL/split_local_feats.py