图像色彩调整
跟图像的翻转类似,调整色彩的亮度、对比度、饱和度和色相在很多图像识别应用中都不会影响识别结果;所以在训练神经网络模型时,可以随机调整训练图像的这些属性,从而使训练得到的模型尽可能小的受到这些无关因素的影响
import tensorflow as tf
import matplotlib.pyplot as plt
# 读取图像的原始数据
image_raw_data = tf.gfile.FastGFile('D:/2019-02/image18.jpg', 'rb').read()
with tf.Session() as sess:
image_data = tf.image.decode_jpeg(image_raw_data)
# 将0-255的图像转换为0-1之间
image_data = tf.image.convert_image_dtype(image_data, dtype=tf.float32)
# 将图像的亮度减0.5,得到的图像效果图如下所示
adjusted = tf.image.adjust_brightness(image_data, -0.5)
# 色彩调整的API可能会导致实数值超出0-1的范围,因此在输出最终图像前需要将其截断在0-1范围区间内
# 否则不仅图像无法正常可视化,,以此为输入的神经网络的训练质量也受到影响
# 如果对图像进行多项处理操作,那么这一截断过程应该在所有的处理完成之后进行
# 下面的样例假设截断操作在最终可视化图像前进行
adjusted = tf.clip_by_value(adjusted, 0.0, 1.0)
plt.imshow(adjusted.eval())
plt.show()
调整对比度
# 调整对比度
# 将图像的对比度减少到0.5倍
adjusted = tf.image.adjust_contrast(image_data, 0.5)
# 将图像的对比度增加五倍
adjusted = tf.image.adjust_contrast(image_data, 5)
# 在[lower, upper]的范围随机调整图的对比度
adjusted = tf.image.random_contrast(image, lower, upper)
# 调整色相
adjusted = tf.image.adjust_hue(image_data, 0.1)
# max_delta的取值在[0, 0.5]之间
adjusted = tf.image.random_hue(image_data, max_delta)
# 调整饱和度
# 将饱和度-5,
adjusted = tf.image.adjust_saturation(image_data, -5)
# 在[lower,upper]之间随机调整
adjusted = tf.image.random_saturation(image_data, lower, upper)
# 图像的标准化,均值为0,方差为1
adjusted = tf.image.per_image_standardization(image_data)
图像处理完整样例
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)
elif color_ordering == 1:
# 还可以定义其他的顺序,这里就不列举了
pass
return tf.clip_by_value(image, 0.0, 1.0)
def preprocess_for_train(image, height, width, bbox):
# 如果没有标注框,就认为整个图像就是需要关注的部分
if bbox is None:
# 一维矩阵[ymin, xmin, ymax, xmax]
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)
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)
return distorted_image
# 读取图像的原始数据
image_raw_data = tf.gfile.FastGFile('D:/2019-02/image18.jpg', 'rb').read()
with tf.Session() as sess:
image_data = tf.image.decode_jpeg(image_raw_data)
# shape为[1,1,4],表示生成一个标注框
boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7]]])
# 运行六次获得六种不同的图像
for i in range(6):
result = preprocess_for_train(image_data, 299, 299, boxes)
plt.imshow(result.eval())
plt.show()