直方图构建图像搜索引擎二
Hobbits and Histograms – A How-To Guide to Building Your First Image Search Engine in Python(直方图构建图像搜索引擎二)
英文原文
直方图构建图像搜索引擎一
translator:aaron-clark-aic
如何建立第一个Python图像搜索引擎
前面一章我们已经建立了基于色彩统计的彩色直方图。原作者的数据库中包含了25张对比图片(取材于霍比特人),我直接在百度上面找几张替代这些原数据。使用一个图像描述器来定义一张图像,图像描述器的输出是一个特征向量。使用两个特征向量进行比较就能够得到距离矩阵(前一篇文中提到的卡方分布Chi-squared)。
第一步:描述一个RGB的三通道图像
前一篇我们使用了一个RGB图像的32份粒度的三通道彩色直方图。
# load the image and show it
image = cv.imread(".././img/base.jpg")
# cv.imshow("image", image)
# grab the image channels, initialize the tuple of colors,
# the figure and the flattened feature vector
chans = cv.split(image)
hist3 = cv.calcHist([chans[0], chans[1], chans[2]], [0, 1, 2],
None, [32, 32, 32], [0, 255, 0, 255, 0, 255])
flatten_base = hist3.flatten()
第二步: 编撰备选图像数据库的索引
index = {}
for imagePath in list_images(".././img/imgDataset"):
# extract our unique image ID (i.e. the filename)
k = imagePath[imagePath.rfind("/") + 1:]
# load the image, describe it using our RGB histogram
# descriptor, and update the index
image_i = cv.imread(imagePath)
chans = cv.split(image_i)
hist3 = cv.calcHist([chans[0], chans[1], chans[2]], [0, 1, 2],
None, [32, 32, 32], [0, 255, 0, 255, 0, 255])
features = hist3.flatten()
index[k] = features
第三步:查找
def chi2_distance( histA, histB, eps=1e-10):
# compute the chi-squared distance
d = 0.5 * np.sum([((a - b) ** 2) / (a + b + eps)
for (a, b) in zip(histA, histB)])
# return the chi-squared distance
return d
results = {}
for (k, features) in index.items():
# compute the chi-squared distance between the features
# in our index and our query features -- using the
# chi-squared distance which is normally used in the
# computer vision field to compare histograms
d = chi2_distance(features, flatten_base)
# now that we have the distance between the two feature
# vectors, we can udpate the results dictionary -- the
# key is the current image ID in the index and the
# value is the distance we just computed, representing
# how 'similar' the image in the index is to our query
results[k] = d
# sort our results, so that the smaller distances (i.e. the
# more relevant images are at the front of the list)
results = sorted([(v, k) for (k, v) in results.items()])
第四步:匹配结果
fig = plt.figure()
ax = fig.add_subplot(711)
ax.set_title("base image")
ax.imshow(image)
for j in range(0,3):
(score, imageName) = results[j]
path = os.path.join(".././img/", imageName)
result = cv.imread(path)
print("\t{}. {} : {:.3f}".format(j + 1, imageName, score))
index_i = 714+2*j-1
ax = fig.add_subplot(str(index_i))
ax.set_title(str((score, imageName)))
ax.imshow(result)