Question: I have two images which I want to compare using python and opencv.

I understood how to extract surf features from a single images from this book: Programming Computer Vision with Python.

I extract the features as follows:

```
import cv2
from numpy import *

# read image
im = cv2.imread('empire.jpg')

# downsample
im_lowres = cv2.pyrDown(im)

# convert to grayscale
gray = cv2.cvtColor(im_lowres,cv2.COLOR_RGB2GRAY)

# detect feature points
s = cv2.SURF()
mask = uint8(ones(gray.shape))

keypoints = s.detect(gray,mask)

# show image and points
vis = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
for k in keypoints[::10]:
    cv2.circle(vis,(int(k.pt[0]),int(k.pt[1])),2,(0,255,0),-1)
    cv2.circle(vis,(int(k.pt[0]),int(k.pt[1])),int(k.size),(0,255,0),2)

cv2.imshow('local descriptors',vis)
cv2.waitKey()

```

Now how I can I compare keypoints with another sets of keypoints which comes from a reference image using?

Answer: 
There is a FLANN implementation for Python OpenCV, I have used it myself and it works very well. Initially it wasn't easy to figure out, but the [this question](https://stackoverflow.com/questions/8301962/opencv-pythons-api-flannbasedmatcher/8311498#8311498) helped me a lot, see [Esteban Angee's](https://stackoverflow.com/users/1053925/esteban-angee) answer.

You can also have a look at my answer to [this question](https://stackoverflow.com/questions/12508934/error-using-knnmatch-with-opencvpython/12517147#12517147), where I quickly explained the code. I repeat the explanation here.

```
r_threshold = 0.6
FLANN_INDEX_KDTREE = 1  # bug: flann enums are missing

```

Construct your parameters dictionary:

```
flann_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 4)
flann = cv2.flann_Index(desc2, flann_params)

```

Perform nearest neighbours search:

```
idx2, dist = flann.knnSearch(desc1, 2, params = {}) # bug: need to provide empty dict
mask = dist[:,0] / dist[:,1] < r_threshold
idx1 = np.arange(len(desc1))
pairs = np.int32( zip(idx1, idx2[:,0]) )

```

Returns the descriptors that matched:

```
return pairs[mask]

```
Matching SURF descriptors is normally done using k-nearest neighbours (with k=2). Certainly for C++ OpenCV has a built-in class for doing this - Fast approximate nearest neighbour descriptor matcher ([FLANN\_matcher](http://opencv.itseez.com/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html?highlight=flann)), though I can't seem to find any docs for Python versions of this. Perhaps have a dig around, see if you can find it?

If you end up needing to do this from scratch, [this post](https://stackoverflow.com/questions/10984313/opencv-2-4-1-computing-surf-descriptors-in-python) has a good code sample using `cv2.KNearest`, which definitely is in the Python version.