In [1]:
%matplotlib inline
from matplotlib import pyplot as plt, cm
import cv2
import numpy as np
In [2]:
# Here is the simple algorithm to extend SIFT to RootSIFT:
# Step 1: Compute SIFT descriptors using your favorite SIFT library.
# Step 2: L1-normalize each SIFT vector.
# Step 3: Take the square-root of each element in the SIFT vector.
# Step 4: L2-normalize the resulting vector.
# this little modification can dramatically improve results, whether you’re matching keypoints,
# clustering SIFT descriptors, of quantizing to form a bag of visual words, Arandjelovic et al
In [8]:
class RootSIFT:
def __init__(self):
# initialize the SIFT feature extractor
self.extractor = cv2.DescriptorExtractor_create("SIFT")
def compute(self, image, kps, eps=1e-7):
# compute SIFT descriptors
(kps, descs) = self.extractor.compute(image, kps)
# if there are no keypoints or descriptors, return an empty tuple
if len(kps) == 0:
return ([], None)
# apply the Hellinger kernel by first L1-normalizing and taking the
# square-root
descs /= (descs.sum(axis=1, keepdims=True) + eps)
descs = np.sqrt(descs)
#descs /= (np.linalg.norm(descs, axis=1, ord=2) + eps)
# return a tuple of the keypoints and descriptors
return (kps, descs)
In [9]:
# load the image we are going to extract descriptors from and convert
# it to grayscale
image = cv2.imread("./data/thumb_IMG_4181_1024.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# detect Difference of Gaussian keypoints in the image
detector = cv2.FeatureDetector_create("SIFT")
kps = detector.detect(image)
# extract normal SIFT descriptors
extractor = cv2.DescriptorExtractor_create("SIFT")
(kps, descs) = extractor.compute(image, kps)
print "SIFT: kps=%d, descriptors=%s " % (len(kps), descs.shape)
# extract RootSIFT descriptors
rs = RootSIFT()
(kps, descs) = rs.compute(image, kps)
print "RootSIFT: kps=%d, descriptors=%s " % (len(kps), descs.shape)