TensorflowIO操作------图像

这篇博客介绍了TensorFlow中的图像操作,包括图像的基本概念,如图像的长宽和颜色通道,以及如何处理图像大小压缩。作者强调了预处理阶段进行图像操作的重要性,如缩小、裁剪等。还详细讲述了如何使用TensorFlow的函数读取和处理图像数据,包括解码JPEG图像、调整图像大小,并使用批处理和乱序读取提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图像操作

图像基本概念

在图像数字化表示当中,分为黑白和彩色两种。在数字化表示图片的时候,有三个因素。分别是图片的长、图片的宽、图片的颜色通道数。那么黑白图片的颜色通道数为1,它只需要一个数字就可以表示一个像素位;而彩色照片就不一样了,它有三个颜色通道,分别为RGB,通过三个数字表示一个像素位。TensorFlow支持JPG、PNG图像格式,RGB、RGBA颜色空间。图像用与图像尺寸相同(heightwidthchnanel)张量表示。图像所有像素存在磁盘文件,需要被加载到内存。

图像大小压缩

大尺寸图像输入占用大量系统内存。训练CNN需要大量时间,加载大文件增加更多训练时间,也难存放多数系统GPU显存。大尺寸图像大量无关本征属性信息,影响模型泛化能力。最好在预处理阶段完成图像操作,缩小、裁剪、缩放、灰度调整等。图像加载后,翻转、扭曲,使输入网络训练信息多样化,缓解过拟合。Python图像处理框架PIL、OpenCV。TensorFlow提供部分图像处理方法。

  • tf.image.resize_images 压缩图片导致定大小

图像数据读取实例

同样图像加载与二进制文件相同。图像需要解码。输入生成器(tf.train.string_input_producer)找到所需文件,加载到队列。tf.WholeFileReader 加载完整图像文件到内存,WholeFileReader.read 读取图像,tf.image.decode_jpeg 解码JPEG格式图像。图像是三阶张量。RGB值是一阶张量。加载图像格 式为[batch_size,image_height,image_width,channels]。批数据图像过大过多,占用内存过高,系统会停止响应。直接加载TFRecord文件,可以节省训练时间。支持写入多个样本。

1.构造文件队列
2.图片阅读器和读取数据
3.解码
4.处理图片大小
5.进行批处理

读取图片数据到Tensor

管道读端多文件内容处理

但是会发现read只返回一个图片的值。所以我们在之前处理文件的整个流程中,后面的内容队列的出队列需要用特定函数去获取。

  • tf.train.batch 读取指定大小(个数)的张量
  • tf.train.shuffle_batch 乱序读取指定大小(个数)的张量

def picread(filelist):
    """
    读取狗图片并转换成张量
    :param filelist: 文件路径+名字的列表
    :return: 每张图片的张量
    """
    #1.构造文件队列
    file_queue=tf.train.string_input_producer(filelist)

    #2.构造阅读器去读取图片内容(默认读取一张图片)
    reader=tf.WholeFileReader()

    key,value=reader.read(file_queue)
    print(value)

    #3.对读取的图片数据进行解码
    image=tf.image.decode_jpeg(value)
    print(image)

    #4.处理图片的大小(统一大小)
    image_resize=tf.image.resize_images(image,[200,200])

    print(image_resize)
    image_resize.set_shape([200,200,3])

    #6.进行批处理
    image_batch=tf.train.batch([image_resize],batch_size=20,num_threads=1,capacity=20)
    print(image_batch)

    return image_batch

if __name__=='__main__':
    file_name=os.listdir('./data/dog/')
    filelist=[os.path.join('./data/dog/',file) for file in file_name ]

    image_batch=picread(filelist)

    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)

 二进制读取

#定义cifar的数据等命令行参数
FLAGS=tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('cifar_dir','./data/cifar-10-batches-bin/','文件的目录')


class CifarRead(object):
    """完成读取二进制文件,写进tfrecords,读取tfrecords"""
    def __init__(self,filelist):
        self.file_list=filelist

        #定义读取的图片的一些属性
        self.height=32
        self.width=32
        self.channel=3
        #二进制每张图片的字节
        self.label_bytes=1
        self.image_bytes=self.height*self.width*self.channel
        self.bytes=self.image_bytes+self.label_bytes

    def read_and_decode(self):
        #1.构造文件队列
        file_queue=tf.train.string_input_producer(self.file_list)

        #2.构造文件阅读器,读取内容,每个样本的字节数
        reader=tf.FixedLengthRecordReader(self.bytes)

        key,value=reader.read(file_queue)

        #3.解码内容,二进制文件内容的解码
        image_label=tf.decode_raw(value,tf.uint8)

        #分割标签与图像张量,转换成相应格式
        label=tf.cast(tf.slice(image_label,[0],[self.label_bytes]),tf.int32)
        image=tf.slice(image_label,[self.label_bytes],[self.image_bytes])

        print(image)

        #给image设置形状
        image_tensor=tf.reshape(image,[self.height,self.width,self.channel])

        #print(image_tensor.eval())

        #4处理流程
        image_batch,label_batch=tf.train.batch([image_tensor,label],batch_size=1,capacity=1,num_threads=1)

        return image_batch,label_batch


if __name__=="__main__":
    # #1.找到文件,放入列表,路径+名字
    # filename_list = os.listdir("./csvdata")
    #
    # readcsv_decode(filename_list)

    #1.找到文件,放入列表,路径+名字
    file_name=os.listdir(FLAGS.cifar_dir)

    filelist=[os.path.join(FLAGS.cifar_dir,file) for file in file_name if file[0:4]=='data']


    cfar=CifarRead(filelist)

    image_batch,label_batch=cfar.read_and_decode()

    with tf.Session() as sess:
             #线程协调员
        coord=tf.train.Coordinator()

             #启动工作线程
        threads=tf.train.start_queue_runners(sess,coord=coord)


             #打印批处理的数据
        print(sess.run([image_batch,label_batch]))

        coord.request_stop()

        coord.join(threads)


 

 

#定义cifar的数据等命令行参数
FLAGS=tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('cifar_dir','./data/cifar-10-batches-bin/','文件的目录')
tf.app.flags.DEFINE_string("cifar_tfrecords", "./tem/cifar.tfrecords", "存进tfrecords的文件")


class CifarRead(object):
    """完成读取二进制文件,写进tfrecords,读取tfrecords"""
    def __init__(self,filelist):
        self.file_list=filelist

        #定义读取的图片的一些属性
        self.height=32
        self.width=32
        self.channel=3
        #二进制每张图片的字节
        self.label_bytes=1
        self.image_bytes=self.height*self.width*self.channel
        self.bytes=self.image_bytes+self.label_bytes

    def read_and_decode(self):
        #1.构造文件队列
        file_queue=tf.train.string_input_producer(self.file_list)

        #2.构造文件阅读器,读取内容,每个样本的字节数
        reader=tf.FixedLengthRecordReader(self.bytes)

        key,value=reader.read(file_queue)

        #3.解码内容,二进制文件内容的解码
        image_label=tf.decode_raw(value,tf.uint8)

        #分割标签与图像张量,转换成相应格式
        label=tf.cast(tf.slice(image_label,[0],[self.label_bytes]),tf.int32)
        image=tf.slice(image_label,[self.label_bytes],[self.image_bytes])

        print(image)

        #给image设置形状
        image_tensor=tf.reshape(image,[self.height,self.width,self.channel])

        #print(image_tensor.eval())

        #4处理流程
        image_batch,label_batch=tf.train.batch([image_tensor,label],batch_size=10,capacity=10,num_threads=1)

        return image_batch,label_batch

    def write_ro_tfrecords(self, image_batch, label_batch):
        """
        将图片的特征值和目标值存进tfrecords
        :param image_batch: 10张图片的特征值
        :param label_batch: 10张图片的目标值
        :return: None
        """
        # 1、建立TFRecord存储器
        writer = tf.python_io.TFRecordWriter(FLAGS.cifar_tfrecords)

        # 2、循环将所有样本写入文件,每张图片样本都要构造example协议
        for i in range(10):
            # 取出第i个图片数据的特征值和目标值
            image = image_batch[i].eval().tostring()

            label = int(label_batch[i].eval()[0])

            # 构造一个样本的example
            example =  tf.train.Example(features=tf.train.Features(feature={
                "image": tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),
                "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),
            }))

            # 写入单独的样本
            writer.write(example.SerializeToString())

        # 关闭
        writer.close()
        return None

    def read_from_tfrecords(self):

        # 1、构造文件队列
        file_queue = tf.train.string_input_producer([FLAGS.cifar_tfrecords])

        # 2、构造文件阅读器,读取内容example,value=一个样本的序列化example
        reader = tf.TFRecordReader()

        key, value = reader.read(file_queue)

        # 3、解析example
        features = tf.parse_single_example(value, features={
            "image": tf.FixedLenFeature([], tf.string),
            "label": tf.FixedLenFeature([], tf.int64),
        })

        # 4、解码内容, 如果读取的内容格式是string需要解码, 如果是int64,float32不需要解码
        image = tf.decode_raw(features["image"], tf.uint8)

        # 固定图片的形状,方便与批处理
        image_reshape = tf.reshape(image, [self.height, self.width, self.channel])

        label = tf.cast(features["label"], tf.int32)

        print(image_reshape, label)

        # 进行批处理
        image_batch, label_batch = tf.train.batch([image_reshape, label], batch_size=10, num_threads=1, capacity=10)

        return image_batch, label_batch


if __name__=="__main__":
    # #1.找到文件,放入列表,路径+名字
    # filename_list = os.listdir("./csvdata")
    #
    # readcsv_decode(filename_list)

    #1.找到文件,放入列表,路径+名字
    file_name=os.listdir(FLAGS.cifar_dir)

    filelist=[os.path.join(FLAGS.cifar_dir,file) for file in file_name if file[0:4]=='data']


    cfar=CifarRead(filelist)

    #image_batch,label_batch=cfar.read_and_decode()

    image_batch,label_batch=cfar.read_from_tfrecords()


    with tf.Session() as sess:
        #线程协调员
        coord=tf.train.Coordinator()

        #启动工作线程
        threads=tf.train.start_queue_runners(sess,coord=coord)

        # # 存进tfrecords文件
        # print("开始存储")
        # #
        # cfar.write_ro_tfrecords(image_batch, label_batch)
        # #
        # print("结束存储")

        #打印批处理的数据
        print(sess.run([image_batch,label_batch]))

        coord.request_stop()

        coord.join(threads)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值