TensorFlow 提供了比较丰富的图像处理函数,如翻转,尺寸调整等.

<h2>1. 图像预处理函数</h2>

#! ---- coding: utf-8 ----

import tensorflow as tf
import matplotlib.pyplot as plt

# 读取图像原始数据
image_raw_data = tf.gfile.FastGFile('/path/to/image.jpg', 'rb').read()

def imshow(img)
    plt.imshow(img)
    plt.show()

# 建立图像处理会话 Session
with tf.Session() as sess:
    #-------------------------------------------
    # 1. 图像解码
    #-------------------------------------------
    # 将原始数据解码成三维维矩阵
    img_data = tf.image.decode_jpeg(image_raw_data)
    print(img_data.eval())
    imshow(img_data)

    # 将图像的矩阵编码成图像并存入文件
    encoded_image = tf.image.encode_jpeg(img_data)
    with tf.gfile.GFile('/path/to/image_output.jpg', 'wb') as f:
        f.write(encoded_image.eval())

    # 将图像数据的类型转为 float32 实数类型,便于图像处理
    img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)

    #------------------------------------------
    # 2. 图像大小调整
    #-------------- ----------------------------
    # resize_images 函数 - 调整图像大小
    # 第一个参数为原始图像
    # 第二个参数为调整后的图像大小 [new_height, new_width]
    # method 参数指定调整图像大小的算法
    #   0 - 双线性插值法(Bilinear interpolation)
    #   1 - 最近邻居法(Nearest neighbor interpolation)
    #   2 - 双三次插值法(Bicubic interpolation)
    #   3 - 面积插值法(Area interpolation)
    resized_img = tf.image.resize_images(img_data, [300, 300], method=0)
    print(resized_img.get_shape())
    imshow(resized_img)

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

    # central_crop 函数 - 调整图像大小
    # 第一个参数是原始图像
    # 第二个参数为调整比例,是[0,1] 间的实数
    central_cropped_img = tf.image.central_crop(img_data, 0.5)
    imshow(central_cropped_img)

    #------------------------------------------
    # 3. 图像翻转
    #-------------- ----------------------------
    flipped_img = tf.image.flip_up_down(img_data)  # 上下翻转
    imshow(flipped_img)
    flipped_img = tf.image.flip_left_right(img_data)  # 左右翻转
    imshow(flipped_img)
    transposed_im = tf.image.transpose_image(img_data)  # 沿对角线翻转
    imshow(transposed_img)

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

    #------------------------------------------
    # 4. 图像色彩调整
    #-------------- ----------------------------
    # 主要调整包括:亮度;对比度;饱和度;色相.
    # 图像亮度调整
    adjusted_img = tf.image.adjust_brightness(img_data, -0.5)  # 图像亮度-0.5
    adjusted_img = tf.clip_by_value(adjusted_img, 0.0, 1.0) # 确保像素值截断在 [0.0, 1.0]间.
    imshow(adjusted_img)

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

    # 图像对比度调整
    adjusted_img = tf.image.adjust_contrast(img_data, -0.5)  # 图像对比度减少到 0.5 倍
    imshow(adjusted_img)
    adjusted_img = tf.image.adjust_contrast(img_data, 5)  # 图像对比度增加 5 倍
    imshow(adjusted_img)
    adjusted_img = tf.image.random_contrast(img_data, lower=-5, upper=5)  # 在 [lower, upper] 范围内随机调整图像对比度
    imshow(adjusted_img)

    # 图像饱和度调整
    adjusted_img = tf.image.adjust_saturation(img_data, -5)  # 图像饱和度 -5
    imshow(adjusted_img)
    adjusted_img = tf.image.adjust_saturation(img_data, 5)  # 图像饱和度 +5
    imshow(adjusted_img)
    adjusted_img = tf.image.random_saturation(image, lower=-5, uppper=5)  # 在 [lower, upper] 范围内随机调整图像饱和度
    imshow(adjusted_img)

    # 图像色相调整
    adjusted_img = tf.image.adjust_hue(img_data, 0.5)  # 图像色相 +0.5
    imshow(adjusted_img)
    adjusted_img = tf.image.random_hue(img_data, max_delta=0.5)  # 在 [-max_delta, max_delta] 范围内随机调整图像色相, max_delta 取值在 [0, 0.5]
    imshow(adjusted_img)

    #------------------------------------------
    # 5. 图像标准化
    #-------------- ----------------------------
    # 将图像上的亮度均值变为 0,方差变为 1.
    adjusted_img = tf.image.per_image_standardization(img_data)

    #------------------------------------------
    # 6. 图像标注框处理
    #-------------- ----------------------------
    # 采用标注框将图像中关注的物体圈出来.
    # draw_bounding_boxes 函数 - 图像加入标注框
    # 该函数要求图像矩阵中的数字为实数, 处理前需要先转换为实数类型.
    # 该函数输入是一个batch的数据,即多张图像组成的四维矩阵
    # 因此,需要对解码后的图像矩阵加一维.
    # img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)
    batched = tf.expand_dims(img_data, 0)
    # 图像标注框
    # 标注框有 4 个数字:[y_min, x_min, y_max, x_max]. 数字均是图像的相对位置.
    # 如:图像尺寸为 180x267, 则 [0.35, 0.47, 0.5, 0.56] 表示从 [63, 125] 到 [90, 150] 的标注框图像.
    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)
    imshow(result)

    # sample_distorted_bounding_box 函数 - 随机截取图像
    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
    # min_object_convered=0.4 表示截取图像部分至少包含某个标注框 40% 的内容信息.
    begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(tf.shape(img_data), 
                                                                        bounding_boxes=boxes, 
                                                                        min_object_convered=0.4)  # 通过标注框告诉算法有信息量的部分
    # 随机截取图像的可视化
    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)
    imshow(distorted_image)

<h2>2. 图像预处理样例</h2>

TensorFlow:实战Google深度学习框架(第2版) - 7.2.2 - 图像预处理完整样例

import tensorflow as tf
import numpy as np
import 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.)
        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)
    else:
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
        image = tf.image.random_brightness(image, max_delta=32./255.)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
        image = tf.image.random_hue(image, max_delta=0.2)

    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.4)
    bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(
        tf.shape(image), bounding_boxes=bbox, min_object_covered=0.4)
    distorted_image = tf.slice(image, bbox_begin, bbox_size)

    # 将随机截取的图片调整为神经网络输入层的大小
    distorted_image = tf.image.resize_images(distorted_image, [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_image


# 读取图片
image_raw_data = tf.gfile.FastGFile("datasets/cat.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(9):
        result = preprocess_for_train(img_data, 299, 299, boxes)
        plt.imshow(result.eval())
        plt.show()
Last modification:October 9th, 2018 at 09:31 am