4

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?

user601836
  • 3,215
  • 4
  • 38
  • 48

2 Answers2

6

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 helped me a lot, see Esteban Angee's answer.

You can also have a look at my answer to this question, 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]
Community
  • 1
  • 1
hjweide
  • 11,893
  • 9
  • 45
  • 49
  • using this is my code with two images, where one is just the same image scaled i got before the result the following message: Warning: invalid value encountered in divide – user601836 Oct 03 '12 at 14:43
  • Yes, this is just a runtime error, I see it myself now and then. I did not realise that it happens for scaled-versions of an image. When I have some time I will look into it more closely. However, so far it has not lead to any problems for me. – hjweide Oct 03 '12 at 15:13
1

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), 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 has a good code sample using cv2.KNearest, which definitely is in the Python version.

Community
  • 1
  • 1
jam
  • 3,640
  • 5
  • 34
  • 50