12、数据读取(四)——图片文件读取
1、图片组成
(1)如何对一张图片进行识别,输入特征值,输出目标值。
- 在计算机中,对于每一张图片,都是通过像素进行显示,每张图片由像素组成,每一个点的像素值不同。
- 在一张200x200的图片中:
黑白图片,单通道图片,每一个像素点只有一个值,即灰度值,范围0-255,所以共有200x200,即20000个像素,共有20000个特征。
彩色图片,三通道图片,每一个像素点只有三个值,即RGB,范围0-255,所以共有200x200x3,即20000x3个像素,共有60000个特征。
(2)图片数字化三要素,[ 长度、宽度、通道数 ]
(3)三要素与张量的关系
指定3-D张量:[height,width,channels] ,即 长度,宽度,通道数
4-D张量:[batch,height,width,channels],即图片的张数(批量),长度,宽度,通道数
2、图片的基本操作
每一个图片样本必须保持特征值数量一样,这就需要所有图片统一特征的数量(像素值一样)
Ⅰ. 目的:①增加图片数据的统一性 ②所有图片转换为指定大小 ③缩小图片数据量,防止增加开销
Ⅱ. 操作API:
缩放图片的大小
tf.image.resize_images(images, size) 缩小图片
● images: 4-D形 状[batch, height, width, channels]或3-D形状的张量[height, width, channels]的图片数据
● size: 1-D int32张量: new_ _height, new_ width, 图像的新尺寸,返回4~D格式或者3-D格式图片
3、图片文件读取API(读取狗的图片,并抓换为张量)
(1)图像读取器
tf.WholeFileReader
● 将文件的全部内容作为值输出的读取器
● return:读取器实例
● read(file_queue):输出将是一个文件名(key) 和该文件的内容(值)
1 reader = tf.WholeFileReader() 2 key, value = reader.read(file_queue)
(2)图像解码器
tf.image.decode_ jpeg(contents)
● 将JPEG编码的图像解码为uint8张量
● return: uint8张量,3-D形状 [ height, width, channels]
1 image = tf.image.decode_jpeg(value)
tf.image.decode_png(contents)
● 将PNG编 码的图像解码为uint8或uint16张量
● return:张量类型, 3-D形 状[height, width, channels]
(3)分步代码实现
将文件读入列表
1 file_name = os.listdir(r"E:\pythonprogram\deepLearning\base\dog") 2 fileList = [os.path.join(r"E:\pythonprogram\deepLearning\base\dog",file) for file in file_name]
Ⅰ. 构建文件队列
file_queue = tf.train.string_input_producer(fileList)
Ⅱ. 构造阅读器去读取图片内容(默认读取一张图片)
1 reader = tf.WholeFileReader() 2 key, value = reader.read(file_queue) #value 是一张图片对应的值 3 print(value) #这里只看tensor的形状
输出:
Tensor("ReaderReadV2:1", shape=(), dtype=string) #什么都没有,需要解码
Ⅲ. 对图片进行解码
1 image = tf.image.decode_jpeg(value) 2 print(image)
输出:
1 Tensor("DecodeJpeg:0", shape=(?, ?, ?), dtype=uint8) #上面读取的是byes类型,解码之后是uint8
Ⅳ. 处理图片的大小(因为图片的大小有可能是不一样的,所以需要统一图片的大小)
1 image_resize = tf.image.resize_images(image,[200,200]) #size 指定图片的长和宽,缩放后的像素由计算机自动处理 2 print(image_resize)
输出:
Tensor("resize/Squeeze:0", shape=(200, 200, ?), dtype=float32) #resize之后变成float, float类型还原时是不行的,像素值只能用一个整型的数值存储的
Ⅴ. 固定样本大小,在固定样本大小之后才能进行批处理
1 image_resize.set_shape([200,200,3]) #设置静态形状,在批处理的时候要求所有形状都要固定 2 print(image_resize)
输出:
Tensor("batch:0", shape=(10, 200, 200, 3), dtype=float32)
Ⅵ. 批处理
1 image_batch = tf.train.batch([image_resize], batch_size=10,num_threads=1,capacity=10) #批处理结果返回image_batch 2 print(image_batch)
输出:
Tensor("batch:0", shape=(10, 200, 200, 3), dtype=float32)
Ⅶ.会话
1 with tf.Session() as sess: 2 #定义一个线程协调器 3 coord = tf.train.Coordinator() 4 5 # 开启读文件的线程 6 threads = tf.train.start_queue_runners(sess, coord=coord) 7 8 #打印读取的内容 9 print(sess.run([image_batch])) 10 11 #回收子线程 12 coord.request_stop() 13 coord.join(threads)
(4)完整代码
1 import tensorflow as tf 2 import os 3 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #去掉警告,将警告级别提升 4 5 6 def picRead(fileList): 7 """ 8 读取狗的图片,并转换为张量 9 :param fileList: 文件路径 + 名字的列表 10 :return: 每张图片的张量 11 """ 12 13 # 1.构建文件队列 14 file_queue = tf.train.string_input_producer(fileList) 15 16 # 2.构造阅读器去读取图片内容(默认读取一张图片),实例化一个reader 17 reader = tf.WholeFileReader() 18 19 key, value = reader.read(file_queue) #value 是一张图片对应的值 20 21 # 3.对图片进行解码,看图片的格式为jpg 22 image = tf.image.decode_jpeg(value) 23 24 # 4.处理图片的大小(因为图片的大小有可能是不一样的,所以需要统一图片的大小) 25 image_resize = tf.image.resize_images(image,[200,200]) #size 指定图片的长和宽,缩放后的像素由计算机自动处理 26 27 # 5.1. 注意:一定要把样本的形状固定 [200,200,3] 28 image_resize.set_shape([200,200,3]) #设置静态形状,在批处理的时候要求所有形状都要固定,如果不固定,计算机不知道取多少张图片层视为一张图片 29 30 # 5. 进行批处理 31 image_batch = tf.train.batch([image_resize], batch_size=10,num_threads=1,capacity=10) #批处理结果返回image_batch 32 return image_batch 33 34 if __name__ == '__main__': 35 # 1.找到文件,放入列表 路径+名字 ->列表当中 36 file_name = os.listdir(r"E:\pythonprogram\deepLearning\base\dog") 37 # print(file_name) 38 fileList = [os.path.join(r"E:\pythonprogram\deepLearning\base\dog",file) for file in file_name] 39 # print(fileList) 40 image_batch = picRead(fileList) 41 42 # 开启会话运行结果 43 with tf.Session() as sess: 44 #定义一个线程协调器 45 coord = tf.train.Coordinator() 46 47 # 开启读文件的线程 48 threads = tf.train.start_queue_runners(sess, coord=coord) 49 50 #打印读取的内容 51 print(sess.run([image_batch])) 52 53 #回收子线程 54 coord.request_stop() 55 coord.join(threads)
输出:
[array([[[[252. , 252. , 252. ], [251. , 251. , 251. ], [251. , 251. , 251. ], ..., [251. , 251. , 251. ], [251. , 251. , 251. ], [249. , 249. , 249. ]], .... .... .... [[182. , 173. , 166. ], [181. , 172. , 165. ], [180. , 171. , 162. ], ..., [171.5 , 161. , 159. ], [181. , 171. , 169. ], [175.5 , 167.5 , 164.5 ]], [[186. , 176. , 167. ], [186. , 176. , 167. ], [184. , 174. , 165. ], ..., [167.5 , 160.5 , 154.5 ], [169.5 , 162.5 , 156.5 ], [171.5 , 164.5 , 158.5 ]]]], dtype=float32)]