TensorFlow 图像增强--随机翻转、随机亮度、对比度、色相等

图像增强在有关图片的训练中是不可或缺的部分。原有数据集中的图片的泛化程度不高,不能代表所有此类型的图片,并且数据集图片的清晰度、亮度、图片中物体的大小相对来说比较片面。在原有数据集上训练好模型后,拿来一张高亮度的图片就会有很大可能识别不出来。所以我们有必要扩充数据集来提高模型的泛化程度。

数据增强是对原有图片的亮度、对比度、色相等随机调整,这样能使数据集涵盖的方面更广,扩充了数据集。对提高模型的泛化程度很有必要。

下面介绍一些TensorFlow中图片增强的常用方法。

读取图像:

1
img_raw = tf.read_file('test.jpg')

解码图像:

1
img = tf.image.decode_jpeg(img_raw, channels=3)

读取图像读取的是图片文件源信息,是字符串,解码后才是三维张量。

1. 翻转

  • 上下翻转

    1
    img = tf.image.flip_up_down(img)

  • 左右反转

    1
    img = tf.image.flip_left_right(img)

  • 随机上下翻转

    1
    img = tf.image.random_flip_up_down(img)

  • 随机左右翻转

    1
    img = tf.image.random_flip_left_right(img)

2. 亮度 / 光照度

  • 调整亮度

    1
    2
    3
    # 后面那个参数时亮度,范围-1到1,
    # -1最暗(全黑),0是原图,1会变最亮(全白)
    img = tf.image.adjust_brightness(img, 0)
  • 随机亮度

    1
    2
    3
    4
    # max_delta 表示随机亮度的范围是 [-max_delta,max_delta]
    # max_delta 需要给一个大于零的数
    # 设定一个范围可以防止亮度过大或过小导致图片失真
    img = tf.image.random_brightness(img,max_delta)

3. 对比度

  • 调整对比度

    函数原型:def adjust_contrast(images, contrast_factor)

    函数的官方解释:对比度是每个图像的每个通道(RGB)独立调整。
    对任意通道的运算是:(x - mean) * contrast_factor + mean ,
    其中x是此通道某点的像素值,mean是此通道像素的均值。
    官方并没有给 contrast_factor 的取值范围。

    contrast_factor 可以理解成对比度增加或减小多少倍,1是原图。

    1
    img = tf.image.adjust_contrast(img,2)
  • 随机对比度

    1
    2
    # lower, upper 是对随机比度的限制范围 
    img = tf.image.random_contrast(img, lower, upper, seed=None)

4. 饱和度

  • 调整饱和度
    调整饱和度也有一个对应的算法。1是原图。

    1
    img = tf.image.adjust_saturation(img,0.5)
  • 随机饱和度

    1
    2
    # 
    img = tf.image.random_saturation(image, lower, upper, seed=None)

5. 色相 / 色度

  • 调整色度

    色度的变化对图像颜色影响较大,一般delta取值[-0.1, 0.1] 就行

    1
    2
    # delta 是调整值,取值范围是[-1,1]
    img = tf.image.adjust_hue(image, delta, name=None)
  • 随机色度

    1
    2
    3
    # delta 的随机范围是 [-max_delta, max_delta]
    # max_delta 需要在区间[0, 0.5]
    img = tf.image.random_hue(image, max_delta, seed=None)

6. 标准化

将图像的像素调整为均值为0,方差为1。

标准化后图像像素直接显示出来效果会严重失真。

1
img = tf.image.per_image_standardization(img)

7. 随机旋转

(未尝试)

旋转与翻转不同,旋转是坐标点的映射,TensorFlow中没有直接的库,需要自己写一个函数来操作。

8. 剪切

(未尝试)

数据集图片中物体的大小会有不同,并且常常数量不平均。

比如玉米种子图片中80%的图片中玉米粒比较多、大小适中,20%的图片玉米粒很大、一张图片中只有几粒。

这样训练出的模型的泛化程度同样不高。

随机剪切,同时将图像仍放缩成相同大小。这样让数据集中不同大小物体的图片数量分布均匀,有助于提高模型泛化程度。

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import matplotlib.pyplot as plt
import tensorflow as tf

def readImg_3():
img_raw = tf.read_file('test.jpg')
img = tf.image.decode_jpeg(img_raw, channels=3)

with tf.Session() as sess:
#img = tf.image.random_brightness(img,0.5)
# img = tf.image.adjust_brightness(img, -1)

#img = tf.image.adjust_contrast(img,2)
#img = tf.image.random_contrast(img, 2)

#img = tf.image.adjust_saturation(img,0.5)
#img = tf.image.random_saturation(img,-0.5,0.5)

#img = tf.image.adjust_hue(img, 0.3)
#img = tf.image.random_hue(img, 10)

# 标准化
img = tf.image.per_image_standardization(img)

#img = tf.image.random_flip_up_down(img)
img_ = img.eval() # 必须在会话中才能eval取值

print(img_.shape)
print(img_.dtype)
#print(img_)
plt.imshow(img_)
plt.show()

readImg_3()