tensorflow学习笔记——图像数据处理

喜欢摄影的盆友都知道图像的亮度,对比度等属性对图像的影响是非常大的,相同物体在不同亮度,对比度下差别非常大。然而在很多图像识别问题中,这些因素都不应该影响最后的结果。所以本文将学习如何对图像数据进行预处理使训练得到的神经网络模型尽可能小地被无关因素所影响。但与此同时,复杂的预处理过程可能导致训练效率的下降。为了减少预处理对于训练速度的影响,后面也学习多线程处理输入数据的解决方案。

  在大部分图像识别问题中,通过图像预处理过程可以提高模型的准确率。当然在TensorFlow中提供了几类图像处理函数,下面一一学习。

1,图像编码处理

  我们知道一张RGB色彩模式的图像可以看成一个三维矩阵,矩阵中的每个数表示了图像上不同位置,不同颜色的亮度。然而图像在存储时并不是直接记录这些矩阵中的数字,而是记录经过压缩编码之后的结果。所以要将一张图像还原成一个三维矩阵,需要解码的过程。TensorFlow提供了对JPEG和png格式图像的编码/解码函数。以下代码示范了如何使用TensorFlow中对 JPEG 格式图像的编码/解码函数。

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

34

35

36

37

38

39

40

41

#_*_coding:utf-8_*_

# matplotlib.pyplot 是一个python 的画图工具。下面用这个来可视化

import matplotlib.pyplot as plt

import tensorflow as tf

 

# 读取图像的原始数据

picture_path = 'kd.jpg'

image_raw_data = tf.gfile.FastGFile(picture_path, 'rb').read()

 

with tf.Session() as sess:

    # 将图像使用JPEG的格式解码从而得到图像对应的三维矩阵

    # TensorFlow提供了 tf.image.decode_png 函数对png格式的图像进行解码

    # 解码之后的结果为一个张量,在使用它的取值之前需要明确调用运行的过程

    img_data = tf.image.decode_jpeg(image_raw_data)

 

    # 输出解码之后的三维矩阵

    # print(img_data.eval())

    '''

        # 输出解码之后的三维矩阵如下:

    [[[4   6   5]

      [4   6   5]

     [4   6   5]

    ...

    [35 29  31]

    [26  20  24]

    [25 20 26]]]

    '''

     

 

    # 使用 pyplot工具可视化得到的图像

    plt.imshow(img_data.eval())

    plt.show()

 

    # 将数据的类型转化成实数方便下面的样例程序对图像进行处理

    # img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)

    

    # 将表示一张图像的三维矩阵重新按照JPEG格式编码并存入文件中

    # 打开这种图片可以得到和原始图像一样的图像

    encoded_image = tf.image.encode_jpeg(img_data)

    with tf.gfile.GFile('output.jpg''wb'as f:

        f.write(encoded_image.eval())

  下图显示了上面代码可视化出来的一张图像:

tensorflow学习笔记——图像数据处理_第1张图片

2,图像大小调整

  一般来说,网络上获取的图像大小是不固定的,但神经网络输入节点的个数是固定的。所以在将图像的像素作为输入提供给神经网络之前,需要先将图像的大小统一。这就是图像大小调整需要完成的任务。图像大小调整有两种方式,第一种是通过算法使得新的图像尽量保存原始图像上的所有信息。TensorFlow提供了四种不同的方法,并且将他们封装到了 tf.image.resize_images 函数,下面代码示范了如何使用这个函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# 加载原始图像

# 读取图像的原始数据,然后解码

picture_path = 'kd.jpg'

image_raw_data = tf.gfile.FastGFile(picture_path, 'rb').read()

 

with tf.Session() as sess:

    # 将图像使用JPEG的格式解码从而得到图像对应的三维矩阵

    # TensorFlow提供了 tf.image.decode_png 函数对png格式的图像进行解码

    # 解码之后的结果为一个张量,在使用它的取值之前需要明确调用运行的过程

    img_data = tf.image.decode_jpeg(image_raw_data)

 

    # 通过tf.image.resize_images函数调整图像的大小

    # 这个函数第一个参数为原始图像,第二个和第三个参数为调整后图像的大小

    # method 参数给出了调整图像大小的算法

    resized = tf.image.resize_images(img_data, 300, 300, method=0)

     

    # 输出调整后图像的大小,此处的结果为(300, 300, ?)表示图像的大小为300*300

    # 但是在图像的深度还没有明确设置之前会是问号

    print(img_data.get_shape)

  下图给出了 tf.image.resize_images 函数的 method 参数取值对应的图像大小调整算法

tensorflow学习笔记——图像数据处理_第2张图片

   实例代码如下:

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

#_*_coding:utf-8_*_

import matplotlib.pyplot as plt

import tensorflow as tf

import numpy as np

 

# 读取图像的原始数据

picture_path = 'kd.jpg'

image_raw_data = tf.gfile.FastGFile(picture_path, 'rb').read()

 

with tf.Session() as sess:

    # 将图像使用JPEG的格式解码从而得到图像对应的三维矩阵

    # TensorFlow提供了 tf.image.decode_png 函数对png格式的图像进行解码

    # 解码之后的结果为一个张量,在使用它的取值之前需要明确调用运行的过程

    img_data = tf.image.decode_jpeg(image_raw_data)

 

    img_data.set_shape([300, 300, 3])

    print(img_data.get_shape(www.jintianxuesha.com))   # (300, 300, 3)

 

    # 重新调整图片的大小

    resized = tf.image.resize_images(img_data, [260, 260], method=0)

 

    # TensorFlow的函数处理图片后存储的数据是float32格式的,

    # 需要转换成uint8才能正确打印图片。

    resized_photo = np.asarray(resized.eval(), dtype='uint8')

    # tf.image.convert_image_dtype(rgb_image, tf.float32)

    plt.imshow(resized_www.yisheng3yul.com photo)

    plt.show()

  结果如下:

tensorflow学习笔记——图像数据处理_第3张图片

  当然,我们也可以进行双三插值法,面积插值法,最近邻插值法进行处理。不同算法调整处理的结果会有细微差别,但不会相差太远。

3,裁剪和填充

  除了把整张图像信息完整保存,TensorFlow还提供了API对图像进行裁剪或者填充。TensorFlow提供了 tf.image.crop_to_bounding_box 函数 和 tf.image.pad_to_bounding_box 函数来剪裁或者填充给定区域的图像。这两个函数都要求给出的尺寸满足一定的要求,否则程序会报错。比如在使用 tf.image.crop_to_bounding_box 函数时候,TensorFlow要求提供的图像尺寸要大于目标尺寸,也就是要求原始图像能够裁剪出目标图像的大小。下面代码展示了通过 tf.image_resize_image_with_crop_or_pad 函数来调整图像大小的功能。

1

2

3

4

5

6

7

# 通过  tf.image_resize_image_with_crop_or_pad 函数调整图像的大小

# 这个函数的第一个参数为原始图像,后面两个参数是调整后的模板图像大小

# 如果原始图像的尺寸大于目标图像,那么这个函数会自动截取图像原始图像中矩阵的部分

# 如果目标图像大于原始图像,这个函数会自动在原始图像的四周填充全0的背景

# 因为我这个图片是500*468,所以第一个命令自动裁剪,第二个命名自动填充

croped = tf.image.resize_image_with_crop_or_pad(img_data, 300, 300)

padded = tf.image.resize_image_with_crop_or_pad(img_data, 600, 600)

  下面示例看一下图片:

tensorflow学习笔记——图像数据处理_第4张图片

tensorflow学习笔记——图像数据处理_第5张图片

4,截取中间50%的图片

   TensorFlow还支持通过比例调整图像大小,函数如下:

1

2

3

4

# 通过 tf.image.central_crop() 函数可以按比例裁剪图像

# 函数第一个参数为原始图像,第二个为调整比例 这个比例是需要在(0, 1] 的实数

# 下面意思是截取中间百分之五十

central_cropped = tf.image.central_crop(www.yacuangyl.com img_data, 0.5)

  截取中间50%的结果展示如下:

tensorflow学习笔记——图像数据处理_第6张图片

5,翻转图片

   TensorFlow提供了一些函数来支持对图像的翻转,下面代码实现了将图像上下反转,左右反转,以及沿对角线翻转的功能。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# 上下翻转

flipped1 = tf.image.flip_up_down(img_data)

plt.imshow(flipped1.eval())

plt.show()

 

# 左右翻转

flipped2 = tf.image.flip_left_right(img_data)

plt.imshow(flipped2.eval()www.jujinyulee.com)

plt.show()

 

#对角线翻转

transposed = tf.image.transpose_image(img_data)

plt.imshow(transposed.eval())

plt.show()

 

# 以一定概率上下翻转图片。

#flipped = tf.image.random_flip_up_down(img_data)

# 以一定概率左右翻转图片。

#flipped = tf.image.random_flip_www.csyldl.com left_right(img_data)

  结果展示如下:

tensorflow学习笔记——图像数据处理_第7张图片

tensorflow学习笔记——图像数据处理_第8张图片

tensorflow学习笔记——图像数据处理_第9张图片

  在很多图像识别问题中,图像的翻转不会影响识别的结果。于是在训练图像识别的神经网络模型时,可以随机地翻转训练图像。这样训练得到的模型可以识别不同角度的实体。比如假设在训练数据中所有的猫头都是向右的,那么训练出来的模型就无法很好的识别猫头向左向右的猫。虽然这个问题可以通过收集更多的训练数据来解决,但是通过随机翻转训练图像的方式可以在零成本的情况下很大的缓解该问题。所以随机翻转训练图像是一种很常见的图像预处理方式。

6,图像色彩调整

  和图像翻转类似,调整图像的亮度,对比度,饱和度和色相在很多图像识别应用中都不会影响识别结果。所以在训练神经网络模型时,可以随机调整训练图像的这些属性,从而使得训练得到的模型尽可能小的受到无关因素的影响。Tensorflow提供了调整这些色彩相关属性的API,以下代码显示了如何修改图像的亮度:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

# 将图片的亮度-0.5。

#adjusted = tf.image.adjust_brightness(img_data, -0.5)

 

# 将图片的亮度-0.5

#adjusted = tf.image.adjust_brightness(img_data, 0.5)

 

# 在[-max_delta, max_delta)的范围随机调整图片的亮度。

adjusted = tf.image.random_brightness(img_data, max_delta=0.5)

 

# 将图片的对比度-5

#adjusted = tf.image.adjust_www.dongfangyuld.com contrast(img_data, -5)

 

# 将图片的对比度+5

#adjusted = tf.image.adjust_contrast(img_data, 5)

 

# 在[lower, upper]的范围随机调整图的对比度。

#adjusted = tf.image.random_contrast(img_data, lower, upper)

 

plt.imshow(adjusted.eval())

plt.show()

  结果展示如下:

tensorflow学习笔记——图像数据处理_第10张图片

7,图像色相调整

  下面代码显示了如何调整图像的色相:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

# 下面四条命令分别将色相加0.1  0.3  0.6   0.9

adjusted = tf.image.adjust_hue(img_data, 0.1)

#adjusted = tf.image.adjust_www.kunlunyulegw.com hue(img_data, 0.3)

#adjusted = tf.image.adjust_hue(img_data, 0.6)

#adjusted = tf.image.adjust_hue(www.leyouzaixan.cn img_data, 0.9)

 

# 在[-max_delta, max_delta]的范围随机调整图片的色相。max_delta的取值在[0, 0.5]之间。

#adjusted = tf.image.random_hue(image, max_delta)

 

# 将图片的饱和度-5。

#adjusted = tf.image.adjust_saturation(img_data, -5)

# 将图片的饱和度+5。

#adjusted = tf.image.adjust_saturation(img_data, 5)

# 在[lower, upper]的范围随机调整图的饱和度。

#adjusted = tf.image.random_saturation(img_data, lower, upper)

 

# 将代表一张图片的三维矩阵中的数字均值变为0,方差变为1。

#adjusted = tf.image.per_image_whitening(img_data)

 

plt.imshow(adjusted.eval())

plt.show()

  结果展示一个调整色相0.1的图片:

tensorflow学习笔记——图像数据处理_第11张图片

8,图像标准化

  图像标准化的过程,其实就是将图像上的亮度均值变为0, 方差变为1,下面代码实现了这个功能:

1

2

3

4

5

# 图像标准化

# 将代表一张图像的三维矩阵中的数字均值变为0, 方差变为1

adjusted = tf.image.per_image_standardization(img_data)

plt.imshow(adjusted.eval(www.gouyiflb.cn))

plt.show()

你可能感兴趣的:(tensorflow学习笔记——图像数据处理)