-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_bags_of_sifts.py
66 lines (61 loc) · 3.39 KB
/
get_bags_of_sifts.py
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
from PIL import Image
import numpy as np
from scipy.spatial import distance
import pickle
import scipy.spatial.distance as distance
from cyvlfeat.sift.dsift import dsift
from time import time
from tqdm import tqdm
def get_bags_of_sifts(image_paths):
############################################################################
# TODO: #
# This function assumes that 'vocab.pkl' exists and contains an N x 128 #
# matrix 'vocab' where each row is a kmeans centroid or visual word. This #
# matrix is saved to disk rather than passed in a parameter to avoid #
# recomputing the vocabulary every time at significant expense. #
# #
# image_feats is an N x d matrix, where d is the dimensionality of the #
# feature representation. In this case, d will equal the number of clusters#
# or equivalently the number of entries in each image's histogram. #
# #
# You will construct SIFT features here in the same way you did in #
# build_vocabulary (except for possibly changing the sampling rate) #
# and then assign each local feature to its nearest cluster center #
# and build a histogram indicating how many times each cluster was used. #
# Don't forget to normalize the histogram, or else a larger image with more#
# SIFT features will look very different from a smaller version of the same#
# image. #
############################################################################
'''
Input :
image_paths : a list(N) of training images
Output :
image_feats : (N, d) feature, each row represent a feature of an image
'''
with open('vocab.pkl', 'rb') as handle:
vocab = pickle.load(handle)
image_feats = []
start_time = time()
print("Construct bags of sifts...")
for path in tqdm(image_paths):
img = np.asarray(Image.open(path),dtype='float32')
_, descriptor = dsift(img, step=[3,3], fast=True)
# calculate the distance between vocab and features of training set
# vocab.shape = (vocab_size, 128), descriptor.shape = (keypoint, 128)
# dist.shape = (vocab_size, keypoints)
dist = distance.cdist(vocab, descriptor, metric='cityblock')
# find the index of a vocabulary closest to each feature of samples from n=150 vocabulary
idx = np.argmin(dist, axis=0)
# calculate the appearence time of each vocabulary
hist, _ = np.histogram(idx, bins=len(vocab))
# normalize histogram
hist_norm = [float(i)/sum(hist) for i in hist]
image_feats.append(hist_norm)
# turn feature into 2-D numpy array
image_feats = np.asarray(image_feats)
end_time = time()
print(f"It takes {((end_time - start_time)/60):.2f} minutes to construct bags of sifts.")
#############################################################################
# END OF YOUR CODE #
#############################################################################
return image_feats