1. 程式人生 > >tensorflow學習(10):影象處理函式

tensorflow學習(10):影象處理函式

一、影象編碼處理

眾所周知,一張RGB彩色想可以看成一個三維矩陣,矩陣中的每一個數字表示了影象上不同位置,不同顏色的亮度。但是影象在儲存時不是直接記錄這些距震中的數字,而是記錄經過壓縮編碼之後的結果,因此要將一張影象還原成一個三維矩陣,需要解碼。tensorflow提供了對JPEG和PNG格式影象的編碼/解碼函式。
下列程式碼解釋了編碼和解碼的過程

import tensorflow as tf
import matplotlib.pyplot as plt

#讀取原始資料,r表示UTF-8編碼,rb表示非UTF-8編碼
image_raw_data = tf.gfile.FastGFile('dog.jpg','rb').read()  

with tf.Session() as sess:
    #對影象的JPEG格式解碼從而得到影象對應的三維矩陣。tensorflow還提供了tf.image.decode_png函式對png格式的影象進行解碼
    #解碼之後的結果為一個張量,在使用它的取值之前需要明確呼叫執行的過程
    image_data = tf.image.decode_jpeg(image_raw_data)
    #輸出解碼之後的三維矩陣
    print(image_data.eval())
    #視覺化影象
    plt.imshow(image_data.eval())
    plt.show()

    #將表示一張影象的三維矩陣重新按照JPEG格式編碼並存入檔案中,開啟這張影象,可以得到和原始影象一樣的影象
    encoded_image = tf.image.encode_jpeg(image_data)
    with tf.gfile.GFile('F:/python-code/tensorflow_learning/dog1.jpg','wb') as f:
        f.write(encoded_image.eval())

二、影象大小處理

這裡會牽涉到影象放大的方法,想要了解的請移步這裡影象內插

1.tf.image.resize_images(input_image,output_size,method)
該函式是將整幅影象進行放大或縮小,其中method的取值如下:

method取值 影象大小調整演算法
0 雙線性插值法
1 最近鄰居法
2 雙三次插值法
3 面積插值法

接下來的程式碼放在上述程式碼的plt.show()之後即可

    #將image_data原本是0-255中的整數轉換成0-1之間的浮點數
    image_data = tf.image.convert_image_dtype(image_data,dtype = tf.float32)
    resized = tf.image.resize_images(image_data,[300,300],method=0)
    plt.imshow(resized.eval())
    plt.show()

需要將0-255的畫素值轉化為0.0-1.0範圍內的實數的原因:大多數API支援整數和實數型別的輸入。如果實數型別,這些API會在內部將輸入轉化為實數後處理,在將輸出轉化為整數。如果有多個處理步驟,在實數和整數之間反覆轉化會導致精度損失,因此最好在影象處理前將其轉化為實數型別

2.tf.image.resize_image_with_crop_or_pad(input_img, h,w)
該函式用於對影象進行裁剪或者填充。h,w分別表示輸出影象的height,weight
如果輸出影象的大小小於輸入影象,那麼這個函式會自動擷取原始影象中居中的部分,如果輸出影象的大小小於輸入影象,那麼這個函式會自動在原始影象的四周填充全零背景

    image_data = tf.image.resize_image_with_crop_or_pad(image_data,300,300)
    plt.imshow(image_data)
    plt.show()

3.tf.image.central_crop(input, alpha)
該函式用於按比例裁剪影象中間的部分,其中0<alpha<=1

    image_data = tf.image.central_crop(image_data,0.5)
    plt.imshow(image_data)
    plt.show()

三、影象翻轉

    #上下翻轉
    flipped = tf.image.flip_up_down(image_data)
    plt.imshow(flipped.eval())
    plt.show()

左右翻轉和沿著對角線翻轉函式如下所示
flipped = tf.image.flip_left_right(image_data)
flipped = tf.image.transpose_image(image_data)

另外,在訓練時,需要對影象進行隨機翻轉,tensorflow提供了下述函式進行概率為50%的隨機翻轉:
flipped = tf.image.random_flip_left_right(image_data)
flipped = tf.image.random_flip_up_down(image_data)

四、影象色彩調整

和影象反轉類似,調整影象的亮度,對比度,飽和度和色相在很多影象識別應用中都不應該影響識別結果。所以在訓練神經網路模型時,可以隨機調整訓練影象的屬性,從而使訓練得到的模型儘可能小的收到無關因素的影響 。
色彩跳幀給定API可能導致畫素的實數值超出0.0-1.0的範圍,因此在輸出最終影象前要將其值截斷在0.0-1.0範圍,否則會出錯。
截斷函式:tf.clip_by_value(input,0.0,1.0)

  1. 亮度調整
#將影象的亮度-0.5
adjusted = tf.image.adjust_brightness(image_data, -0.5)
#在[-max_delta, max_delta] 的範圍隨機調整影象的亮度
adjusted = tf.image.random_brightness(image_data, max_delta)
#調整完之後別忘了截斷
adjusted = tf.clip_by_value(adjusted, 0.0 , 1.0)
  1. 對比度調整
#將影象的對比度減少到0.5倍
adjusted = tf.image.adjust_contrast(image_data, 0.5)
#將影象的對比度增加到5倍
adjusted = tf.image.adjust_contrast(image_data, 5)
#在[lower, upper]範圍內隨機調整對比度
adjusted = tf.image.random_contrast(image_data, lower, upper)
  1. 色相調整
#將色相加0.1
adjusted = tf.image.adjust_hue(image_data, 0.1)
#在[-max_delta, max_delta]範圍內隨機調整色相,0<max_delta<0.5
adjusted = tf.image.random_hue(image_data, max_delta)
  1. 飽和度調整
#將影象的飽和度-5
adjusted = tf.image.adjust_saturation(image_data, -5)
#將影象的飽和度+5
adjusted = tf.image.adjust_saturation(image_data, +5)
#在[lower, upper] 範圍呃逆隨機調整影象的飽和度
adjusted = tf.image.random_saturation(image_data, lower, upper)
  1. 影象標準化
    該操作將影象上的亮度均值變成0,方差變成1
adjusted = tf.image.per_image_standardization(image_data)

五、標註框

在很影象識別的資料集中,影象中需要關注的物體通常會被標註框圈出來。tensorflow提供了一些工具來處理標註框,以下程式碼展示瞭如何通過tf.image.draw_bounding_boxes函式在影象中加入標註框

    #將影象縮小一些,這樣視覺化能讓標註框更加清楚
    image_data = tf.image.resize_images(image_data,[182,267],method=1)
    #tf.image.draw_bounding_boxes函式要求影象矩陣中的數字為實數,所以需要先將影象矩陣轉化
    #成實數型別,而且其輸入是一個batch資料,也就是多張影象組成的四維矩陣,所以需要將解碼之後的影象矩陣加一維
    batched = tf.expand_dims(tf.image.convert_image_dtype(image_data,tf.float32),0)
    #給出每一張影象的所有標註框,一個標註框有四個數字,分別代表[ymin,xmin,ymax,xmax]
    #注意,這裡給出的數字都是影象的相對位置,範圍在0-1之間
    #boxes需要三維陣列的原因,分別代表了[batch, N, 4]
    boxes = tf.constant([[[0.05,0.05,0.9,0.7],[0.35,0.47,0.5,0.56]]])
    result = tf.image.draw_bounding_boxes(batched, boxes)
    plt.imshow(result[0].eval())
    plt.show()