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)
- 亮度調整
#將影象的亮度-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)
- 對比度調整
#將影象的對比度減少到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)
- 色相調整
#將色相加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)
- 飽和度調整
#將影象的飽和度-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)
- 影象標準化
該操作將影象上的亮度均值變成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()