TensorFlow學習(十):圖像預處理

更新時間:

2018.6.2
增加了通過 tf.image 進行數據增強的內容,非常重要,可以直接跳到第四節。

之前做的一些任務都是從.csv文件裏面讀取數據來處理,這些元素都已經是處理好的值了,所以很方便。但是更多時候,我們是要從硬盤上的圖片直接來做處理,所以,這裏需要用到一些基本的圖像處理有關的函數了。OpenCV肯定是可以使用的,但是tensorflow本身也提供了一些好用的函數。
因爲通過Tensorflow完成圖像有關的任務太多了,所以瞭解一點Tensorflow中自帶的圖像處理有關的函數是很有必要的。
Tensorflow中內置的圖像處理的函數肯定沒有OpenCV那麼多那麼強大啦,但是僅僅是作爲簡單的預處理的話,完全是夠用了。

主要使用的模塊就是tf.image,所以首先要是先把官方文檔列出來:Module: tf.image,然後接下來就是按照圖片處理的順序來分別講解各個函數的使用。
本節的完整測試代碼,可以在我的GitHub:LearningTensorFlow/12.ImageProcess/上找到。

一.圖像的編解碼

Ⅰ.概覽

下面是tensorflow自帶編解碼部分的函數,這裏一起列出來,但是並不會全部都詳細講,因爲使用方式大同小異,在例子中只是詳細講其中一個,其他的都可以類比或者看文檔寫出來,實在是很簡單,就不需要多花筆墨。

decode_gif(…): Decode the first frame of a GIF-encoded image to a uint8 tensor.
decode_jpeg(…): Decode a JPEG-encoded image to a uint8 tensor.
decode_png(…): Decode a PNG-encoded image to a uint8 or uint16 tensor.
decode_image(…): Convenience function for decode_gif, decode_jpeg, and decode_png.
encode_jpeg(…): JPEG-encode an image.
encode_png(…): PNG-encode an image.

在這一步,要是隻是想把某個或者某些個文件讀到ndarray中去,推薦更加高效的做法,就是使用matplot.image中的imread()方法,或者opencv中的方法,都是很簡單無腦的。
比如在這裏,我文件夾下面有個叫做“1.jpg”的文件,那麼就可以用比較簡單的方法得到:
這裏寫圖片描述

二.數據轉化和形狀變換

這一步的目的是什麼呢?首先,很多圖像像素默認是int類型的,在tensorflow裏面,float類型的數據更加適合處理,然後形狀來說,我們知道,對於圖片來說,一個網絡的輸入尺寸是固定的,而訓練的時候圖片的尺寸確不一定是固定的,所以有必要用各種方式把圖片尺寸轉換爲固定的適合網絡輸入的格式。

Ⅰ.數據類型轉化

convert_image_dtype(image,dtype,saturate=False,name=None)

作用:把圖片元素類型,轉成想要的類型,返回轉換後的圖片,注意,要是轉成了float類型之後,像素值會在 [0,1)這個範圍內
參數:
image: 圖像
dtype: 待轉換類型
saturate: If True, clip the input before casting (if necessary).
name: 可選操作名

with graph.as_default():
    #convert type
    pic=tf.image.convert_image_dtype(image=pic,dtype=tf.float32)
with session.as_default():
    pic_run=session.run(pic)
    print("type of pic:",pic_run.dtype)
    print(pic_run)
    plt.imshow(pic_run)

結果:
這裏寫圖片描述

Ⅱ.形狀變換

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

作用:使用指定的方法來改變形狀
參數:
images: 4維tensor,形狀爲 [batch, height, width, channels] 或者3維tensor,形狀爲 [height, width, channels].
size: 1維 int32類型的 Tensor,包含兩個元素:new_height, new_width.
method: 改變形狀的方法,默認是ResizeMethod.BILINEAR.

ResizeMethod.BILINEAR: 雙線性插值(Bilinear interpolation.)
ResizeMethod.NEAREST_NEIGHBOR: 最近鄰插值(Nearest neighbor interpolation.)
ResizeMethod.BICUBIC: 雙三次插值(Bicubic interpolation.)
ResizeMethod.AREA: 面積插值(Area interpolation.)

align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to false.

還有其他類似的函數帶有剪裁和形狀改變的功能,,如

resize_image_with_crop_or_pad(…): Crops and/or pads an image to a target width and height.
central_crop(…): Crop the central region of the image.
crop_and_resize(…): Extracts crops from the input image tensor and bilinearly resizes them (possibly
crop_to_bounding_box(…): Crops an image to a specified bounding box.

因爲使用上面差不多,所以就不一個個詳細介紹了,可以看文檔,選擇合適的方法來使用.

Ⅲ.圖像翻轉

上面介紹了尺寸的問題,然後就是翻轉的問題了.爲什麼要翻轉呢?以這幅圖爲例:
這裏寫圖片描述
神經網絡其實是很”笨”的,要是你提供的圖片都是像上面那樣朝向左邊,那麼當出現一幅朝向右邊的圖片的時候,它很可能無法識別.
所以,可以人爲的多加一些翻轉上去,使得各個角度的圖片都有一點,無形中,擴充了數據量,還緩解了識別錯誤的問題.
翻轉有一些常見的函數,

flip_left_right(…): 左右翻轉
flip_up_down(…): 上下翻轉
transpose_image(…): 對角線翻轉
random_flip_left_right(…): 隨機左右翻轉
random_flip_up_down(…): 隨機上下翻轉

同樣,使用方法都是差不多的,這裏值以第一個爲例子,其他的類比使用就行了.
flip_left_right(image)

作用:左右翻轉一幅圖片,返回一個形狀和原圖片相同的圖片(翻轉後)
參數:
image: 3維tensor,形狀爲[height, width, channels].

這裏寫圖片描述

三.顏色變換

和前面使用翻轉可以來”增加數據集”以外,調節顏色屬性也是同樣很有用的方法,這裏主要有調整亮度,對比度,飽和度,色調等方法.如下:
亮度:

adjust_brightness(…): 調整亮度
random_brightness(…): 隨機調整亮度

對比度:

adjust_contrast(…): 調整對比度
random_contrast(…): 隨機調整亮度

飽和度:

adjust_saturation(…): 調整飽和度
random_saturation(…): 隨機調整飽和度

色調:

adjust_hue(…): 調整色調
random_hue(…): 隨機調整色調

這裏只舉一個調節亮度的例子,其他大同小異,可以試一下看結果
adjust_brightness(image,delta)

作用:調節亮度
參數:
image: tensor,原圖片
delta: 標量,待加到像素值上面的值.

這裏寫圖片描述

四.數據增強相關

數據增強的作用就不多說了,tensorflow的數據預處理部分也給出了一些數據增強的方法,表面上看上去也許只是普通的圖片變換,但是這些方法在一方面來說能夠非常有效的擴充“數據集”。
這幾個方法就是tf.image裏面帶有random的一些方法。也就是隨機怎樣怎樣,上面其實已經列國了,這裏再列出來一遍,大家可以根據需要來選擇可能用到的.

random_brightness(…): Adjust the brightness of images by a random factor.

random_contrast(…): Adjust the contrast of an image by a random factor.

random_flip_left_right(…): Randomly flip an image horizontally (left to right).

random_flip_up_down(…): Randomly flips an image vertically (upside down).

random_hue(…): Adjust the hue of an RGB image by a random factor.

random_saturation(…): Adjust the saturation of an RGB image by a random factor.

本節只詳細介紹三個非常有用的的函數,兩個是翻轉圖像的,分別是random_flip_left_right(...)random_flip_up_down(...) 看名字就知道是左右翻轉和上下翻轉,還有一個是tf.image.sample_distorted_bounding_box 是隨機截取圖像。

tf.image.sample_distorted_bounding_box(image_size,bounding_boxes,seed=Noneseed2=None,min_object_covered=0.1,aspect_ratio_range=None,area_range=None,max_attempts=None,use_image_if_no_bounding_boxes=None,name=None)

Generate a single randomly distorted bounding box for an image.

Bounding box annotations are often supplied in addition to ground-truth labels in image recognition or object localization tasks. A common technique for training such a system is to randomly distort an image while preserving its content, i.e. data augmentation. This Op outputs a randomly distorted localization of an object, i.e. bounding box, given an image_size, bounding_boxes and a series of constraints.

The output of this Op is a single bounding box that may be used to crop the original image. The output is returned as 3 tensors: begin, size and bboxes. The first 2 tensors can be fed directly into tf.slice to crop the image. The latter may be supplied to tf.image.draw_bounding_boxes to visualize what the bounding box looks like.

Bounding boxes are supplied and returned as [y_min, x_min, y_max, x_max]. The bounding box coordinates are floats in [0.0, 1.0] relative to the width and height of the underlying image.

For example,

# Generate a single distorted bounding box.
begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(
    tf.shape(image),
    bounding_boxes=bounding_boxes,
    min_object_covered=0.1)

# Draw the bounding box in an image summary.
image_with_box = tf.image.draw_bounding_boxes(tf.expand_dims(image, 0),
                                              bbox_for_draw)
tf.summary.image('images_with_box', image_with_box)

# Employ the bounding box to distort the image.
distorted_image = tf.slice(image, begin, size)

Note that if no bounding box information is available, setting use_image_if_no_bounding_boxes = true will assume there is a single implicit bounding box covering the whole image. If use_image_if_no_bounding_boxes is false and no bounding boxes are supplied, an error is raised.

Args:
image_size: A Tensor. Must be one of the following types: uint8, int8, int16, int32, int64. 1-D, containing [height, width, channels].
bounding_boxes: A Tensor of type float32. 3-D with shape [batch, N, 4] describing the N bounding boxes associated with the image.
seed: An optional int. Defaults to 0. If either seed or seed2 are set to non-zero, the random number generator is seeded by the given seed. Otherwise, it is seeded by a random seed.
seed2: An optional int. Defaults to 0. A second seed to avoid seed collision.
min_object_covered: A Tensor of type float32. Defaults to 0.1. The cropped area of the image must contain at least this fraction of any bounding box supplied. The value of this parameter should be non-negative. In the case of 0, the cropped area does not need to overlap any of the bounding boxes supplied.
aspect_ratio_range: An optional list of floats. Defaults to [0.75, 1.33]. The cropped area of the image must have an aspect ratio = width / height within this range.
area_range: An optional list of floats. Defaults to [0.05, 1]. The cropped area of the image must contain a fraction of the supplied image within in this range.
max_attempts: An optional int. Defaults to 100. Number of attempts at generating a cropped region of the image of the specified constraints. After max_attempts failures, return the entire image.
use_image_if_no_bounding_boxes: An optional bool. Defaults to False. Controls behavior if no bounding boxes supplied. If true, assume an implicit bounding box covering the whole input. If false, raise an error.
name: A name for the operation (optional).
Returns:
A tuple of Tensor objects (begin, size, bboxes).

begin: A Tensor. Has the same type as image_size. 1-D, containing [offset_height, offset_width, 0]. Provide as input to tf.slice.
size: A Tensor. Has the same type as image_size. 1-D, containing [target_height, target_width, -1]. Provide as input to tf.slice.
bboxes: A Tensor of type float32. 3-D with shape [1, 1, 4] containing the distorted bounding box. Provide as input to tf.image.draw_bounding_boxes.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章