【TensorFlow】数据处理(对图像的处理)

来源:互联网 发布:jersey 返回对象json 编辑:程序博客网 时间:2024/05/29 16:11

项目已上传至 GitHub —— img-pre

目录结构


images 文件夹下存放将被用于处理的图像,img_all.py 示范了 TensorFlow 中图像处理函数的使用方法,img_pre.py 给出了一个对图像进行预处理的程序示例

img-pre/    images/        1.jpg    img_all.py    img_pre.py

图像处理函数


编码处理

在使用图像之前需要先对图像进行解码,将图像转为像素矩阵,tensorflow.image 提供了图像解码函数,返回的矩阵数据类型是 uint8

  • decode_jpeg:解码 JPEG 格式图像
  • decode_and_crop_jpeg:解码并裁剪 JPEG 格式图像
  • decode_png:解码 PNG 格式图像
  • decode_gif:解码 GIF 格式图像
  • decode_bmp:解码 BMP 格式图像
  • decode_image:自动检测图像格式进行解码,注意 GIF 格式图像返回一个四维矩阵

以下代码示范对 JPEG 格式图像的解码处理

import tensorflow as tfimport matplotlib.pyplot as plt# 读取图像的原始数据image_raw_data = tf.gfile.FastGFile('images/1.jpg', 'rb').read()# 使用pyplot显示图像def show(img_data):    plt.imshow(img_data.eval())    plt.show()with tf.Session() as sess:    # 将原始数据解码成多维矩阵    img_data = tf.image.decode_jpeg(image_raw_data)    print(img_data.eval())    show(img_data)    # 将图像的矩阵编码成图像并存入文件    encoded_image = tf.image.encode_jpeg(img_data)    with tf.gfile.GFile('images/output.jpg', 'wb') as f:        f.write(encoded_image.eval())    # 将图像数据的类型转为实数类型,便于对图像进行处理    img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)

大小调整

tf.image.resize_images 函数中有四种调整图像的方法,结果会有细微差别

method 图像大小调整算法 0 双线性插值法(Bilinear interpolation) 1 最近邻居法(Nearest neighbor interpolation) 2 双三次插值法(Bicubic interpolation) 3 面积插值法(Area interpolation)


以下代码都是在图像编码处理代码的基础下运行,省去了加载原始图像,定义会话等过程

    # 用resize_images调整图像大小    # 第一个参数为原始图像    # 第二个参数为调整后的图像大小[new_height,new_width],跟旧版本分为两个参数不一样    # method参数给出了调整图像大小的算法    resized = tf.image.resize_images(img_data, [300, 300], method=0)    print(resized.get_shape())  # 图像深度没有显式指定则为问号    show(resized)

还可以通过 resize_image_with_crop_or_pad 函数对图像进行裁剪或填充

    # 用resize_image_with_crop_or_pad调整图像大小    # 第一个参数为原始图像    # 第二个和第三个参数是调整后的图像大小,大于原图则填充,小于则裁剪居中部分    croped = tf.image.resize_image_with_crop_or_pad(img_data, 200, 200)    show(croped)    padded = tf.image.resize_image_with_crop_or_pad(img_data, 500, 600)    show(padded)

还支持通过比例裁剪图像

    # 用central_crop调整图像大小    # 第一个参数是原始图像    # 第二个参数为调整比例,是(0,1]的实数    central_cropped = tf.image.central_crop(img_data, 0.5)    show(central_cropped)

图像翻转

以下代码示范了将图像进行上下翻转、左右翻转及沿对角线翻转

    # 图像翻转    flipped = tf.image.flip_up_down(img_data)  # 上下    show(flipped)    flipped = tf.image.flip_left_right(img_data)  # 左右    show(flipped)    transposed = tf.image.transpose_image(img_data)  # 对角线    show(transposed)

还可以随机翻转图像

    # 随机翻转图像    flipped = tf.image.random_flip_up_down(img_data)  # 随机上下    show(flipped)    flipped = tf.image.random_flip_left_right(img_data)  # 随机左右    show(flipped)

色彩调整

图像的色彩调整有四方面

  • 亮度
  • 对比度
  • 饱和度
  • 色相

修改图像的亮度

    # 调整图像的亮度    adjusted = tf.image.adjust_brightness(img_data, 0.5)  # 将图像的亮度+0.5    show(adjusted)    adjusted = tf.image.random_brightness(        img_data, max_delta=0.5)  # 在[-0.5,0.5]范围内随机调整图像亮度    show(adjusted)

修改图像的对比度

    # 调整图像的对比度    adjusted = tf.image.adjust_contrast(img_data, -5)  # 将图像的对比度-5    show(adjusted)    adjusted = tf.image.adjust_contrast(img_data, 5)  # 将图像的对比度+5    show(adjusted)    adjusted = tf.image.random_contrast(img_data, lower=-5, upper=5)  # 随机调整对比度

修改图像的饱和度

    # 调整图像的饱和度    adjusted = tf.image.adjust_saturation(img_data, -5)  # 将饱和度-5    show(adjusted)    adjusted = tf.image.adjust_saturation(img_data, 5)  # 将饱和度+5    show(adjusted)    adjusted = tf.image.random_saturation(image, lower=-5, uppper=5)  # 随机调整饱和度

调整图像的色相

    # 调整图像的色相    adjusted = tf.image.adjust_hue(img_data, 0.5)  # 将色相+0.5    show(adjusted)    adjusted = tf.image.random_hue(img_data, max_delta=0.5)  # 随机调整色相    show(adjusted)

处理标注框

以下代码示范了如何在图像中加入标注框

    # 用draw_bounding_boxes加入标注框    # 要求图像矩阵类型为实数    # 输入是一个batch的数据,也就是多张图像,所以需要加一维    batched = tf.expand_dims(img_data, 0)    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5,                                                   0.56]]])  # 代表图像的相对位置    result = tf.image.draw_bounding_boxes(batched, boxes)    show(result)

还能通过 sample_distorted_bounding_box 函数来随机截取图像

    # 用sample_distorted_bounding_box随机截取图像    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])    begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(        tf.shape(img_data), bounding_boxes=boxes)  # 通过标注框告诉算法有信息量的部分    batched = tf.expand_dims(img_data, 0)    image_with_box = tf.image.draw_bounding_boxes(batched, bbox_for_draw)    distorted_image = tf.slice(img_data, begin, size)    show(distorted_image)

图像预处理示例


该代码实现自《TensorFlow:实战Google深度学习框架》

img_pre.py 这个示例给出了如何在程序中对图像进行预处理,从而降低不相关因素对训练模型的影响

import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt# 通过调整亮度、对比度、饱和度、色相的顺序随机调整图像的色彩def distort_color(image, color_ordering=0):    if color_ordering == 0:        image = tf.image.random_brightness(image, max_delta=32 / 255.0)        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)        image = tf.image.random_hue(image, max_delta=0.2)        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)    elif color_ordering == 1:        image = tf.image.random_brightness(image, max_delta=32 / 255.0)        image = tf.image.random_hue(image, max_delta=0.2)        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)    elif color_ordering == 2:        # 一共可以有24种排列情况        pass    return tf.clip_by_value(image, 0.0, 1.0)# 对图像进行预处理def preprocess_for_train(image, height, width, bbox):    # 默认整个图像是需要关注的部分    if bbox is None:        bbox = tf.constant(            [0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])    # 转换图像张量的类型    if image.dtype != tf.float32:        image = tf.image.convert_image_dtype(image, dtype=tf.float32)    # 随机截取图像,减少需要关注的物体大小对图像识别算法的影响    bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(        tf.shape(image), bounding_boxes=bbox, min_object_covered=0.1)    distorted_image = tf.slice(image, bbox_begin, bbox_size)    # 将随机截取的图像调整为输入层的大小    distorted_image = tf.image.resize_images(        distorted_image, size=[height, width], method=np.random.randint(4))    # 随机左右翻转图像    distorted_image = tf.image.random_flip_left_right(distorted_image)    # 使用一种随机顺序调整图像色彩    distorted_image = distort_color(distorted_image, np.random.randint(2))    return distorted_imageimage_raw_data = tf.gfile.FastGFile('images/1.jpg', 'rb').read()with tf.Session() as sess:    img_data = tf.image.decode_jpeg(image_raw_data)    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])    for i in range(6):        result = preprocess_for_train(img_data, 300, 300, boxes)        plt.imshow(result.eval())        plt.show()

原书中的函数版本有些落后,有些函数会报错

  1. tf.image.sample_distorted_bounding_box()

    # 旧版本bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox)# 新版本bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox,min_object_covered=0.1)

    如果不显式给 min_object_covered 参数就会报错

    ValueError: Tried to convert ‘min_object_covered’ to a tensor and failed. Error: None values not supported. 
  2. tf.image.resize_images()

    # 旧版本distorted_image=tf.image.resize_images(distorted_image,height,width,method=method)# 新版本distorted_image = tf.image.resize_images(distorted_image, size=[height, width], method=method)

    如果不将 size 写为 size=[height,width] 的形式就会报错

    TypeError: resize_images() got multiple values for argument ‘method