tensorflow读取图片案例

1、知识点

"""
1、图片读取流程与API:
    1、构造图片文件队列
        文件队列API:
            a)tf.train.string_input_producer(string_tensor,,shuffle=True) 将输出字符串(例如文件名)输入到管道队列
                参数:
                    string_tensor    含有文件名的1阶张量
                    num_epochs:过几遍数据,默认无限过数据
                    return:具有输出字符串的队列

    2、构造图片阅读器
        图像读取API:tf.WholeFileReader  图像读取器,将文件的全部内容作为值输出的读取器
            return:读取器实例
            方法:read(file_queue):输出将是一个文件名(key)和该文件的内容(值)

    3、读取图片数据(解码过程)
        图像解码器
            1、tf.image.decode_jpeg(contents) 将JPEG编码的图像解码为uint8张量
                    return:uint8张量,3-D形状[height, width, channels]
                
            2、tf.image.decode_png(contents)将PNG编码的图像解码为uint8或uint16张量
                    return:张量类型,3-D形状[height, width, channels]
    4、处理图片数据,固定图像形状
        缩放图片: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格式图片
    5、进行批处理
        1、tf.train.batch(tensors,batch_size,num_threads = 1,capacity = 32,name=None) 读取指定大小(个数)的张量
            参数:   
                tensors:可以是包含张量的列表
                batch_size:从队列中读取的批处理大小
                num_threads:进入队列的线程数
                capacity:整数,队列中元素的最大数量
                return:tensors
        
        2、tf.train.shuffle_batch(tensors,batch_size,capacity,min_after_dequeue,num_threads=1,) 乱序读取指定大小(个数)的张量
            参数:
                min_after_dequeue:留下队列里的张量个数,能够保持随机打乱
    6、线程协调器:
        tf.train.Coordinator() 线程协调员,实现一个简单的机制来协调一组线程的终止
            方法:
                request_stop() 请求停止
                should_stop() 检查是否要求停止
                join(threads=None, stop_grace_period_secs=120)  等待线程终止
            return:线程协调员实例
    7、开启线程操作
        tf.train.start_queue_runners(sess=None,coord=None) 收集所有图中的队列线程,并启动线程
            参数与返回值:
                sess:所在的会话中
                coord:线程协调器
                return:返回所有线程队列
  

2、图像知识
        黑白图(又称单通道图):灰度值[0-255] , 一个像素点只有一个值
        彩色图(又称三通道图):RGB ,一个像素点有三个值
        图像数字化三要素:长度、宽度、通道数  [height,width,channels]  ,[200,200,1]
        特征:对于图片,一个像素表示一个特征
        图像样本:每一个样本必须保证特征值数量一样
        图片二阶张量:[100,200*200*1],表示100张40000个特征的黑白图
        图片三阶张量:[200,200,1],表示一张200*200的黑白图
        图片四阶张量:[100,200,200,1]表示100张200*200的黑色图片
    
        图片的存储数据类型:uint8(节约空间)
        矩阵计算:float32(提高精度)

3、报错:
        1、Invalid argument: Shape mismatch in tuple component 0. Expected [200,200,3], got [200,200,4]
                解决方法:表示数据不匹配,定义为3通道,但是图片本身是4通道,因此需将定义的3通道改为4通道
"""

2、代码

# coding = utf-8
import tensorflow as tf
import os

def readPic(filelist):
    """
    读取图片
    :param filelist:  文件路径+名字列表名
    :return:每张图片的张量
    """
    #1、构造文件队列
    file_queue = tf.train.string_input_producer(file_list)
    #2、构造阅读器去读取图片内容(默认读取一张图片)
    reader = tf.WholeFileReader()
    key , value = reader.read(file_queue)
    #3、对读取的图片进行解码
    image = tf.image.decode_jpeg(value)
    #4、处理图像大小
    image_size = tf.image.resize_images(image,[200,200])
    #print(image_size)

    #注意:一定要把样本的形状固定 [200,200,3],在批处理的时候要求所有图像形状固定且一致
    image_size.set_shape([200,200,3])
    #print(image_size)

    #5、进行批处理
    image_batch = tf.train.batch([image_size], batch_size=20, num_threads=1, capacity=20)
    print(image_batch)
    return image_batch

if __name__ == \'__main__\':
    file_name = os.listdir("./pic")
    file_list = [os.path.join("./pic",file) for file in file_name]
    image_batch = readPic(file_list)
    #print(image_batch)
    #开启会话
    with tf.Session() as sess:
        #定义一个协调器
        coord = tf.train.Coordinator()
        #开启线程
        threads = tf.train.start_queue_runners(sess,coord=coord)

        print(sess.run([image_batch]))

        #回收线程
        coord.request_stop()
        coord.join(threads)