文章参考来自:
https://blog.csdn.net/qq_23981335/article/details/80525642
https://blog.csdn.net/runner668/article/details/80404737
这里提供了一种把图片转换成tfrecords文件的方法。
先介绍下图片解码的两种方法:
第一种方法是用tf.gfile.FastGFile读取图片,然后进行解码,再把图片转换成tf.float32;
# 读取图片
img = tf.gfile.FastGFile('img/img1/'+imgpath, 'rb').read()
# 解码图片(如果是 png 格式就使用tf.image.decode_png))
img = tf.image.decode_jpeg(img)
# 图片归一化,[0,1],浮点类型数据。因为为了将图片数据能够保存到 TFRecord 结构体中,所以需要将其图片矩阵转换成 string,
# 所以为了在使用时能够转换回来,这里确定下数据格式为 tf.float32
img = tf.image.convert_image_dtype(img, dtype=tf.float32)
第二种方法则是直接读取即可 bytes。
img = Image.open('img/img1/'+imgpath)
img_raw = img.tobytes() # 将图片转化为原生bytes
首先,贴出第一种方法:
背景:文件夹中有两种图片,txt中是两张图片的文件名,如下:
代码如下:
# -*- coding:utf-8 -*-
# 将图片保存成 TFRecord
import tensorflow as tf
import numpy as np
savedir = "data/tf2.tfrecords" # 希望在data/文件夹中生成“data.tfrecords"的TFRecord格式文件
#把标签转换成tfrecord文件需要的格式:int64_list
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
#转换成字节流
def _bytes_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def load(imgdir, width, height, method=0):
# 准备一个 writer 用来写 TFRecord 文件
writer = tf.python_io.TFRecordWriter(savedir) #在‘savedir’路径下生成一个tf文件
imglist = open(imgdir, 'r')
with tf.Session() as sess:
for line in imglist: # open 打开的文件返回对象是一个可迭代对象,直接用 for 迭代访问
# 获得图片的路径和类型
tmp = line.strip().split(' ') # str.strip([chars])用于去除头尾的字符chars,为空时默认删除空白符;
while '' in tmp:
tmp.remove('')
imgpath = tmp[0] # 字符串列表tmp中tmp[0]代表该图像的路径
label = int(tmp[1]) # 字符串列表tmp中tmp[1]代表该图像的标签
print(tmp)
# 读取图片
img = tf.gfile.FastGFile('img/img1/'+imgpath, 'rb').read()
# 解码图片(如果是 png 格式就使用tf.image.decode_png))
img = tf.image.decode_jpeg(img)
# 图片归一化,[0,1],浮点类型数据。因为为了将图片数据能够保存到 TFRecord 结构体中,所以需要将其图片矩阵转换成 string,
# 所以为了在使用时能够转换回来,这里确定下数据格式为 tf.float32
img = tf.image.convert_image_dtype(img, dtype=tf.float32)
# 把图片转换成希望的大小,由于本例子中两张图片大小都是650*434,所以此步骤可以省略。要注意的时候resize_images中输入图片的宽、高顺序
img = tf.image.resize_images(img, [height, width], method)
# 执行op:image
img = sess.run(img)
# 将其图片矩阵转换成string
img_raw = img.tostring()
# 将数据整理成 TFRecord 需要的数据结构
example = tf.train.Example(features=tf.train.Features(feature= \
{'imge_raw': _bytes_feature(img_raw),
'label': _int64_feature(label)}))
# 写入TFRecord
# SerializeToString()作用:把example序列化为一个字符串,因为在写入到TFRcorde的时候,write方法的参数是字符串的.
writer.write(example.SerializeToString())
writer.close()
if __name__ == '__main__':
load("img/img1/data.txt", 650, 434)
结果如下,生成了一个tf文件:
第二种方法把上面读取照片的方法替换一下即可,这里不过多描述了。
其实转tf文件的格式很简单,基本结构如下:
1.先创建一个tf文件,用于写入
2.读取标签(可按自己的风格定义标签,比如:男、女)
3.读取照片,并转成tf的格式(如:字节流)
4.构建一个字典:tf.train.Example,就是将数据整理成 TFRecord 需要的数据结构
5.write,把数据写入tf文件
import tensorflow as tf
import numpy as np
tfrecords_filename = 'tf/tf1.tfrecords'
writer = tf.python_io.TFRecordWriter(tfrecords_filename) # 创建.tfrecord文件,准备写入
for i in range(100):
img_raw = np.random.random_integers(0, 255, size=(7, 30)) # 创建7*30,取值在0-255之间随机数组
img_raw = img_raw.tostring() #把数组转成tf的格式,用随机数组代替照片——图片的本质就是数组,因此这里也可以用数组替代
example = tf.train.Example(features=tf.train.Features(
feature={
'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[i])), #标签
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])) #图片
}))
writer.write(example.SerializeToString())
writer.close()