OpenCV: Extract SURF Features from user-defined keypoints

2024/9/22 18:47:25

I want to compute SURF Features from keypoints that I specify. I am using the Python wrapper of OpenCV. The following is the code I am trying to use, but I cannot find a working example anywhere.

surf = cv2.SURF()
keypoints, descriptors = surf.detect(np.asarray(image[:,:]),None,useProvidedKeypoints = True)

How can I specify the keypoints to be used by this function?

Similar, unanswered, question: cvExtractSURF don't work when useProvidedKeypoints = true

Documentation

Answer

Try using cv2.DescriptorMatcher_create for that.

For instance, in the following code I am using pylab, but you can get the message ;)

It computes the keypoints using GFTT, and then uses the SURF descriptor and the Brute force matching. The output of each code part is show as header.


%pylab inline
import cv2
import numpy as npimg = cv2.imread('./img/nail.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imshow(gray,  cmap=cm.gray)

Output is something like this https://i.stack.imgur.com/8eOTe.png

(For this example I will cheat and use the same image to get the keypoints and descriptors).

img1 = gray
img2 = gray
detector = cv2.FeatureDetector_create("GFTT")
descriptor = cv2.DescriptorExtractor_create("SURF")
matcher = pt1=(int(k1[m.queryIdx].pt[0]),int(k1[m.queryIdx].pt[1]))("FlannBased")# detect keypoints
kp1 = detector.detect(img1)
kp2 = detector.detect(img2)print '#keypoints in image1: %d, image2: %d' % (len(kp1), len(kp2))

keypoints in image1: 1000, image2: 1000

# descriptors
k1, d1 = descriptor.compute(img1, kp1)
k2, d2 = descriptor.compute(img2, kp2)print '#Descriptors size in image1: %s, image2: %s' % ((d1.shape), (d2.shape))

Descriptors size in image1: (1000, 64), image2: (1000, 64)

# match the keypoints
matches = matcher.match(d1,d2)# visualize the matches
print '#matches:', len(matches)
dist = [m.distance for m in matches]print 'distance: min: %.3f' % min(dist)
print 'distance: mean: %.3f' % (sum(dist) / len(dist))
print 'distance: max: %.3f' % max(dist)

matches: 1000

distance: min: 0.000

distance: mean: 0.000

distance: max: 0.000

# threshold: half the mean
thres_dist = (sum(dist) / len(dist)) * 0.5 + 0.5# keep only the reasonable matches
sel_matches = [m for m in matches if m.distance < thres_dist]print '#selected matches:', len(sel_matches)

selected matches: 1000

#Plot
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
view = zeros((max(h1, h2), w1 + w2, 3), uint8)
view[:h1, :w1, 0] = img1
view[:h2, w1:, 0] = img2
view[:, :, 1] = view[:, :, 0]
view[:, :, 2] = view[:, :, 0]for m in sel_matches:# draw the keypoints# print m.queryIdx, m.trainIdx, m.distancecolor = tuple([random.randint(0, 255) for _ in xrange(3)])pt1=(int(k1[m.queryIdx].pt[0]),int(k1[m.queryIdx].pt[1]))pt2=(int(k2[m.queryIdx].pt[0]+w1),int(k2[m.queryIdx].pt[1]))cv2.line(view,pt1,pt2,color)

Output is something like this https://i.stack.imgur.com/8CqrJ.png

https://en.xdnf.cn/q/71895.html

Related Q&A

Realtime processing and callbacks with Python and C++

I need to write code to do some realtime processing that is fairly computationally complex. I would like to create some Python classes to manage all my scripting, and leave the intensive parts of the a…

How can I troubleshoot a segmentation fault when working with Python Ctypes and C++?

Lets say I have the following two function signatures in C++:BYTE* init( BYTE* Options, BYTE* Buffer )and:int next( BYTE* interface, BYTE* Buffer )The idea is that I first initialize an Interface class…

Undefined variable from import when using protocol buffers in PyDev

Ive got a PyDev project that uses protocol buffers. The protocol buffer files are located in a zip file generated by the protoc compiler. Everything works when I run the program, however PyDev reports …

Animating a network graph to show the progress of an algorithm

I would like to animate a network graph to show the progress of an algorithm. I am using NetworkX for graph creation. From this SO answer, I came up with a solution using clear_ouput from IPython.displ…

How to run grpc on ipv4 only

Im going to run a grpc server on IPv4 address like this: server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) protoc_pb2_grpc.add_ProtocServicer_to_server(StockProtocServicer(), server) ser…

Python/PyCharm mark unused import as used

I need to import a resource_rc.py file in my module. It is immediately marked by PyCharm as "unused". Is there a way to mark "unused" imports and also variables, etc. as used in Pyt…

Replacing every 2nd element in the list

I got a 2 dimensional list:[[5, 80, 2, 57, 5, 97], [2, 78, 2, 56, 6, 62], [5, 34, 3, 54, 6, 5, 2, 58, 5, 61, 5, 16]]In which I need to change every second element to 0, starting from first one. So it s…

Are C++-style internal typedefs possible in Cython?

In C++ its possible to declare type aliases that are members of a class or struct:struct Foo {// internal type aliastypedef int DataType;// ... };Is there any way to do the same thing in Cython? Ive t…

How do I use a regular expression to match a name?

I am a newbie in Python. I want to write a regular expression for some name checking. My input string can contain a-z, A-Z, 0-9, and _ , but it should start with either a-z or A-Z (not 0-9 and _ ). I…

python - multiprocessing module

Heres what I am trying to accomplish - I have about a million files which I need to parse & append the parsed content to a single file. Since a single process takes ages, this option is out. Not us…