gpt4 book ai didi

python - OpenCV - Python Bag Of Words(BoW)从字典生成直方图

转载 作者:太空宇宙 更新时间:2023-11-03 22:48:46 24 4
gpt4 key购买 nike

我一直在尝试使用关键点和词袋技术在 Python OpenCV 3.2.0 中创建图像分类器。经过一番阅读后,我发现我可以按如下方式执行此操作

  1. 使用 AKAZE 提取图像描述符
  2. 对描述符进行k-means聚类生成字典
  3. 根据字典生成图像的直方图
  4. 使用直方图训练 SVM

我设法完成了第 1 步和第 2 步,但在第 3 步和第 4 步时卡住了。

我使用 k 均值聚类成功返回的标签生成了直方图(我认为)。但是,当我想使用未用于生成字典的新测试数据时,我得到了一些意想不到的结果。我尝试使用像这样的 FLANN 匹配器 tutorial但是我从标签数据生成直方图得到的结果与 FLANN 匹配返回的数据不匹配。

我加载图像:

dictionary_size = 512
# Loading images
imgs_data = []
# imreads returns a list of all images in that directory
imgs = imreads(imgs_path)
for i in xrange(len(imgs)):
# create a numpy to hold the histogram for each image
imgs_data.insert(i, np.zeros((dictionary_size, 1)))

然后我创建一个描述符数组 (desc):

def get_descriptors(img, detector):
# returns descriptors of an image
return detector.detectAndCompute(img, None)[1]

# Extracting descriptors
detector = cv2.AKAZE_create()

desc = np.array([])
# desc_src_img is a list which says which image a descriptor belongs to
desc_src_img = []
for i in xrange(len(imgs)):
img = imgs[i]
descriptors = get_descriptors(img, detector)
if len(desc) == 0:
desc = np.array(descriptors)
else:
desc = np.vstack((desc, descriptors))
# Keep track of which image a descriptor belongs to
for j in range(len(descriptors)):
desc_src_img.append(i)
# important, cv2.kmeans only accepts type32 descriptors
desc = np.float32(desc)

然后使用 k-means 对描述符进行聚类:

# Clustering
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 0.01)
flags = cv2.KMEANS_PP_CENTERS
# desc is a type32 numpy array of vstacked descriptors
compactness, labels, dictionary = cv2.kmeans(desc, dictionary_size, None, criteria, 1, flags)

然后我使用从 k-means 返回的标签为每个图像创建直方图:

# Getting histograms from labels
size = labels.shape[0] * labels.shape[1]
for i in xrange(size):
label = labels[i]
# Get this descriptors image id
img_id = desc_src_img[i]
# imgs_data is a list of the same size as the number of images
data = imgs_data[img_id]
# data is a numpy array of size (dictionary_size, 1) filled with zeros
data[label] += 1

ax = plt.subplot(311)
ax.set_title("Histogram from labels")
ax.set_xlabel("Visual words")
ax.set_ylabel("Frequency")
ax.plot(imgs_data[0].ravel())

这会输出这样的直方图 Label Histogram分布非常均匀,符合我的预期。

然后我尝试在同一张图片上做同样的事情,但使用的是 FLANN:

matcher = cv2.FlannBasedMatcher_create()
matcher.add(dictionary)
matcher.train()

descriptors = get_descriptors(imgs[0], detector)

result = np.zeros((dictionary_size, 1), np.float32)
# flan matcher needs descriptors to be type32
matches = matcher.match(np.float32(descriptors))
for match in matches:
visual_word = match.trainIdx
result[visual_word] += 1

ax = plt.subplot(313)
ax.set_title("Histogram from FLANN")
ax.set_xlabel("Visual words")
ax.set_ylabel("Frequency")
ax.plot(result.ravel())

这会输出这样的直方图 FLANN Histogram分布非常不均匀,与第一个直方图不匹配。

您可以在 GitHub 上查看完整代码和图片.在运行之前将“imgs_path”(第 20 行)更改为包含图像的目录。

我哪里错了?为什么直方图如此不同?如何使用字典为新数据生成直方图?

作为旁注,我尝试使用 OpenCV BOW 实现,但发现另一个问题,它给出了错误:“_queryDescriptors.type() == trainDescType in function cv::BFMatcher::knnMatchImpl”这就是我尝试自己实现的原因。如果有人可以提供一个使用 Python OpenCV BOW 和 AKAZE 的工作示例,那就再好不过了。

最佳答案

看来你不能事先使用字典训练 FlannBasedMatcher,如下所示:

matcher = cv2.FlannBasedMatcher_create()
matcher.add(dictionary)
matcher.train()

但是你可以像这样在匹配时传入字典:

matcher = cv2.FlannBasedMatcher_create()

...

matches = matcher.match(np.float32(descriptors), dictionary)

我不完全确定这是为什么。也许 train 方法仅供 match 方法使用,如 post 中所暗示的那样.

同样根据opencv docs match 的参数是:

  • queryDescriptors – Query set of descriptors.
  • trainDescriptors – Train set of descriptors. This set is not added to the train descriptors collection stored in the class object.
  • matches – Matches. If a query descriptor is masked out in mask , no match is added for this descriptor. So, matches size may be smaller than the query descriptors count.

所以我猜你应该将 dictionary 作为 trainDescriptors 传递进去,因为它就是这样。

如果有人能对此有更多的了解,我们将不胜感激。

下面是使用上述方法后的结果:

The two histograms; one generated from labels and one generated from the flann matches

您可以看到完整的更新代码 here .

关于python - OpenCV - Python Bag Of Words(BoW)从字典生成直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43104111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com