由於 Gradio 輸出入元件很多, 因此將其分成基礎與進階兩類以免篇幅過長, 本篇繼續來測試進階的 Gradio 元件. 本系列之前的文章參考 :
八. 進階輸出入元件測試 :
進階的 Gradio 元件主要包含多媒體的圖片 (Image), 音訊 (Audio), 視訊 (Video), 與資料框 (DataFrame) 等, 這些在機器學習/深度學習應用中很常用.
1. Image 元件 :
Image 元件為輸出入兩用, 當作輸入元件時可用來上傳圖片或透過 Webcam 拍照; 當作輸出元件時則可用來顯示圖片, 其參數如下 :
- label: 設定元件的標籤文字 (預設值 None)
- value: 設定圖片的初始值, 可以是圖片檔路徑, URL 或 PIL Image 物件 (預設值 None)
- tool: 設定工具類型,"editor"=編輯工具, "sketch"=繪圖板, None=拖曳上傳 (預設)
- type: 傳回的資料類型, 值 'numpy' (預設值) 或 'pil' 或 'filepath'
- sources: 圖片輸入來源串列, 預設 ['upload', 'webcam', 'clipboard']
- width: 指定圖片寬度 (px)
- height: 指定圖片高度 (px)
- image_mode: 指定圖片的顏色模式, 彩色 "RGB" (預設) 或灰階 "L"
注意, Image 當輸入元件時預設會傳出一個形狀為 (height, width, 3) 的 NumPy 陣列給 fn 所指定的處理函式, 如果在該函式中要使用 PIL(Pirrow) 套件處理圖像, 可將 type 設為 'pil', 這樣 Image 就會傳送 PIL 的 Image 物件給處理函式.
測試程式碼如下 :
import gradio as gr
def handler(in1):
msg=f'尺寸:(width, height)={in1.size}'
return msg, in1
in1=gr.Image(label='上傳圖像', type='pil')
out1=gr.Textbox(label='輸出')
out2=gr.Image(label='圖像輸出')
iface=gr.Interface(
fn=handler,
inputs=[in1],
outputs=[out1, out2],
title='Image 元件測試',
allow_flagging='never',
)
iface.launch()
此例設置了一個 Image 圖像輸入元件 in1, 一個用來顯示圖像尺寸資訊的 Textbox 輸出框 out1, 以及一個用來輸出上傳圖像的 Image 圖像輸出元件 out2. 其中 in1 要指定 type 參數為 'pil'. 此 Image 輸入元件可上傳圖檔或使用 Webcam 拍照, 按 Submit 後呼叫 handler(), Gradio 會將圖片轉成 PIL (Pirrow) 的 Image 物件傳給 handler() 的輸入參數 in1, handler() 會取出圖像的尺寸資訊輸出到 out1 輸出框, 同時將圖像輸出到 Image 輸出元件 out2.
可見若沒有傳入 sources 參數, Image 元件底下會出現三種輸入方式的小按鈕讓使用者點選輸入方式, 因為 sources 的預設值是 ['upload', 'webcam', 'clipboard'], 只要 sources 元素至少有兩個就會出現底下的小按鈕, 如果只傳入一個元素例如 sources=[''upload'] 底下就不會出現小按鈕.
預設是 upload 模式, 如果手邊沒有圖檔可到 Wiki 下載 Lena 的圖片 (jpg) 來測試 :
結果如下 :
此例程式碼放在 Hugging Face Space :
下面範例改寫自官網教學文件, 利用 Numpy 對 Image 輸入上傳之圖像做濾鏡處理後輸出到另一個 Image 元件, 參考 :
程式碼改寫如下 :
import gradio as gr
import numpy as np
def handler(in1):
sepia_filter=np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
img=in1.dot(sepia_filter.T)
img /= img.max()
return img
in1=gr.Image(label='上傳圖像')
out1=gr.Image(label='圖像輸出')
iface=gr.Interface(
fn=handler,
inputs=[in1],
outputs=[out1],
title='Image 元件測試',
allow_flagging='never',
)
iface.launch()
此例設置了一個 Image 圖像輸入元件 in1, 以及一個用來輸出經濾鏡處理過的圖像的 Image 輸出元件 out1. 其中 in1 未指定 type 參數預設為 'numpy', 因此它會將輸入之圖像以 Numpy 陣列格式傳送給處理函式 handler().
在處理函式 handler() 中定義了一個可將傳入之圖像色彩轉換為棕褐色調的濾鏡陣列 sepia_filter, 其中每一欄代表 R, G, B 三通道的加權值, 此濾鏡需先轉置再與輸入圖像做點積, 然後除以做大值進行歸一化讓輸出值介於 0~1 之間, 以避免數值過大.
輸出的濾鏡效果如下 :
此例程式碼放在 Hugging Face Space :
2. Audio 元件 :
Audio 元件是輸出入兩用元件, 當輸入用時可用來拖曳或上傳音訊檔, 也可以錄音輸入音訊; 當音訊上傳或錄音完成, 又搖身一變成為可播放該音訊的輸出元件, 其可用參數如下 :
- label: 元件標籤 (預設值 None)
- value: 本機的圖片路徑檔名或網路圖檔的 URL (預設值 None)
- sources: 音訊輸入來源串列 (預設值 ['upload', 'microhone'])
- type: 傳送給處理函式的資料型態, 預設值為 'numpy', 一般上傳或錄音要設為 'filepath'
Audio 元件可以上傳的檔案格式有 : mp3, wav, ogg, 與 flag.
測試程式碼如下 :
import gradio as gr
def handler(in1):
msg=f'輸入的類型: {type(in1)}\n{in1}'
return msg
in1=gr.Audio(label='音訊輸入', type='filepath') # 一般應用需設為 filepath
out1=gr.Textbox(label='輸出資訊')
iface=gr.Interface(
fn=handler,
inputs=[in1],
outputs=out1,
title='Audio 元件測試',
flagging_mode='never',
)
iface.launch()
此例設置了一個 Audio 音訊輸入元件 in1, 以及一個用來顯示資訊的 Textbox 輸出元件 out1. 其中 in1 若未指定 type 參數預設為 'numpy', 此預設值會讓 Audio 元件傳送音訊的原始 Numpy 陣列行給 fn 所指定的處理函式, 適合需要對音訊進行分析或處理的應用場合 (例如濾波, 頻譜分析, 提取聲學特徵等), 一般應用須設為 'filepath', Audio 元件會直接傳送上傳或錄製的音訊檔位置 (字串) 給處理函式, 此處 handler() 會將收到的音訊檔資訊型態與路徑輸出到 Textbox 元件顯示 :
下面是上傳一個 mp3 檔的結果, Audio 元件上會顯示 Play 播放按鈕可輸出音訊內容, 按 Submit 鈕會顯示此音訊檔檔名路徑等資訊 :
按 Audio 底下右邊的小按鈕選擇麥克風為音訊輸入來源, 第一次使用會跳出是否授權網頁使用麥克風錄音的視窗 :
按 "允許" 後 Audio 元件上就會出現 Record 錄音按鈕, 按下即開始錄音 :
錄音中可以按暫停, 錄完就按停止鍵 :
按 Submit 鍵可知錄音會固定存成 audio.wav 檔 :
此例程式碼放在 Hugging Face Space :
下面是用預設的 type='numpy' 讓 Audio 元件傳出 Numpy 陣列的範例 :
import gradio as gr
import numpy as np
def handler(in1):
if in1 is None:
msg='請先上傳或錄音!'
try:
sample_rate, audio_data=in1
duration=len(audio_data)/sample_rate # 計算音訊長度(秒)
avg_amplitude=np.mean(np.abs(audio_data)) # 計算音訊平均振幅
msg=(f'音訊類型: {type(in1)}\n'
f'音訊資料: {in1}\n'
f'取樣率: {sample_rate}\n'
f'時長: {duration:.2f} 秒\n'
f'平均振幅: {avg_amplitude:.4f}'
)
except Exception as e:
msg=f'處理音訊時發生錯誤:{e}'
return msg
in1=gr.Audio(label='音訊輸入') # 預設 type='numpy'
out1=gr.Textbox(label='輸出資訊')
iface=gr.Interface(
fn=handler,
inputs=[in1],
outputs=out1,
title='Audio 元件測試',
flagging_mode='never',
)
iface.launch()
此例與上例差別在於 Audio 元件沒有傳入 type 參數, 因此使用預設值 'numpy', 由於上傳 mp3 檔案需要安裝 ffmpeg 等套件, 但上傳 wav 檔則不用, 故此例使用麥克風錄音, 錄好按 Submit 呼叫 handler() 函式, 傳入參數是由一個整數取樣率與一個 Numpy 陣列組成之 tuple, 解構後用它們來計算音訊時長與平均振幅後輸出資訊到 TextBox 元件, 結果如下 :
此例程式碼放在 Hugging Face Space :
3. Video 元件 :
與 Audio 元件一樣, Video 元件也是輸入輸出兩用元件, 使用者可以利用拖曳/上傳視訊檔或使用 Webcam 錄製影片來輸入視訊, 輸入完成後 Video 元件上會出現 Play 按鈕可播放所輸入之視訊.
常用參數如下 :
- label: 元件標籤 (預設值 None)
- value: 設定預設之視訊內容, 可以是本機的路徑檔名或網路視訊檔的 URL (預設 None)
- format: 設定傳送到處理函式之視訊格式, 'avi' 或 'mp4' (預設值)
- width: 設定播放器之寬度 (px), 預設 None=視訊寬度
- height: 設定播放器之高度 (px), 預設 None=視訊高度
Video 可以上傳的視訊檔案類型有 mp4, webm, 與 ogg 三種. 注意, 新版 Gradio 已經不能指定 Video 元件的 sources 參數, 固定為上傳與攝影兩種輸入模式, 測試程式碼如下 :
import gradio as gr
def handler(in1):
msg=f'輸入的類型: {type(in1)}\n{in1}'
return msg
in1=gr.Video(label='視訊輸入', width=352, height=240)
out1=gr.Textbox(label='輸出資訊')
iface=gr.Interface(
fn=handler,
inputs=[in1],
outputs=out1,
title='Video 元件測試',
flagging_mode='never',
)
iface.launch()
此例設置了一個 Video 音訊輸入元件 in1, 以及一個用來顯示資訊的 Textbox 輸出元件 out1. Video 元件預設是上傳模式, 可以拖曳/上傳 mp4, webm, 或 ogg 視訊檔 :
上傳視訊檔後會出現播放鈕, Video 元件搖身一變成為輸出元件可播放所上傳之視訊檔 :
按 Submit 鈕顯示鎖上傳之視訊檔訊息 :
如果用 Webcam 錄影的話預設會儲存為 sample.webm 視訊檔 :
此例程式碼放在 Hugging Face Space :
4. Gallery 元件 :
Gallery 元件是圖片輸出元件, 顧名思義就是用來呈現眾多圖片的畫廊, 常用參數如下 :
- label: 元件標籤 (預設值 None)
- columns: 畫廊的欄 (行) 數 (預設值 2)
- rows: 畫廊的列數 (預設值 None=不設限)
- scale: 圖片縮放比例 (整數, 預設值 1)
經測試 scale 參數並無作用. 測試程式如下 :
import gradio as gr
import os
def handler(dir):
imgs=[os.path.join(dir, name) for name in sorted(os.listdir(dir)) if name.endswith(('.jpg', '.png', '.jpeg'))]
return imgs
in1=gr.Textbox(label='路徑', value='.')
out1=gr.Gallery(label='圖片集')
iface=gr.Interface(
fn=handler,
inputs=in1,
outputs=out1,
title='Gallery 元件測試',
flagging_mode='never',
)
iface.launch()
此例設置了一個 Textbox 元件用來輸入資料夾路徑, 以及一個 Gallery 元件用來顯示資料夾下的 png 或 jpg 圖檔. 處理函式 handler() 利用 os.listdir() 找出資料夾下的所有檔案與目錄, 經排序後檢查是否名稱以 .jpg, .png, 或 ,.jpeg 結尾, 是的話就將其名稱前面串接指定之資料夾後放入串列中傳回給 Gallery 元件輸出, 結果如下 :
可見 Gallery 預設會以兩欄來顯示圖片. 如果用 columns 設為 4 欄 :
out1=gr.Gallery(label='圖片集', columns=4)
結果如下 :
此範例修改自下列文章 :
沒有留言:
張貼留言