學習筆記TF015:載入圖像、圖像格式、圖像操作、顏色

来源:http://www.cnblogs.com/libinggen/archive/2017/05/28/6914962.html
-Advertisement-
Play Games

TensorFlow支持JPG、PNG圖像格式,RGB、RGBA顏色空間。圖像用與圖像尺寸相同(height*width*chnanel)張量表示。通道表示為包含每個通道顏色數量標量秩1張量。圖像所有像素存在磁碟文件,需要被載入到記憶體。 圖像載入與二進位文件相同。圖像需要解碼。輸入生成器(tf.tr ...


TensorFlow支持JPG、PNG圖像格式,RGB、RGBA顏色空間。圖像用與圖像尺寸相同(height*width*chnanel)張量表示。通道表示為包含每個通道顏色數量標量秩1張量。圖像所有像素存在磁碟文件,需要被載入到記憶體。

圖像載入與二進位文件相同。圖像需要解碼。輸入生成器(tf.train.string_input_producer)找到所需文件,載入到隊列。tf.WholeFileReader載入完整圖像文件到記憶體,WholeFileReader.read讀取圖像,tf.image.decode_jpeg解碼JPEG格式圖像。圖像是三階張量。RGB值是一階張量。載入圖像格式為[batch_size,image_height,image_width,channels]。批數據圖像過大過多,占用記憶體過高,系統會停止響應。

大尺寸圖像輸入占用大量系統記憶體。訓練CNN需要大量時間,載入大文件增加更多訓練時間,也難存放多數系統GPU顯存。大尺寸圖像大量無關本征屬性信息,影響模型泛化能力。

tf.image.decode_jpeg解碼JPEG格式圖像。tf.image.decode_png解碼PNG格式圖像。 差別在alpha(透明度)信息。移除區域alpha值設0,有助於標識。JPEG圖像頻繁操作會留下偽影(atrifact)。PNG格式無損壓縮,保留原始文件全部信息(被縮放或降採樣除外),文件體積較大。

TensorFlow內置文件格式TFRecord,二進位數據和訓練類別標簽數據存儲在同一文件。模型訓練前圖像轉換為TFRecord格式。TFRecord文件是protobuf格式。數據不壓縮,可快速載入到記憶體。

獨熱編碼(one-hot encoding)格式,表示多類分類(單)標簽數據。圖像載入到記憶體,轉換為位元組數組,添加到tf.train.Example文件,SerializeToString 序列化為二進位字元,保存到磁碟。序列化將記憶體對象轉換為可安全傳輸文件格式,可被載入,可被反序列化為樣本格式。直接載入TFRecord文件,可以節省訓練時間。支持寫入多個樣本。

TFRecordReader對象讀取TFRecord文件。tf.parse_single_example不解碼圖像,解析TFRecord,圖像按原始位元組讀取(tf.decode-raw)。tf.reshape調整形狀,使佈局符合tf.nn.conv2d要求([image_height,image_width,image_channels])。tf.expand擴展維數,把batch_size維添加到input_batch。tf.equal檢查是否載入同一圖像。sess.run(tf.cast(tf_record_features['label'], tf.string))查看從TFRecord文件載入的標簽。使用圖像數據推薦使用TFRecord文件存儲數據與標簽。做好圖像預處理並保存結果。

最好在預處理階段完成圖像操作,裁剪、縮放、灰度調整等。圖像載入後,翻轉、扭曲,使輸入網路訓練信息多樣化,緩解過擬合。Python圖像處理框架PIL、OpenCV。TensorFlow提供部分圖像處理方法。裁剪,tf.image.central_crop,移除圖像區域,完全丟棄其中信息,與tf.slice(移除張量分量)類似,基於圖像中心返回結果。訓練時,如果背景有用,tf.image.crop_to_bounding_box(只接收確定形狀張量,輸入圖像需要事先在數據流圖運行) 隨機裁剪區域起始位置到圖像中心的偏移量。

tf.image.pad_to_bounding_box 用0填充邊界,使輸入圖像符合期望尺寸。尺寸過大過小圖像,邊界填充灰度值0像素。tf.image.resize_image_with_crop_or_pad,相對圖像中心,裁剪或填充同時進行。

翻轉,每個像素位置沿水平或垂真方向翻轉。隨機翻轉圖像,可以防止過擬合。tf.slice選擇圖像數據子集。tf.image.flip_left_right 完成水平翻轉。tf.image.flip_up_down 完成垂直翻轉。seed參數控制翻轉隨機性。

編輯過圖像訓練,誤導CNN模型。屬性隨機修改,使CNN精確匹配編輯過或不同光照圖像特征。tf.image.adjust_brightness 調整灰度。tf.image.adjust_contrast 調整對比度。調整對比度,選擇較小增量,避免“過曝”,達到最大值無法恢復,可能全白全黑。tf.slice 突出改變像素。tf.image.adjust_hue 調整色度,色彩更豐富。delta參數控制色度數量。tf.image.adjust_saturation 調整飽和度,突出顏色變化。

單一顏色圖像,灰度顏色空間,單顏色通道,只需要單個分量秩1張量。縮減顏色空間可以加速訓練。灰度圖具有單個分量,取值範圍[0,255]。tf.image.rgb_to_grayscale 把RGB圖像轉換為灰度圖。灰度變換,每個像素所有顏色值取平均。tf.image.rgb_to_hsv RGB圖像轉換為HSV, 色度、飽和度、灰度構成HSV顏色空間,3個分量秩1張量。更貼近人類感知屬性。HSB,B亮度值。tf.image.hsv_to_rgb HSV圖像轉換為RGB,tf.image.grayscale_to_rgb 灰度圖像轉換為RGB。python-colormath提供LAB顏色空間,顏色差異映射貼近人類感知,兩個顏色歐氏距離反映人類感受的顏色差異。

tf.image.convert_image_dtype(image, dtype,saturate=False) 圖像數據類型變化,像素值比例變化。

 

    import tensorflow as tf
    sess = tf.Session()
    red = tf.constant([255, 0, 0])
    file_names = ['./images/chapter-05-object-recognition-and-classification/working-with-images/test-input-image.jpg']
    filename_queue = tf.train.string_input_producer(file_names)
    image_reader = tf.WholeFileReader()
    _, image_file = image_reader.read(filename_queue)
    image = tf.image.decode_jpeg(image_file)
    sess.run(tf.global_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess,coord=coord)
    print sess.run(image)
    filename_queue.close(cancel_pending_enqueues=True)
    coord.request_stop()
    coord.join(threads)
    print "------------------------------------------------------"
    image_label = b'\x01'
    image_loaded = sess.run(image)
    image_bytes = image_loaded.tobytes()
    image_height, image_width, image_channels = image_loaded.shape
    writer = tf.python_io.TFRecordWriter("./output/training-image.tfrecord")
    example = tf.train.Example(features=tf.train.Features(feature={
            'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_label])),
            'image': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes]))
        }))
    print example
    writer.write(example.SerializeToString())
    writer.close()
    print "------------------------------------------------------"
    tf_record_filename_queue = tf.train.string_input_producer(["./output/training-image.tfrecord"])
    tf_record_reader = tf.TFRecordReader()
    _, tf_record_serialized = tf_record_reader.read(tf_record_filename_queue)
    tf_record_features = tf.parse_single_example(
    tf_record_serialized,
    features={
        'label': tf.FixedLenFeature([], tf.string),
        'image': tf.FixedLenFeature([], tf.string),
        })
    tf_record_image = tf.decode_raw(
        tf_record_features['image'], tf.uint8)
    tf_record_image = tf.reshape(
        tf_record_image,
        [image_height, image_width, image_channels])
    print tf_record_image
    tf_record_label = tf.cast(tf_record_features['label'], tf.string)
    print tf_record_label
    print "------------------------------------------------------"
    sess.close()
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess,coord=coord)
    print sess.run(tf.equal(image, tf_record_image))
    sess.run(tf_record_label)
    coord.request_stop()
    coord.join(threads)
    print "------------------------------------------------------"
    print sess.run(tf.image.central_crop(image, 0.1))
    real_image = sess.run(image)
    bounding_crop = tf.image.crop_to_bounding_box(
        real_image, offset_height=0, offset_width=0, target_height=2, target_width=1)
    print sess.run(bounding_crop)
    print "------------------------------------------------------"
    real_image = sess.run(image)
    pad = tf.image.pad_to_bounding_box(
        real_image, offset_height=0, offset_width=0, target_height=4, target_width=4)
    print sess.run(pad)
    print "------------------------------------------------------"
    crop_or_pad = tf.image.resize_image_with_crop_or_pad(
        real_image, target_height=2, target_width=5)
    print sess.run(crop_or_pad)
    print "------------------------------------------------------"
    sess.close()
    sess = tf.Session()
    top_left_pixels = tf.slice(image, [0, 0, 0], [2, 2, 3])
    flip_horizon = tf.image.flip_left_right(top_left_pixels)
    flip_vertical = tf.image.flip_up_down(flip_horizon)
    sess.run(tf.global_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess,coord=coord)
    print sess.run([top_left_pixels, flip_vertical])
    print "------------------------------------------------------"
    top_left_pixels = tf.slice(image, [0, 0, 0], [2, 2, 3])
    random_flip_horizon = tf.image.random_flip_left_right(top_left_pixels)
    random_flip_vertical = tf.image.random_flip_up_down(random_flip_horizon)
    print sess.run(random_flip_vertical)
    print "------------------------------------------------------"
    example_red_pixel = tf.constant([254., 2., 15.])
    adjust_brightness = tf.image.adjust_brightness(example_red_pixel, 0.2)
    print sess.run(adjust_brightness)
    print "------------------------------------------------------"
    adjust_contrast = tf.image.adjust_contrast(image, -.5)
    print sess.run(tf.slice(adjust_contrast, [1, 0, 0], [1, 3, 3]))
    print "------------------------------------------------------"
    adjust_hue = tf.image.adjust_hue(image, 0.7)
    print sess.run(tf.slice(adjust_hue, [1, 0, 0], [1, 3, 3]))
    print "------------------------------------------------------"
    adjust_saturation = tf.image.adjust_saturation(image, 0.4)
    print sess.run(tf.slice(adjust_saturation, [1, 0, 0], [1, 3, 3]))
    print "------------------------------------------------------"
    gray = tf.image.rgb_to_grayscale(image)
    print sess.run(tf.slice(gray, [0, 0, 0], [1, 3, 1]))
    print "------------------------------------------------------"
    hsv = tf.image.rgb_to_hsv(tf.image.convert_image_dtype(image, tf.float32))
    print sess.run(tf.slice(hsv, [0, 0, 0], [3, 3, 3]))
    print "------------------------------------------------------"
    rgb_hsv = tf.image.hsv_to_rgb(hsv)
    rgb_grayscale = tf.image.grayscale_to_rgb(gray)
    print rgb_hsv, rgb_grayscale
    print "------------------------------------------------------"

 


參考資料:
《面向機器智能的TensorFlow實踐》

歡迎加我微信交流:qingxingfengzi
我的微信公眾號:qingxingfengzigz
我老婆張幸清的微信公眾號:qingqingfeifangz


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先先瞭解一下ef生成的模型edmx的代碼,傳送門:http://www.cnblogs.com/yushengbo/p/4807715.html 一、添加新的欄位 例子就用我現在項目的這個吧,首先在edmx中的表裡新建一個欄位: 然後設置他的屬性什麼別的內容,之後在表格所示範圍內點擊右鍵,選擇在模 ...
  • 前言:對於經常忙於服務端開發的小伙伴來說,與DB層打交道是在正常不過的事了,但是每次頁面的查詢條件新增往往意味著後端代碼參數化同比增長,當然你可以不使用sqlhelper自帶的參數化條件查詢,可以直接傳遞參數,這樣一來,可能你寫的代碼就變少了,但是存在一個隱藏的問題就是sql註入,對於sql註入我想 ...
  • EntityFramework核心是EDM實體數據模型,該模型由三部分組成。 (1) 概念模型,由概念架構定義語言文件(.csdl)來定義. (2) 映射,由映射規範語言文件(.msl)定義. (3) 存儲模型,由存儲架構定義語言文件(.ssdl)來定義,亦稱邏輯模型. 上述概念比較抽象,歸根到本質 ...
  • 後臺模版來自:Ace Admin http://ace.jeka.by/form-elements.html 左側菜單,通過js根據url來判斷顯示哪塊 window.location.pathname: 代表URL 的路徑部分(就是文件地址) 本例返回值:/Company/AddOrEditCom ...
  • 特性參數 webapi 框架里有很多特性參數,為瞭解除一些新人的疑惑,寫個小例子分享下。 class Program { static void Main(string[] args) { var message = new MessageData { Header="header...", Bod ...
  • 類和對象 類是某一批對象的抽象,可以把類理解成某種概念。對象是一個具體存在的實體。類和對象是面向對象的核心。 類定義的是多個實例的特征,類不是具體存在,實例才是具體存在。 定義類(class)的語法: [修飾符] class 類名 { 零個到多個構造器定義.... 零個到多個成員變數.... 零個到 ...
  • 《lucene實戰(第2版)》基於apache的lucene3.0,從lucene核心、lucene應用、案例分析3個方面詳細系統地介紹了lucene,包括認識lucene、建立索引、為應用程式添加搜索功能、高級搜索技術、擴展搜索、使用tika提取文本、lucene的高級擴展、使用其他編程語言訪問l ...
  • 作為PythonWeb開發的微框架,Flask獨樹一幟。它不會強迫開發者遵循預置的開發規範,為開發者提供了自由度和創意空間。 《圖靈程式設計叢書·Flask Web開發:基於Python的Web應用開發實戰》作者擁有25年軟體開發經驗,而《圖靈程式設計叢書·Flask Web開發:基於Python的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...