OpenCV:从用户定义的关键点中提取 SURF 特征
Posted
技术标签:
【中文标题】OpenCV:从用户定义的关键点中提取 SURF 特征【英文标题】:OpenCV: Extract SURF Features from user-defined keypoints 【发布时间】:2012-07-30 13:22:31 【问题描述】:我想从我指定的关键点计算 SURF 特征。我正在使用 OpenCV 的 Python 包装器。以下是我尝试使用的代码,但我在任何地方都找不到工作示例。
surf = cv2.SURF()
keypoints, descriptors = surf.detect(np.asarray(image[:,:]),None,useProvidedKeypoints = True)
如何指定此函数要使用的关键点?
类似的,未回答的问题: cvExtractSURF don't work when useProvidedKeypoints = true
Documentation
【问题讨论】:
你最终让它工作了吗? 我做了,我什至在这里发布了答案,但我只是注意到它由于某种原因被删除了。奇怪的。无论如何,您可以使用Mahotas 来执行此操作,或者查看同时发布的其他一些答案。 【参考方案1】:如果我正确理解 Python 绑定的源代码,则 C++ 接口中的“关键点”参数永远不会在 Python 绑定中使用。所以我冒着风险,用当前的绑定做你想做的事情是不可能的。一个可能的解决方案是编写自己的绑定。我知道这不是您希望的答案...
【讨论】:
我开始怀疑实际上是一样的......我已经开始研究使用 Python 库进行 SURF,例如 Python Mahotas 不过,编写自己的绑定到自己的自定义函数应该不会太难。 mahotas 的作者在这里:mahotas 可以为所欲为。【参考方案2】:尝试为此使用 cv2.DescriptorMatcher_create。
例如,在下面的代码中我使用的是 pylab,但你可以得到消息;)
它使用 GFTT 计算关键点,然后使用 SURF 描述符和蛮力匹配。 每个代码部分的输出显示为标题。
%pylab inline
import cv2
import numpy as np
img = cv2.imread('./img/nail.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imshow(gray, cmap=cm.gray)
输出类似于http://i.stack.imgur.com/8eOTe.png
(对于这个例子,我将作弊并使用相同的图像来获取关键点和描述符)。
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))
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))
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)
匹配数:1000
距离:分钟:0.000
距离:平均值:0.000
距离:最大: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)
选定的匹配项: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.distance
color = 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)
输出类似于http://i.stack.imgur.com/8CqrJ.png
【讨论】:
【参考方案3】:如何使用前面提到的Mahotas
完成此操作的示例:
import mahotas
from mahotas.features import surf
import numpy as np
def process_image(imagename):
'''Process an image and returns descriptors and keypoints location'''
# Load the images
f = mahotas.imread(imagename, as_grey=True)
f = f.astype(np.uint8)
spoints = surf.dense(f, spacing=12, include_interest_point=True)
# spoints includes both the detection information (such as the position
# and the scale) as well as the descriptor (i.e., what the area around
# the point looks like). We only want to use the descriptor for
# clustering. The descriptor starts at position 5:
desc = spoints[:, 5:]
kp = spoints[:, :2]
return kp, desc
【讨论】:
以上是关于OpenCV:从用户定义的关键点中提取 SURF 特征的主要内容,如果未能解决你的问题,请参考以下文章
如何访问SURF的关键点的特征尺度和主导方向在Python?