1. 程式人生 > >TensorFlow學習筆記(10) 影象資料處理

TensorFlow學習筆記(10) 影象資料處理

通過對影象的預處理,可以避免模型受到無關因素的影響,可以提高模型的準確率。

影象編碼處理

影象在儲存時並不是直接記錄影象矩陣中各個畫素值,而是記錄經過壓縮編碼之後的結果。將一張影象還原成矩陣,需要解碼的過程。TF提供了對jpeg和png格式影象的編碼/解碼函式:

import matplotlib.pyplot as plt
import tensorflow as tf

#讀取原始影象資料
image_raw_data = tf.gfile.FastGFile('picture.jpeg', 'rb').read()

with tf.Session() as sess:
    #tf.image.decode_jpeg對jpeg影象進行解碼
    #tf.image.decode_png對png影象進行解碼,結果均為一張量
    img_data = tf.image.decode_jpeg(image_raw_data)
    print(sess.run(img_data))

    plt.imshow(sess.run(img_data))
    plt.show()

    #轉換資料型別為實數方便處理
    img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)

    #編碼為jpeg格式    
    img_data = tf.image.convert_image_dtype(img_data, dtype=tf.uint16)
    encode_img = tf.image.encode_jpeg(img_data)
    with tf.gfile.FastGfile('picture_out.png', 'wb') as f:
        f.write(sess.run(encode_img))

影象大小調整

影象大小的調整有兩種方式,第一種是通過演算法使得新的影象儘量儲存原始影象上的資訊。

#img_data是已經經過解碼且進行型別轉化的資料

#第二個第三個引數為調整後圖像的大小
#method=0   採用雙線性插值法
#method=1   採用最近鄰居法
#method=2   採用雙三次插值法
#method=3   採用面積插值法
resized = tf.image.resize_images(img_data, [300, 300], method=0)

TF也提供了對影象進行裁剪或填充的方法

#通過tf.image.resize_image_with_crop_or_pad可以實現影象的裁剪和填充
#如果給定尺寸比原圖大則填充,否則裁剪原圖居中部分
croped = tf.image.resize_image_with_crop_or_pad(img_data, [1000, 1000])
padded = tf.image.resize_image_with_crop_or_pad(img_data, [3000, 3000])

另外tf.image.crop_to_bounding_box函式和tf.image.pad_to_bounding_box函式可以用來剪裁或填充給定區域的影象。


影象翻轉

以下程式碼實現影象上下翻轉、左右翻轉以及對角線翻轉。

    fliped = tf.image.flip_up_down(img_data)
    fliped = tf.image.flip_left_right(img_data)

    transposed = tf.image.transpose_image(img_data)

通過隨機翻轉訓練影象的方式可以使得訓練得到的模型可以識別不同角度的實體:

    fliped = tf.image.random_flip_up_down(img_data)
    fliped = tf.image.random_flip_left_right(img_data)


影象色彩調整

#亮度-0.5 及 +0.5
adjusted = tf.image.adjust_brightness(img_data, -0.5)
adjusted = tf.image.adjust_brightness(img_data, +0.5)
#在[-x,x]範圍內隨機調整亮度
adjusted = tf.image.random_brightness(img_data, x)

#對比度-0.5 及 +0.5
adjusted = tf.image.adjust_contrast(img_data, -0.5)
adjusted = tf.image.adjust_contrast(img_data, +0.5)
#在[x,y]範圍內隨機調整對比度
adjusted = tf.image.random_contrast(img_data, x, y)

#色相 +0.1  及 +0.5
adjusted = tf.image.adjust_hue(img_data, 0.1)
adjusted = tf.image.adjust_hue(img_data, 0.5)
#在[-x,x]範圍內隨機調整色相
adjusted = tf.image.random_hue(img_data, x)

#飽和度 -0.5 及 +0.5
adjusted = tf.image.adjust_saturation(img_data, -0.5)
adjusted = tf.image.adjust_saturation(img_data, 0.5)
#在[-x,x]範圍內隨機調整飽和度
adjusted = tf.image.random_saturation(img_data, x, y)

#將影象變為均值為0方差為1的影象(二值圖?)
adjusted = tf.image.per_image_standardization(img_data)


處理標註框

TF提供了一些工具來標註影象中需要關注的物體,使用tf.image.draw_bounding_boxes可以在影象中加入標註框。

    img_data = tf.image.resize_images(img_data, [108, 192], method=0)
    #由於tf.image.draw_bounding_boxes函式輸入影象為一個四維矩陣,所以解碼之後要加一維,其中第一維度表示第幾張圖片
    batched = tf.expand_dims(tf.image.convert_image_dtype(img_data, tf.float32), 0)
    #給出影象的標註框,一個標註框有四個數字,分別代表[ymin,xmin,ymax,xmax],其中數字都代表其相對位置
    boxes = tf.constant([[[0.1, 0.2, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
    result = tf.image.draw_bounding_boxes(batched, boxes)

    plt.imshow(sess.run(result[0]))
    plt.show()

另外,也可以通過tf.image.sample_distorted_bounding_box函式實現影象的隨機擷取,這樣可以提高模型的robustness,不受被識別物體大小的影響。

    boxes = tf.constant([[[0.1, 0.2, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
    #通過提供標註框的方式來限定隨機擷取的範圍
    begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(tf.shape(img_data), bounding_boxes=boxes)
    batched = tf.expand_dims(tf.image.convert_image_dtype(img_data, tf.float32), 0)
    #繪製標註框
    image_with_box = tf.image.draw_bounding_boxes(batched, bbox_for_draw)
    #提取截圖切片
    distorted_image = tf.slice(img_data, begin, size)