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)


SIFT: kps=4929, descriptors=(4929, 128) 
RootSIFT: kps=4929, descriptors=(4929, 128)