1.源程序:
最近使用了官方Tensorflow的关于花朵分类迁移学习的代码,想要测试单张或者几张图片的分类识别效果。找了好久。总算是找到了一个可用的程序,贴出来:
import tensorflow as tf
import numpy as np
import glob
import os.path
import tensorflow as tf
import numpy as np
import cv2
# 模型目录
CHECKPOINT_DIR = './ckpt/checkpoints/' #训练后生成的检查点文件夹,在当前工程下。
INCEPTION_MODEL_FILE = './inception_dec_2015/tensorflow_inception_graph.pb'
# inception-v3模型参数
BOTTLENECK_TENSOR_NAME = 'pool_3/_reshape:0' # inception-v3模型中代表瓶颈层结果的张量名称
JPEG_DATA_TENSOR_NAME = 'DecodeJpeg/contents:0' # 图像输入张量对应的名称
# 测试数据
#path = './test/33.jpg' #这里选择一张图片用于测试,该图片属于sunflower类别的花。
#类别字典
strings = ['0005', '0003', '0001', '0002', '0007','0009']
def id_to_string(node_id):
return strings[node_id]
# 读取数据
#image_data = tf.gfile.FastGFile(path, 'rb').read()
# 评估
checkpoint_file = tf.train.latest_checkpoint(CHECKPOINT_DIR)
with tf.Graph().as_default() as graph:
with tf.Session().as_default() as sess:
# 读取训练好的inception-v3模型
with tf.gfile.FastGFile(INCEPTION_MODEL_FILE, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# 加载inception-v3模型,并返回瓶颈层输出张量和数据输入张量
bottleneck_tensor, jpeg_data_tensor = tf.import_graph_def(
graph_def,
return_elements=[BOTTLENECK_TENSOR_NAME, JPEG_DATA_TENSOR_NAME])
# 使用inception-v3处理图片获取特征向量
#bottleneck_values = sess.run(bottleneck_tensor,{jpeg_data_tensor: image_data})
# 将四维数组压缩成一维数组,由于全连接层输入时有batch的维度,所以用列表作为输入 // add_FC_layer true imagedata
#bottleneck_values = [np.squeeze(bottleneck_values)]
# 加载图和变量(这里我选择的是step=200的图,使用的是绝对路径。)
saver = tf.train.import_meta_graph('ckpt/best_0.987500.ckpt-800.meta')
saver.restore(sess, tf.train.latest_checkpoint('./ckpt/'))
softmax_tensor = sess.graph.get_tensor_by_name('final_training_ops/prob:0')
# 通过名字从图中获取输入占位符 (add_FC_layer input placeholder )
input_x = graph.get_operation_by_name(
'BottleneckInputPlaceholder').outputs[0]
for root, dirs, files in os.walk('./test/'):
for file in files:
#
image_data = tf.gfile.FastGFile(os.path.join(root, file), 'rb').read()
print(type(image_data))
# 使用inception-v3处理图片获取特征向量
bottleneck_values = sess.run(bottleneck_tensor,{jpeg_data_tensor: image_data}) #resource data process use inceptipnv3
# 将四维数组压缩成一维数组,由于全连接层输入时有batch的维度,所以用列表作为输入 // add_FC_layer true imagedata
bottleneck_values = [np.squeeze(bottleneck_values)]
predictions = sess.run(softmax_tensor, {input_x: bottleneck_values}) #
predictions = np.squeeze(predictions) #
#
image_path = os.path.join(root, file)
print(image_path)
#
top_k = predictions.argsort()[::-1] #从最后一个元素到第一个元素复制一遍 argsort将x中的元素index值 从小到大排列
#print(top_k)
human_string = id_to_string(top_k[0]) #得到对应标签
# for node_id in top_k:
# #
# human_string = id_to_string(node_id)
# #
# score = predictions[node_id]
# print('%s (score = %.5f)' % (human_string, score))
# print()
print('(预测为%s类)' % human_string)
img = cv2.imread(image_path)
cv2.imshow('image', img)
#cv2.waitKey(0)
cv2.destroyAllWindows()
2.场景2 上面场景1是自己从本地传入的图。也就是用了这个函数:
image_data = tf.gfile.FastGFile(os.path.join(root, file), 'rb').read()
现在我需要载入opencv resize 之后得到的path 这个变量。他是numpy数据类型。而上面代码1直接导入运行的是bytes(string)格式。所以需要经过一定的处理,将resize得到的图像转换为能够使用的tf.string格式。试了很多种方式,最终得到了我想要的。
即OpenCV的图像转换为字节字符串的方式为:
如果有一个图像img(这是一个numpy数组),您可以使用以下命令将其转换为字符串:
>>> img_str = cv2.imencode('.jpg', img)[1].tostring()
>>> type(img_str)
'str'
参考:https://codeday.me/bug/20181211/436854.html
完整代码:
import tensorflow as tf
import numpy as np
import glob
import os.path
import tensorflow as tf
import numpy as np
import cv2
import sys
sys.path.append('/mnt/4T/ycc/cnn mnistdata/personclassify_transfer')
#from io import BytesIO
from PIL import Image
# 模型目录
CHECKPOINT_DIR = '/mnt/4T/ycc/cnn mnistdata/personclassify_transfer/ckpt/checkpoints/' #训练后生成的检查点文件夹,在当前工程下。
INCEPTION_MODEL_FILE = '/mnt/4T/ycc/cnn mnistdata/personclassify_transfer/inception_dec_2015/tensorflow_inception_graph.pb'
# inception-v3模型参数
BOTTLENECK_TENSOR_NAME = 'pool_3/_reshape:0' # inception-v3模型中代表瓶颈层结果的张量名称
JPEG_DATA_TENSOR_NAME = 'DecodeJpeg/contents:0' # 图像输入张量对应的名称
# 测试数据
#path = './test/001.jpg' #这里选择一张图片用于测试,该图片属于sunflower类别的花。
#类别字典
strings = ['0005', '0003', '0001', '0002', '0007','0009']
def id_to_string(node_id):
return strings[node_id]
def predictions(path):
# 读取数据
#image_data = tf.gfile.FastGFile(path, 'rb').read()
#cv2.imshow('draw',path)
# 评估
checkpoint_file = tf.train.latest_checkpoint(CHECKPOINT_DIR)
with tf.Graph().as_default() as graph:
with tf.Session().as_default() as sess:
# 读取训练好的inception-v3模型
with tf.gfile.FastGFile(INCEPTION_MODEL_FILE, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# 加载inception-v3模型,并返回瓶颈层输出张量和数据输入张量
bottleneck_tensor, jpeg_data_tensor = tf.import_graph_def(graph_def,return_elements=[BOTTLENECK_TENSOR_NAME, JPEG_DATA_TENSOR_NAME])
# 使用inception-v3处理图片获取特征向量
#bottleneck_values = sess.run(bottleneck_tensor,{jpeg_data_tensor: image_data})
# 将四维数组压缩成一维数组,由于全连接层输入时有batch的维度,所以用列表作为输入 // add_FC_layer true imagedata
#bottleneck_values = [np.squeeze(bottleneck_values)]
# 加载图和变量(这里我选择的是step=200的图,使用的是绝对路径。)
saver = tf.train.import_meta_graph('/mnt/4T/ycc/cnn mnistdata/personclassify_transfer/ckpt/best_0.987500.ckpt-800.meta')
saver.restore(sess, tf.train.latest_checkpoint('/mnt/4T/ycc/cnn mnistdata/personclassify_transfer/ckpt/'))
softmax_tensor = sess.graph.get_tensor_by_name('final_training_ops/prob:0')
# 通过名字从图中获取输入占位符 (add_FC_layer input placeholder )
input_x = graph.get_operation_by_name(
'BottleneckInputPlaceholder').outputs[0]
print("out2=",type(path))
#path这里是从opencv传入的resize过的图像,原始为numpy数据类型,现在需要转换为bytes/string类型
image_data = cv2.imencode('.jpg', path)[1].tostring()
print("out2=",type(image_data))
#image_data = imageBuf.getvalue()
#path=np.asarray(path, np.float32)
#image_data = tf.convert_to_tensor(path, np.float32)
#png_data = tf.placeholder(tf.string, shape=[])
#image_data = tf.image.decode_png(path, channels=3)
# 使用inception-v3处理图片获取特征向量
bottleneck_values = sess.run(bottleneck_tensor,{jpeg_data_tensor: image_data}) #resource data process use inceptipnv3
# 将四维数组压缩成一维数组,由于全连接层输入时有batch的维度,所以用列表作为输入 // add_FC_layer true imagedata
bottleneck_values = [np.squeeze(bottleneck_values)]
predictions = sess.run(softmax_tensor, {input_x: bottleneck_values}) #
predictions = np.squeeze(predictions) #
#
#image_path = os.path.basename(path)
#print(image_path)
#
top_k = predictions.argsort()[::-1] #从最后一个元素到第一个元素复制一遍 argsort将x中的元素index值 从小到大排列
#print(top_k)
human_string = id_to_string(top_k[0]) #得到对应标签
# for node_id in top_k:
# #
# human_string = id_to_string(node_id)
# #
# score = predictions[node_id]
# print('%s (score = %.5f)' % (human_string, score))
# print()
print('(预测为%s类)' % human_string)
# img = cv2.imread(image_path)
# cv2.imshow('image', img)
#cv2.waitKey(0)
return human_string
#cv2.destroyAllWindows()
TIPS:以上的训练测试源码:链接:https://pan.baidu.com/s/16kj68OGYLu0bwQ1Winqm1g 提取码:9eun
基于inception的迁移学习图片分类单(多)张图片测试代码。训练测试全套源码; 注:数据集格式为flowerdata放到与训练测试代码一个目录下,且数据集里的多个文件夹代表多个类别(例如:以花类别为例子)
如果有c币也可以下载csdn的支持下,代码打包是一样的。https://download.youkuaiyun.com/download/ycc2011/11178612
(csdn已经不能自定义1个币下载了,所以很无奈)