文中源码可在微信公众年夜众号「01 二进制」后台回答「图像检索」获取。

序言

在上一篇文章《图像检索系列——利用 Python 检测图像相似度》中,我们先容了一个在图像检索领域非常常用的算法——感知哈希算法。
这是一个很大略且快速的算法,其事理在于针对每一张图片都天生一个特定的“指纹”,然后采纳一种相似度的度量办法得出两张图片的近似程度。

然而随着深度学习的崛起,极大的推动了图像领域的发展,在提取特色这方面而言,神经网络目前有着不可替代的上风。
在上一篇文章中我们也先容了图像检索每每是基于图像的特色比较,看特色匹配的程度有多少,从而检索出相似度高的图片。
而检测图像特色,VGG16 具有得天独厚的上风。

php搜图源码图像检索系列应用深度进修实现以图搜图 Node.js

接下来本文将会通过一个大略的案例来实现一个基于深度学习的图像检索小工具。

准备事情

老样子,先来准备好我们这次须要利用到的工具:

IDE:PycharmPython:3.7Packages:Keras + TensorFlow + Pillow + Numpy

keras

Keras 是一个高层神经网络 API,Keras 由纯 Python 编写而成并基Tensorflow、Theano以及CNTK后端。
大略来说,keras 便是对 TF 等框架的再一次封装,使得利用起来更加方便。

基于 vgg16 网络提取图像特色我们都知道,vgg 网络在图像领域有着广泛的运用,后续许多层次更深,网络更宽的模型都是基于此扩展的,vgg 网络能很好的提取到图片的有用特色,本次实现是基于 Keras 实现的,提取的是末了一层卷积特色。

思路

紧张思路是基于 CVPR2015 的论文《Deep Learning of Binary Hash Codes for Fast Image Retrieval》实现的海量数据下的基于内容图片检索系统。
大略说来便是对图片数据库的每张图片抽取特色(一样平常形式为特色向量),存储于数据库中,对付待检索图片,抽取同样的特色向量,然后并对该向量和数据库中向量的间隔(相似度打算),找出最靠近的一些特色向量,其对应的图片即为检索结果。
如下图所示:

用户要乞降预处理部分紧张是 Web 做事端该当做的,这里不加以谈论,接下来我们紧张进行红线标注部分的实现。

实操提取图片特色

keras 在个中文文档中供应了一个利用 VGG16 提取特色的 demo

from keras.applications.vgg16 import VGG16from keras.preprocessing import imagefrom keras.applications.vgg16 import preprocess_inputimport numpy as npmodel = VGG16(weights='imagenet', include_top=False)img_path = 'elephant.jpg'img = image.load_img(img_path, target_size=(224, 224))x = image.img_to_array(img)x = np.expand_dims(x, axis=0)x = preprocess_input(x)features = model.predict(x)

这里我们须要对其进行大略修正,封装成一个类以便后期调用。
如下图所示:

考虑到篇幅,文中代码图片已删除较多注释,如需理解详细注释信息,可在微信"大众年夜众号「01 二进制」后台回答「图像检索」获取源代码。
下同

将特色以及对应的文件名保存为 h5 文件什么是 h5 文件

h5 文件是层次数据格式第 5 代的版本(Hierarchical Data Format,HDF5),用以存储和组织大规模数据。

H5 将文件构造简化成两个紧张的工具类型:

数据集 dataset,便是同一类型数据的多维数组组 group,是一种容器构造,可以包含数据集和其他组,若一个文件中存放了不同种类的数据集,这些数据集的管理就用到了 group

直不雅观的理解,可以参考我们的文件系统,不同的文件存放在不同的目录下:

目录便是 hdf5 文件中的 group,描述了数据集 DataSet 的分类信息,通过 group 有效的将多种 dataset 进行管理和划分。
文件便是 hdf5 文件中的 dataset,表示详细的数据

下图便是数据集和组的关系:

在 Python 中,我们常日利用 h5py 库对 .h5 文件进行操作,详细的读写方法自行百度,这里不在演示。

抽取数据集中的图像特色保存到 h5 文件中

我们在项目根目录下命名一个 database 文件夹作为数据集,然后编写一个获取文件夹内图片的方法:

def get_imlist(path): return [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.jpg')]

随后我们便可以依次读取数据然后,逐一提取其特色保存到文件中了。
如下图:

至此,我们就已经算是完成了模型的演习了。

选一张测试图片测试检索效果

经由上述操作,我们已经将数据集中的所有图片的特色保存到模型中了,剩下的便是抽取待测图片的特色,然后和特色集中的特色逐一比较向量间的相似度(余弦相似度),然后按照相似度排序返回给用户即可。

Tips:各种相似度的 Python 表示可以参考Python Numpy 打算各种间隔

以某一个包包为测试图片,输出结果如下所示:

在 PyCharm 中可以很方便的查看 matplotlib 天生的图片,第一张为测试图片,后面三张为检索图片,可以看出效果相称好了。

Tips:如果想用 Resnet 或者 Densenet 提取特色,只需针对上述代码做出相应的修正,去掉注释修正部分代码即可。
详见源码。

末了

至此我们已经利用深度学习实现了一个图片检索的小工具了,如何将其和 web/app 结合到一起就不在本文的谈论范围了,有兴趣可以下载本文源码自行变动,也可扫描下方二维码关注微信"大众号「01 二进制」与我取得联系。