个人说明
本人是编程业余爱好者,最近看上人工智能技术,先着手于以图搜图应用,因为并没有专业的知识,用词会显得不专业。本系列文章编码都是来自于网络搜索,自己总结首先致力于实用,然后再细细研究原理等,也希望更多的人加入交流,不要嫌弃我的水平。
系列说明
这里默认tensorflow+vgg16已经安装完毕,如果有人不懂安装,可以下面反馈我另外写一篇搭建:
- 电脑配置 :个人使用的是dellD630电脑,双核+5G内存+win764位;
- tensorflow版本:由于电脑很老,tensorflow没有用最新版本,为什么?安装最新版本报错了,所以退回,自己根据自己电脑情况安装tensorflow,遇到问题再看。
- 其他包 :使用代码可能还依赖其他包,代码使用过程中根据错误提示,缺啥补啥就行了,;
- 其他问题 :之前在Ubuntu上玩,但是觉得有点不方便,就回win下,代码无影响,只是修改代码里面的文件路径就可以用;
搜图逻辑
从倒序的逻辑讲,拿到一个图片,首先要对这个图片生成一个标识(也就是特征),然后在一大堆标识库中对比和他相似的,这里肯定会返回一些对比结果类的,最后后再对这个结果排序显示出来就完成。所以理清搜图本质:
1.将图片转换成一种数字标识(特征)。
2.搜图其实是文字(特征)对比过程。
下面要做的是将图片先变成标识,也就是特征提取,然后保存。
文件夹图库特征提取
# -*- coding: utf-8 -*-
import vgg16
import tensorflow as tf
import utils
import cv2
import numpy as np
from scipy.linalg import norm
import os
import time
images = tf.placeholder(dtype=tf.float32, shape=[None, 224, 224, 3])
vgg = vgg16.Vgg16()
vgg.build(images)
def get_feats_dirs(imagefold):
vgg16_feats = np.zeros((27, 4096)) //这可能是生成一个矩阵,27是我这个文件夹里图片的各数,4096是特征码的长度
for root, dirs, files in os.walk(imagefold):
with tf.Session() as sess:
start00=time.clock()
for i in range(len(files)):
imagePath= root + '\\' + files[i] //拼凑图片路径
start1=time.clock()
print("开始对 %d 生成特征: %s\n" % (i, imagePath))
img_list = utils.load_image(imagePath)//加载图片
start2= time.clock()
print("载入图片花费:%ds" % (time.clock() - start1))
batch = img_list.reshape((1, 224, 224, 3))//可以叫做对图片格式化吧,做成vgg16的标准格式
start4 = time.clock()
feature = sess.run(vgg.fc6, feed_dict={images: batch})#喂入图片,提取fc6层的特征
start3 = time.clock()
feature = np.reshape(feature, [4096])
feature /= norm(feature) # 特征归一化
feature=np.array(feature)
vgg16_feats[i, :] = feature #每张图片的特征向量为1行
dict1.update({i:imagePath})
print("完成生成特征,花费:%ds\n" % (time.clock()-start1))
print("完成所有,总花费:%ds/%d\n"%(time.clock()-start00,len(dict1)))
vgg16_feats = np.save( r'd:\\config\\feats', vgg16_feats)//保存所有特征
return vgg16_feats
if __name__ == '__main__':
get_feats_dirs("D:\\pic")
遗留问题
我们发现第一张图片生成特征的时间异常夸张,后面会趋于下降直至平稳。我完全不知道这是什么原因造成的,模型在程序调用方法前也已经载入,这到底是什么原因,有没有什么方法可以让生成第一张图片特征的时候就是下面稳定的时间呢。欢迎指教哦。`.