图像编码处理

一张RGB三通道的彩色图像可以看成一个三维矩阵,矩阵中的不位置上的数字代表图像的像素值。然后图像在存储时并不是直接记录这些矩阵中的数字,而是经过了压缩编码。所以将一张图像还原成一个三维矩阵的过程就是解码的过程,反之就是编码了。

tensorflow提供了对jpeg、png等常见图像格式的编码/解码函数,以下代码示范tensorflow对jpeg格式图像的编码/解码函数。

import tensorflow as tf
import matplotlib.pyplot as plt


image_raw_data = tf.gfile.FastGFile('img/1.jpg','rb').read()

with tf.Session() as sess:
     img_data = tf.image.decode_jpeg(image_raw_data)
     print(img_data.eval())

     plt.imshow(img_data.eval())
     plt.show()

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

     encoded_image = tf.image.encode_jpeg(img_data)
     with tf.gfile.GFile("img/2.jpg","wb") as f:
          f.write(encoded_image.eval())

输出:

                                                                             [[ 63  54  37]
                                                                              [ 72  63  46]
                                                                              [ 77  68  51]
                                                                               ...
                                                                               [ 68  85  53]
                                                                               [ 72  87  66]
                                                                               [ 74  91  75]]

                                                                              [[ 73  64  47]
                                                                               [ 80  71  54]
                                                                               [ 85  76  59]
                                                                               ...
                                                                               [ 71  88  56]
                                                                               [ 75  90  69]
                                                                               [ 76  93  77]]]       (太长了,略一下)

                                 

其中: tf.image.decode_jpeg()函数为jpeg(jpg)图片解码的过程,对应的encode_jpeg函数为编码过程,编码后将图片重命名写入到指定的路径下。类似的函数还有tf.image.encode_png(),可以对图片进行PNG编码.。


图像尺寸调整

在Tensorflow中通过tf.image.resize_images()函数实现对图像尺寸的调整,函数定义为:

                                 def resize_images(images,
                                                   size,
                                                   method=ResizeMethod.BILINEAR,
                                                   align_corners=False):

第一个输入参数:image,输入图像,形状为[batch, height, width, channels]的4-D张量或形状为[height, width, channels]的3-D张量;

第二个输入参数:size,2个元素(new_height, new_width)的1维int32张量,表示图像的新大小,如:[300,300];

第三个输入参数:method,可选参数::(method=0:双线性插值算法(Bilinear interpolation),

                                                                method=1:最近邻居法(Nearest  neighbor interpolation),

                                                                method=2:双三次插值法(Bicubic interpolation),

                                                                method=3:面积插值法(Area interpolation));

第四个输入参数:align_corners,布尔型,如果为True,则输入和输出张量的4个拐角像素的中心对齐,并且保留角落像素处的值,默认为False.;

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
 
image_raw_data = tf.gfile.GFile('img/1.jpg','rb').read()   #加载原始图像
 
with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(image_raw_data)
    plt.imshow(img_data.eval())
    plt.show()
 
    resized = tf.image.resize_images(img_data, [300,300],method=0)  #第一个参数为原始图像,第二个参数为图像大小,第三个参数给出了指定的算法
    resized = np.asarray(resized.eval(),dtype='uint8')
    plt.imshow(resized)
    plt.show()

               

         输出:

                

此外,类似的函数还有很多,比如:resize_area(...):调整images为size使用区域插值,

                                                                resize_bicubic(...):调整images为size使用双三次插值,

                                                                             resize_bilinear(...):调整images为size使用双线性插值.,                                                                                                                             resize_image_with_crop_or_pad(...):裁剪或将图像填充到目标宽度和高度,

                                                                resize_nearest_neighbor(...):使用最近的相邻插值调整图像的大小。



图像翻转

tensorflow提供了一些函数来支持对图像的翻转,主要函数有:

                   tf.image.flip_left_right(...):水平翻转图像(从左到右);

                   tf.image.flip_up_down(...):垂直翻转图像(颠倒);

                   tf.image.random_flip_left_right(...):水平(从左到右)随机翻转图像;

                   tf.image.random_flip_up_down(...):垂直(颠倒)随机翻转图像。

# coding:utf-8

import matplotlib.pyplot as plt
import tensorflow as tf
# 读取图像数据
img = tf.gfile.FastGFile('img/1.jpg','rb').read()

with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(img)

    flipped0 = tf.image.flip_up_down(img_data)

    flipped1 = tf.image.flip_left_right(img_data)

    flipped2 = tf.image.transpose_image(img_data)

    plt.subplot(221), plt.imshow(img_data.eval()), plt.title('original')
    plt.subplot(222), plt.imshow(flipped0.eval()), plt.title('flip_up_down')
    plt.subplot(223), plt.imshow(flipped1.eval()), plt.title('flip_left_right')
    plt.subplot(224), plt.imshow(flipped2.eval()), plt.title('transpose_image')
    plt.tight_layout()

    plt.show()

输出:

                                


图像色彩调整

调整图像对比度、亮度、饱和度和色相在很多图像识别应用中都不会影像识别结果,所以在训练神经网络模型时,可以随机调整训练图像的这些属性,从而使训练的模型尽可能小的受到无关因素的影响,tensorflow提供了很多调整这些相关属性的AP-I,主要函数有:

                                adjust_brightness(...):调整RGB或灰度图像的亮度;

                                adjust_contrast(...):调整RGB或灰度图像的对比度;

                                adjust_gamma(...):对输入图像执行Gamma校正;

                                adjust_hue(...):调整RGB图像的色调;

                                adjust_saturation(...):调整RGB图像的饱和度;

                                tf.image.per_image_standardization(...):标准化调整。

# coding:utf-8

import matplotlib.pyplot as plt
import tensorflow as tf
# 读取图像数据
img = tf.gfile.FastGFile('img/1.jpg','rb').read()

with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(img)
    
    #第二个参数可修改
    adjusted0 = tf.image.adjust_brightness(img_data, -0.5)
    adjusted1 = tf.image.adjust_contrast(img_data, -5)
    adjusted2 = tf.image.adjust_saturation(img_data, 0.1)
    adjusted3 = tf.image.adjust_saturation(img_data, -5)
    adjusted4 = tf.image.per_image_standardization(img_data)

    plt.subplot(231), plt.imshow(img_data.eval()), plt.title('original')
    plt.subplot(232), plt.imshow(adjusted0.eval()), plt.title('adjust_brightness')
    plt.subplot(233), plt.imshow(adjusted1.eval()), plt.title('adjust_contrast')
    plt.subplot(234), plt.imshow(adjusted2.eval()), plt.title('adjust_saturation')
    plt.subplot(235), plt.imshow(adjusted3.eval()), plt.title('adjust_saturation')
    plt.subplot(236), plt.imshow(adjusted4.eval()), plt.title('per_image_standardization')
    plt.tight_layout()

    plt.show()

输出:


处理标注框

在很多图像识别的数据集中,图像中需要关注的物体通常会被标注框圈出来。tensorflow提供了一些工具来处理标注框。首先介绍两个函数:

                              tf.image.draw_bounding_boxes():在指定坐标圈标注框;

                             tf.image.sample_distorted_bounding_box():随机坐标画标注框。

# coding:utf-8

import matplotlib.pyplot as plt
import tensorflow as tf
# 读取图像数据
img = tf.gfile.FastGFile('img/1.jpg','rb').read()

with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(img)
    expand = tf.expand_dims(tf.image.convert_image_dtype(img_data, dtype=tf.float32),0)

    boxes = tf.constant([[[0.07, 0.45, 0.3, 0.6]]])
    
    result = tf.image.draw_bounding_boxes(images=expand, boxes=boxes)

    boxes2 = tf.constant([[[0.07, 0.45, 0.3, 0.6], [0.5, 0.2, 0.7, 0.4]]])

    batched2 = tf.expand_dims(tf.image.convert_image_dtype(img_data, dtype=tf.float32), 0)

    img_withbox = tf.image.draw_bounding_boxes(images=batched2, boxes=boxes2)

    begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(
        tf.shape(img_data), bounding_boxes=boxes2, min_object_covered=0.1
    )

    distorted_image = tf.slice(img_data, begin=begin, size=size)

    plt.subplot(131), plt.imshow(img_data.eval()), plt.title('original')
    plt.subplot(132), plt.imshow(result.eval().reshape([500,500,3])), plt.title('draw_bounding_box')
    plt.subplot(133), plt.imshow(distorted_image.eval()), plt.title('sample_distored_bounding_box')

    plt.tight_layout()

    plt.show()

输出:

 

 

注意:tf.image.draw_bounding_box()的输入图像是多张图像组成的四维矩阵,所以需要将解码后的图像矩阵加一维,使用了tf。expand_dims()函数。


参考文献:https://www.w3cschool.cn/tensorflow_python/tensorflow_python-m7ku2pvd.html