Hike News
Hike News

深度學習-tensorflow基礎-讀取數據-API應用-圖像讀取

Introduction

圖像基本知識

  • 在電腦中圖片是由pixel(像素)組成的
  • 圖片的特徵值就是像素值(長度x寬度x通道數)
  • 黑白圖片又稱為單通道圖片:每一個像素點只有一個值(灰度值),介於0~255之間
  • 彩色圖片又稱為三通道圖片:每一個像素點由RGB三個值組成

張量表達圖片數據

圖像數字化

三要素:長度、寬度、通道數

  • 一通道:灰度值
  • 三通道:RGB

三要素與張量的關係

指定3-D張量:[長度,寬度,通道數(channel)]

  • 通道數決定彩色或是黑白圖片

圖像基本操作

機器學習進行分類時,每一個樣本必須保持特徵值數量一致(將所有圖片統一大小,像素值一樣)

目的

  • 增加圖片數據的統一性
  • 所有圖片轉換成指定大小
  • 縮小圖片數據量,防止增加開銷

縮放圖片大小

  • tf.image.resize_images(images,size)
    • resize過後的圖片可能會改變圖片的數據,整數(uint8)—->浮點數(float32)
      • 一般圖片都是用uint8類型儲存,float32類型還原不了為一張圖片
        • uint8用於存儲:節約空間
        • float32用於提高矩陣計算的經度
      • 但是計算都是使用float32進行計算
    • images
      • 4-D形狀([batch, height, width, channels])張量的圖片數據
        • batch:幾張圖片
      • 3-D形狀([height, width, channels])張量的圖片數據
    • size
      • 1-D int32張量
      • new_height, new_width:圖像的新尺寸,例如[200,200]
    • 返回4-D格式 或 3-D格式的圖片

構造圖片文件隊列

與讀取文字文件的文件隊列相同

構造讀取器

  • 圖片是一張一張的讀取
  • tf.WholeFileReader()
    • 文件的全部內容作為值輸出的讀取器
    • 常用於圖片讀取
    • 返回一個圖像讀取器實例

method

  • read(file_queue):輸出將是一個文件名(key)和該文件的內容(value)
    • 預設value為一張圖片的內容

圖片解碼

其對應不同的圖片格式擁有不同的解碼器

JPEG

  • tf.image.decode_jpeg(contents)
    • 將JPEG編碼的圖像解碼為uint8類型的張量
    • contents:讀取器讀取出來的文件內容
      • 也就是read方法的value內容
    • 返回一個uint8張量
      • 3-D形狀([height,width,channels])

PNG

  • tf.image.decode_png(contents)
    • 將PNG編碼的圖像解碼為uint8 或 uint16類型的張量
    • 返回一個uint8 或 uint16張量類型
      • 3-D形狀([height,width,channels])

批處理

在進行批處理之前長、寬、通道數全部都必須定義,不能有不確定的值,否則會報錯

  • 利用set_shape方法固定長、寬、通道數
  • batch方法與文件批處理相同

讀取狗的圖片範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import tensorflow as tf
import glob

# 讀取狗的圖片並轉換成張量
def picread(filelist):
# 2. 構造文件隊列
file_queue = tf.train.string_input_producer(filelist)

# 3. 構造圖片讀取器讀取圖片內容(預設值是讀取一張圖片)
reader = tf.WholeFileReader()
key,val = reader.read(file_queue)

# 4. 對讀取圖片進行解碼
image_data = tf.image.decode_jpeg(val) # 讀取出來image_data為unit8類型,shape(?,?,?),分別為長、寬、通道數

# 5. 處理圖片的大小(統一大小)
image_resize = tf.image.resize_images(image_data,[200,200])

# 注意:批處理之前一定要把樣本的形狀固定[200,200,3]
image_resize.set_shape([200,200,3])

# 6. 進行批處理
image_batch = tf.train.batch([image_resize],batch_size=100,num_threads=1,capacity=100)

return image_batch

if __name__ == '__main__':
# 1. 找到文件,並放入列表 路徑+名字--->列表當中
file_name = glob.glob("./dog_pic/*.jpg")
filelist = [path_name for path_name in file_name]

image_batch = picread(filelist)

# 開啟會話運行結果
with tf.Session() as sess:
# 定義一個線程協調器
coord = tf.train.Coordinator()

# 開啟讀文件的線程
threads = tf.train.start_queue_runners(sess,coord = coord)

# 查看讀取的內容(模擬訓練)
print(sess.run([image_batch]))

# 回收子線程
coord.request_stop()
coord.join(threads)

Result

1
2
3
4
5
6
7
8
9
10
11
[array([[[[255.        , 255.        , 255.        ],
[255. , 255. , 255. ],
[255. , 255. , 255. ],
...,
[[199. , 98. , 56. ],
[197.28 , 100.12 , 55.08 ],
[204.24 , 103.479996 , 57.239998 ],
...,
[129.4002 , 82.00026 , 69.40021 ],
[109.520035 , 77.16 , 74.359985 ],
[ 94.56012 , 72.20004 , 74.04001 ]]]], dtype=float32)]

tips

  • 讀取出來的圖片矩陣要儲存,為了節省空間最好使用uint8類型進行儲存
  • 如要將圖片數據進行計算,為了提高精度需使用tf.cast()轉換類型的方法轉換成float32類型