1. 程式人生 > >【TensorFlow】資料處理(對影象的處理)

【TensorFlow】資料處理(對影象的處理)

專案已上傳至 GitHub —— img-pre

1. 目錄結構

images/ 資料夾下存放將被用於處理的影象,img_all.py 示範了 TensorFlow 中影象處理函式的使用方法,img_pre.py 給出了一個對影象進行預處理的程式示例:

img-pre/
    images/
        1.jpg
    img_all.py
    img_pre.py

2. 影象處理函式

2.1 編碼處理

在使用影象之前需要先對影象進行解碼,將影象轉為畫素矩陣,tensorflow.image 提供了影象解碼函式,返回的矩陣資料型別是 uint8:

  • decode_jpeg:解碼 JPEG 格式影象
  • decode_and_crop_jpeg:解碼並裁剪 JPEG 格式影象
  • decode_png:解碼 PNG 格式影象
  • decode_gif:解碼 GIF 格式影象
  • decode_bmp:解碼 BMP 格式影象
  • decode_image:自動檢測影象格式進行解碼,注意 GIF 格式影象返回一個四維矩陣

以下程式碼示範對 JPEG 格式影象的解碼處理:

import tensorflow as tf
import matplotlib.pyplot as plt

# 讀取影象的原始資料
image_raw_data = tf.gfile.FastGFile('images/1.jpg', 'rb'
).read() # 使用pyplot顯示影象 def show(img_data): plt.imshow(img_data.eval()) plt.show() with tf.Session() as sess: # 將原始資料解碼成多維矩陣 img_data = tf.image.decode_jpeg(image_raw_data) print(img_data.eval()) show(img_data) # 將影象的矩陣編碼成影象並存入檔案 encoded_image = tf.image.encode_jpeg(
img_data) with tf.gfile.GFile('images/output.jpg', 'wb') as f: f.write(encoded_image.eval()) # 將影象資料的型別轉為實數型別,便於對影象進行處理 img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)

2.2 大小調整

tf.image.resize_images 函式中有四種調整影象的方法,結果會有細微差別:

method 影象大小調整演算法
0 雙線性插值法(Bilinear interpolation)
1 最近鄰居法(Nearest neighbor interpolation)
2 雙三次插值法(Bicubic interpolation)
3 面積插值法(Area interpolation)

以下程式碼都是在影象編碼處理程式碼的基礎下執行,省去了載入原始影象,定義會話等過程:

    # 用resize_images調整影象大小
    # 第一個引數為原始影象
    # 第二個引數為調整後的影象大小[new_height,new_width],跟舊版本分為兩個引數不一樣
    # method引數給出了調整影象大小的演算法
    resized = tf.image.resize_images(img_data, [300, 300], method=0)
    print(resized.get_shape())  # 影象深度沒有顯式指定則為問號
    show(resized)

還可以通過 resize_image_with_crop_or_pad 函式對影象進行裁剪或填充:

    # 用resize_image_with_crop_or_pad調整影象大小
    # 第一個引數為原始影象
    # 第二個和第三個引數是調整後的影象大小,大於原圖則填充,小於則裁剪居中部分
    croped = tf.image.resize_image_with_crop_or_pad(img_data, 200, 200)
    show(croped)
    padded = tf.image.resize_image_with_crop_or_pad(img_data, 500, 600)
    show(padded)

還支援通過比例裁剪影象:

    # 用central_crop調整影象大小
    # 第一個引數是原始影象
    # 第二個引數為調整比例,是(0,1]的實數
    central_cropped = tf.image.central_crop(img_data, 0.5)
    show(central_cropped)

2.3 影象翻轉

以下程式碼示範了將影象進行上下翻轉、左右翻轉及沿對角線翻轉:

    # 影象翻轉
    flipped = tf.image.flip_up_down(img_data)  # 上下
    show(flipped)
    flipped = tf.image.flip_left_right(img_data)  # 左右
    show(flipped)
    transposed = tf.image.transpose_image(img_data)  # 對角線
    show(transposed)

還可以隨機翻轉影象:

    # 隨機翻轉影象
    flipped = tf.image.random_flip_up_down(img_data)  # 隨機上下
    show(flipped)
    flipped = tf.image.random_flip_left_right(img_data)  # 隨機左右
    show(flipped)

2.4 色彩調整

影象的色彩調整有四方面:

  • 亮度
  • 對比度
  • 飽和度
  • 色相

修改影象的亮度:

    # 調整影象的亮度
    adjusted = tf.image.adjust_brightness(img_data, 0.5)  # 將影象的亮度+0.5
    show(adjusted)
    adjusted = tf.image.random_brightness(
        img_data, max_delta=0.5)  # 在[-0.5,0.5]範圍內隨機調整影象亮度
    show(adjusted)

修改影象的對比度:

    # 調整影象的對比度
    adjusted = tf.image.adjust_contrast(img_data, -5)  # 將影象的對比度-5
    show(adjusted)
    adjusted = tf.image.adjust_contrast(img_data, 5)  # 將影象的對比度+5
    show(adjusted)
    adjusted = tf.image.random_contrast(img_data, lower=-5, upper=5)  # 隨機調整對比度

修改影象的飽和度:

    # 調整影象的飽和度
    adjusted = tf.image.adjust_saturation(img_data, -5)  # 將飽和度-5
    show(adjusted)
    adjusted = tf.image.adjust_saturation(img_data, 5)  # 將飽和度+5
    show(adjusted)
    adjusted = tf.image.random_saturation(image, lower=-5, uppper=5)  # 隨機調整飽和度

調整影象的色相:

    # 調整影象的色相
    adjusted = tf.image.adjust_hue(img_data, 0.5)  # 將色相+0.5
    show(adjusted)
    adjusted = tf.image.random_hue(img_data, max_delta=0.5)  # 隨機調整色相
    show(adjusted)

2.5 處理標註框

以下程式碼示範瞭如何在影象中加入標註框:

	# 用draw_bounding_boxes加入標註框
    # 要求影象矩陣型別為實數
    # 輸入是一個batch的資料,也就是多張影象,所以需要加一維
    batched = tf.expand_dims(img_data, 0)
    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)
    show(result)

還能通過 sample_distorted_bounding_box 函式來隨機擷取影象:

	# 用sample_distorted_bounding_box隨機擷取影象
    boxes = tf.constant([[[0.05, 0.05, 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(img_data, 0)
    image_with_box = tf.image.draw_bounding_boxes(batched, bbox_for_draw)
    distorted_image = tf.slice(img_data, begin, size)
    show(distorted_image)

3. 影象預處理示例

img_pre.py 這個示例給出瞭如何在程式中對影象進行預處理,從而降低不相關因素對訓練模型的影響:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt


# 通過調整亮度、對比度、飽和度、色相的順序隨機調整影象的色彩
def distort_color(image, color_ordering=0):
    if color_ordering == 0:
        image = tf.image.random_brightness(image, max_delta=32 / 255.0)
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
        image = tf.image.random_hue(image, max_delta=0.2)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
    elif color_ordering == 1:
        image = tf.image.random_brightness(image, max_delta=32 / 255.0)
        image = tf.image.random_hue(image, max_delta=0.2)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
    elif color_ordering == 2:
        # 一共可以有24種排列情況
        pass
    return tf.clip_by_value(image, 0.0, 1.0)


# 對影象進行預處理
def preprocess_for_train(image, height, width, bbox):
    # 預設整個影象是需要關注的部分
    if bbox is None:
        bbox = tf.constant(
            [0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])

    # 轉換影象張量的型別
    if image.dtype != tf.float32:
        image = tf.image.convert_image_dtype(image, dtype=tf.float32)

    # 隨機擷取影象,減少需要關注的物體大小對影象識別演算法的影響
    bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(
        tf.shape(image), bounding_boxes=bbox, min_object_covered=0.1)
    distorted_image = tf.slice(image, bbox_begin, bbox_size)

    # 將隨機擷取的影象調整為輸入層的大小
    distorted_image = tf.image.resize_images(
        distorted_image, size=[height, width], method=np.random.randint(4))

    # 隨機左右翻轉影象
    distorted_image = tf.image.random_flip_left_right(distorted_image)

    # 使用一種隨機順序調整影象色彩
    distorted_image = distort_color(distorted_image, np.random.randint(2))
    return distorted_image


image_raw_data = tf.gfile.FastGFile('images/1.jpg', 'rb').read()
with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(image_raw_data)
    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
    for i in range(6):
        result = preprocess_for_train(img_data, 300, 300, boxes)
        plt.imshow(result.eval())
        plt.show()

原書中的函式版本有些落後,有些函式會報錯:

  1. tf.image.sample_distorted_bounding_box()

    # 舊版本
    bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox)
    
    # 新版本
    bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox,min_object_covered=0.1)
    

    如果不顯式給 min_object_covered 引數就會報錯:

    ValueError: Tried to convert ‘min_object_covered’ to a tensor and failed. Error: None values not supported. 
    
  2. tf.image.resize_images()

    # 舊版本
    distorted_image=tf.image.resize_images(distorted_image,height,width,method=method)
    
    # 新版本
    distorted_image = tf.image.resize_images(distorted_image, size=[height, width], method=method)
    

    如果不將 size 寫為 size=[height,width] 的形式就會報錯:

    TypeError: resize_images() got multiple values for argument ‘method’
    

相關推薦

專欄 - 資料分析python、SQL

資料分析(python、SQL) 隨著大資料時代的到來,各行各業有大量的資料分析需求。python是一門“新世界”的主流語言,有很強大的第三方庫(Pandas,Numpy,Matplotlib)。本欄主要基於python語言,整理

TensorFlow資料處理影象處理

專案已上傳至 GitHub —— img-pre 1. 目錄結構 images/ 資料夾下存放將被用於處理的影象,img_all.py 示範了 TensorFlow 中影象處理函式的使用方法,img_pre.py 給出了一個對影象進行預處理的程式示例: im

Tensorflow資料及模型的儲存和恢復

如果你是一個深度學習的初學者,那麼我相信你應該會跟著教材或者視訊敲上那麼一遍程式碼,搭建最簡單的神經網路去完成針對 MNIST 資料庫的數字識別任務。通常,隨意構建 3 層神經網路就可以很快地完成任務,得到比較高的準確率。這時候,你信心大增,準備挑戰更難的任務。

洛谷 P2634 BZOJ 2152 模板點分治聰聰可可

sum oid 遍歷 重復 代碼 接下來 個數 石頭 col 題目描述 聰聰和可可是兄弟倆,他們倆經常為了一些瑣事打起來,例如家中只剩下最後一根冰棍而兩人都想吃、兩個人都想玩兒電腦(可是他們家只有一臺電腦)……遇到這種問題,一般情況下石頭剪刀布

JMeter學習二十九使用Jmeter創建ActiveMQ JMS POINT TO POINT請求,環境搭建、請求創建、插件安裝、監聽服務器資源等

分布式 jndi 根目錄 point 啟動 lib .cn 轉載 p2p 最近要做公司消息中間件的性能測試,第一個想到的工具就是Jmeter了,網上簡單搜了一下,基本上都是WEB測試的居多,只好自己研究官方文檔了。 其中涉及Jmeter基本的術語或者概念,請自行參考官方文檔

JMeter學習二十七Jmeter常見問題

pre 麻煩 continue 而不是 行為 let 方式 prop 右上角 收集工作中JMeter遇到的各種問題 1. JMeter的工作原理是什麽?   向服務器提交請求;從服務器取回請求返回的結果。 2. JMeter的作用?   JMeter可以用於測試

JMeter學習二十八內存溢出解決方法

不能 -xms 百度 解決 code apache 超過 軟件測試 內存 使用jmeter進行壓力測試時遇到一段時間後報內存溢出outfmenmory錯誤,導致jmeter卡死了,先嘗試在jmeter.bat中增加了JVM_ARGS="-Xmx2048m -Xms2048m

JMeter學習二十五HTTP屬性管理器HTTP Cookie Manager、HTTP Request Defaults

agen 讀取 expired fault 範圍 運行時 ear 定制 只有一個 Test Plan的配置元件中有一些和HTTP屬性相關的元件:HTTP Cache Manager、HTTP Authorization Manager、HTTP Cookie Manager

BZOJ3669Noi2014魔法森林Link-Cut Tree

沒有 力量 表示 cto ota code 描述 queue str 【BZOJ3669】【Noi2014】魔法森林(Link-Cut Tree) 題面 題目描述 為了得到書法大家的真傳,小 E 同學下定決心去拜訪住在魔法森林中的隱 士。魔法森林可以被看成一個包含 n 個節

BZOJ2816ZJOI2012網絡Link-Cut Tree

max 三種 ++i error 如果 描述 信息 logs fat 【BZOJ2816】【ZJOI2012】網絡(Link-Cut Tree) 題面 題目描述 有一個無向圖G,每個點有個權值,每條邊有一個顏色。這個無向圖滿足以下兩個條件: 對於任意節點連出去的邊中,相同顏

Poj1273Drainage Ditches網絡流

ace ring tmp scanf down std ems mar scan Description 給圖,求最大流 最大流模板題,這裏用dinic Code #include <cstdio> #include <cstring> #inclu

BZOJ4530大融合Link-Cut Tree

數據 ota mes read names 編號 ble pla str 【BZOJ4530】大融合(Link-Cut Tree) 題面 討厭權限題!!! Loj鏈接 題目描述 小強要在 N個孤立的星球上建立起一套通信系統。這套通信系統就是連接 N個點的一個樹。這個樹的邊是

BZOJ3998弦論後綴自動機

span return last log map div com inline main 【BZOJ3998】弦論(後綴自動機) 題面 BZOJ 題解 這題應該很簡單 構建出\(SAM\)後 求出每個點往後還能構建出幾個串 按照拓撲序\(dp\)一些就好了 然後就是第\(k

CF235CCyclical Quest後綴自動機

ems long long cli 出現 cpp 數組 getchar blog 及其 【CF235C】Cyclical Quest(後綴自動機) 題面 洛谷 題解 大致翻譯: 給定一個串 然後若幹組詢問 每次也給定一個串 這個串可以旋轉(就是把最後一位丟到最前面這樣子)

Bzoj3894文理分科最小割

描述 擁有 pri const getch bzoj3 solution efi ini Description ?文理分科是一件很糾結的事情!(雖然看到這個題目的人肯定都沒有糾結過) ?小P所在的班級要進行文理分科。他的班級可以用一個n*m的矩陣進行描述,每個格子代表一個

Hdu4825Xor Sum01字典樹

insert else 結果 char clu 向人 logs mark 每次 Description Zeus 和 Prometheus 做了一個遊戲,Prometheus 給 Zeus 一個集合,集合中包含了N個正整數,隨後 Prometheus 將向 Zeus 發起M

Bzoj2286消耗戰虛樹+DP

swap mem cpp php down oid info LV algo Description 題目鏈接 Solution 在虛樹上跑DP即可 Code #include <cstdio> #include <algorithm> #inclu

NOI2001 炮兵陣地 狀壓dp

ron 很多 == 處理 gist i++ ostream push 計算 傳送門 Luogu 題目描述 司令部的將軍們打算在NM的網格地圖上部署他們的炮兵部隊。一個NM的地圖由N行M列組成,地圖的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下圖。在

模板求星期已知年月日

color 模板 div lse urn -- return pan bsp int getweek(int y,int m,int d) { int x; if(m==1||m==2) m+=12,y--; if(y<175

BZOJ2006超級鋼琴RMQ,priority_queue

else cto parse main 元組 log 最大的 問題 mes 題意: 思路: 用三元組(i, l, r)表示右端點為i,左端點在[l, r]之間和最大的區間([l, r]保證是對於i可行右端點區間的一個子區間),我們用堆維護一些這樣的三元組。 堆中初始的元素