浅谈TensorFlow中读取图像数据的三种方式


Posted in Python onJune 30, 2020

 本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片、大量图片,和TFRecorder读取方式。并且还补充了功能相近的tf函数。

1、处理单张图片

我们训练完模型之后,常常要用图片测试,有的时候,我们并不需要对很多图像做测试,可能就是几张甚至一张。这种情况下没有必要用队列机制。

import tensorflow as tf
import matplotlib.pyplot as plt

def read_image(file_name):
 img = tf.read_file(filename=file_name)  # 默认读取格式为uint8
 print("img 的类型是",type(img));
 img = tf.image.decode_jpeg(img,channels=0) # channels 为1得到的是灰度图,为0则按照图片格式来读
 return img

def main( ):
 with tf.device("/cpu:0"):

  # img_path是文件所在地址包括文件名称,地址用相对地址或者绝对地址都行 
   img_path='./1.jpg'
   img=read_image(img_path)
   with tf.Session() as sess:
   image_numpy=sess.run(img)
   print(image_numpy)
   print(image_numpy.dtype)
   print(image_numpy.shape)
   plt.imshow(image_numpy)
   plt.show()

if __name__=="__main__":
 main()

"""

输出结果为:

img 的类型是 <class 'tensorflow.python.framework.ops.Tensor'>
[[[196 219 209]
  [196 219 209]
  [196 219 209]
  ...

 [[ 71 106  42]
  [ 59  89  39]
  [ 34  63  19]
  ...
  [ 21  52  46]
  [ 15  45  43]
  [ 22  50  53]]]
uint8
(675, 1200, 3)
"""

 

和tf.read_file用法相似的函数还有tf.gfile.FastGFile  tf.gfile.GFile,只是要指定读取方式是'r' 还是'rb' 。

2、需要读取大量图像用于训练

这种情况就需要使用Tensorflow队列机制。首先是获得每张图片的路径,把他们都放进一个list里面,然后用string_input_producer创建队列,再用tf.WholeFileReader读取。具体请看下例:

def get_image_batch(data_file,batch_size):
 data_names=[os.path.join(data_file,k) for k in os.listdir(data_file)]
 
 #这个num_epochs函数在整个Graph是local Variable,所以在sess.run全局变量的时候也要加上局部变量。 
 filenames_queue=tf.train.string_input_producer(data_names,num_epochs=50,shuffle=True,capacity=512)
 reader=tf.WholeFileReader()
 _,img_bytes=reader.read(filenames_queue)
 image=tf.image.decode_png(img_bytes,channels=1) #读取的是什么格式,就decode什么格式
 #解码成单通道的,并且获得的结果的shape是[?, ?,1],也就是Graph不知道图像的大小,需要set_shape
 image.set_shape([180,180,1]) #set到原本已知图像的大小。或者直接通过tf.image.resize_images,tf.reshape()
 image=tf.image.convert_image_dtype(image,tf.float32)
 #预处理 下面的一句代码可以换成自己想使用的预处理方式
 #image=tf.divide(image,255.0) 
 return tf.train.batch([image],batch_size)

这里的date_file是指文件夹所在的路径,不包括文件名。第一句是遍历指定目录下的文件名称,存放到一个list中。当然这个做法有很多种方法,比如glob.glob,或者tf.train.match_filename_once

全部代码如下:

import tensorflow as tf
import os
def read_image(data_file,batch_size):
 data_names=[os.path.join(data_file,k) for k in os.listdir(data_file)]
 filenames_queue=tf.train.string_input_producer(data_names,num_epochs=5,shuffle=True,capacity=30)
 reader=tf.WholeFileReader()
 _,img_bytes=reader.read(filenames_queue)
 image=tf.image.decode_jpeg(img_bytes,channels=1)
 image=tf.image.resize_images(image,(180,180))

 image=tf.image.convert_image_dtype(image,tf.float32)
 return tf.train.batch([image],batch_size)

def main( ):
 img_path=r'F:\dataSet\WIDER\WIDER_train\images\6--Funeral' #本地的一个数据集目录,有足够的图像
 img=read_image(img_path,batch_size=10)
 image=img[0] #取出每个batch的第一个数据
 print(image)
 init=[tf.global_variables_initializer(),tf.local_variables_initializer()]
 with tf.Session() as sess:
  sess.run(init)
  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(sess=sess,coord=coord)
  try:
   while not coord.should_stop():
    print(image.shape)
  except tf.errors.OutOfRangeError:
   print('read done')
  finally:
   coord.request_stop()
  coord.join(threads)


if __name__=="__main__":
 main()

"""

输出如下:

(180, 180, 1)
(180, 180, 1)
(180, 180, 1)
(180, 180, 1)
(180, 180, 1)
"""

这段代码可以说写的很是规整了。注意到init里面有对local变量的初始化,并且因为用到了队列,当然要告诉电脑什么时候队列开始, tf.train.Coordinator 和 tf.train.start_queue_runners 就是两个管理队列的类,用法如程序所示。

与 tf.train.string_input_producer相似的函数是 tf.train.slice_input_producer。 tf.train.slice_input_producer和tf.train.string_input_producer的第一个参数形式不一样。等有时间再做一个二者比较的博客

 3、对TFRecorder解码获得图像数据

其实这块和上一种方式差不多的,更重要的是怎么生成TFRecorder文件,这一部分我会补充到另一篇博客上。

仍然使用 tf.train.string_input_producer。

import tensorflow as tf
import matplotlib.pyplot as plt
import os
import cv2
import numpy as np
import glob

def read_image(data_file,batch_size):
 files_path=glob.glob(data_file)
 queue=tf.train.string_input_producer(files_path,num_epochs=None)
 reader = tf.TFRecordReader()
 print(queue)
 _, serialized_example = reader.read(queue)
 features = tf.parse_single_example(
  serialized_example,
  features={
   'image_raw': tf.FixedLenFeature([], tf.string),
   'label_raw': tf.FixedLenFeature([], tf.string),
  })
 image = tf.decode_raw(features['image_raw'], tf.uint8)
 image = tf.cast(image, tf.float32)
 image.set_shape((12*12*3))
 label = tf.decode_raw(features['label_raw'], tf.float32)
 label.set_shape((2))
 # 预处理部分省略,大家可以自己根据需要添加
 return tf.train.batch([image,label],batch_size=batch_size,num_threads=4,capacity=5*batch_size)

def main( ):
 img_path=r'F:\python\MTCNN_by_myself\prepare_data\pnet*.tfrecords' #本地的几个tf文件
 img,label=read_image(img_path,batch_size=10)
 image=img[0]
 init=[tf.global_variables_initializer(),tf.local_variables_initializer()]
 with tf.Session() as sess:
  sess.run(init)
  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(sess=sess,coord=coord)
  try:
   while not coord.should_stop():
    print(image.shape)
  except tf.errors.OutOfRangeError:
   print('read done')
  finally:
   coord.request_stop()
  coord.join(threads)


if __name__=="__main__":
 main()

在read_image函数中,先使用glob函数获得了存放tfrecord文件的列表,然后根据TFRecord文件是如何存的就如何parse,再set_shape;这里有必要提醒下parse的方式。我们看到这里用的是tf.decode_raw ,因为做TFRecord是将图像数据string化了,数据是串行的,丢失了空间结果。从features中取出image和label的数据,这时就要用 tf.decode_raw  解码,得到的结果当然也是串行的了,所以set_shape 成一个串行的,再reshape。这种方式是取决于你的编码TFRecord方式的。

再举一种例子:

reader=tf.TFRecordReader()
_,serialized_example=reader.read(file_name_queue)
features = tf.parse_single_example(serialized_example, features={
 'data': tf.FixedLenFeature([256,256], tf.float32), ###
 'label': tf.FixedLenFeature([], tf.int64),
 'id': tf.FixedLenFeature([], tf.int64)
})
img = features['data']
label =features['label']
id = features['id']

这个时候就不需要任何解码了。因为做TFRecord的方式就是直接把图像数据append进去了。

参考链接:

https://blog.csdn.net/qq_34914551/article/details/86286184

到此这篇关于浅谈TensorFlow中读取图像数据的三种方式的文章就介绍到这了,更多相关TensorFlow 读取图像数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
用Python编写一个基于终端的实现翻译的脚本
Apr 24 Python
在Python下尝试多线程编程
Apr 28 Python
Python中time模块与datetime模块在使用中的不同之处
Nov 24 Python
python中enumerate函数遍历元素用法分析
Mar 11 Python
python3实现暴力穷举博客园密码
Jun 19 Python
pandas的object对象转时间对象的方法
Apr 11 Python
PyQt5每天必学之事件与信号
Apr 20 Python
python 读取DICOM头文件的实例
May 07 Python
Django forms表单 select下拉框的传值实例
Jul 19 Python
Python利用scapy实现ARP欺骗的方法
Jul 23 Python
python实现对变位词的判断方法
Apr 05 Python
Python基础之进程详解
May 21 Python
python中 _、__、__xx__()区别及使用场景
Jun 30 #Python
Django实现内容缓存实例方法
Jun 30 #Python
Pytorch 卷积中的 Input Shape用法
Jun 29 #Python
Python闭包装饰器使用方法汇总
Jun 29 #Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 #Python
Python接口测试环境搭建过程详解
Jun 29 #Python
python字典的值可以修改吗
Jun 29 #Python
You might like
PHP autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
解析php dirname()与__FILE__常量的应用
2013/06/24 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
Webkit的跨域安全问题说明
2011/09/13 Javascript
固定网页背景图同时保持图片比例的思路代码
2013/08/15 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
原生js和jquery实现图片轮播特效
2015/04/23 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
2016/01/05 Javascript
谈一谈js中的执行环境及作用域
2016/03/30 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
2016/06/17 Javascript
每日十条JavaScript经验技巧(二)
2016/06/23 Javascript
微信小程序 页面跳转传参详解
2016/10/28 Javascript
Vue源码解析之数据响应系统的使用
2019/04/24 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
小程序两种滚动公告栏的实现方法
2019/09/17 Javascript
微信小程序抽奖组件的使用步骤
2021/01/11 Javascript
详解JavaScript中的this指向问题
2021/02/05 Javascript
[49:28]VP vs Optic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python中的filter()函数的用法
2015/04/27 Python
Python如何抓取天猫商品详细信息及交易记录
2018/02/23 Python
Python的多维空数组赋值方法
2018/04/13 Python
django 框架实现的用户注册、登录、退出功能示例
2019/11/28 Python
python中数据库like模糊查询方式
2020/03/02 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
2020/12/07 Python
求职简历中个人的自我评价
2013/12/01 职场文书
《十六年前的回忆》教学反思
2014/02/14 职场文书
教师远程培训感言
2014/03/06 职场文书
护士个人自我鉴定
2014/03/24 职场文书
房屋出租协议书
2014/04/10 职场文书
企业职业病防治方案
2014/05/29 职场文书
南京导游词
2015/02/03 职场文书
小学语文教学随笔
2015/08/14 职场文书
Windows下用Nginx配置https服务器及反向代理的问题
2021/09/25 Servers