Camera / app.py
petertulip86's picture
Update app.py
be1d691 verified
import cv2
import numpy as np
import gradio as gr
def hsv_filter(image, h_low=0, h_high=179, s_low=0, s_high=255, v_low=0, v_high=255):
"""
對輸入的圖像應用 HSV 過濾
Args:
image: 輸入的圖像(來自上傳)
h_low, h_high: Hue(色調)的最低和最高值
s_low, s_high: Saturation(飽和度)的最低和最高值
v_low, v_high: Value(亮度)的最低和最高值
Returns:
原始圖像、HSV 過濾遮罩和過濾後的結果
"""
if image is None:
# 如果沒有圖像,返回None
return None, None, None
# 將圖像轉換為BGR(如果它是RGB)
if len(image.shape) == 3 and image.shape[2] == 3:
# Gradio 使用 RGB,但 OpenCV 使用 BGR
image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
else:
image_bgr = image
# 將圖像轉換為 HSV 色彩空間
hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
# 設置 HSV 過濾範圍
lower = np.array([h_low, s_low, v_low])
upper = np.array([h_high, s_high, v_high])
# 建立遮罩
mask = cv2.inRange(hsv, lower, upper)
# 使用遮罩從原始圖像中提取物體
result = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)
# 將結果轉換回 RGB 以在 Gradio 中顯示
result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
# 將遮罩轉換為 RGB 以便在 Gradio 中顯示
mask_rgb = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
# 確保原始圖像也是 RGB
orig_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
return orig_rgb, mask_rgb, result_rgb
def create_test_image():
"""
創建一個測試圖像,包含不同顏色區塊,用於演示 HSV 過濾效果
"""
# 創建一個白色背景
test_image = np.ones((300, 400, 3), dtype=np.uint8) * 255
# 添加不同顏色的區塊(BGR 格式)
# 紅色區塊
test_image[50:150, 50:150] = [0, 0, 255] # BGR格式的紅色
# 綠色區塊
test_image[50:150, 200:300] = [0, 255, 0] # BGR格式的綠色
# 藍色區塊
test_image[200:250, 50:350] = [255, 0, 0] # BGR格式的藍色
# 黃色區塊
test_image[150:200, 150:200] = [0, 255, 255] # BGR格式的黃色
# 將BGR轉換為RGB格式
test_image_rgb = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB)
return test_image_rgb
def process_image(image, h_low, h_high, s_low, s_high, v_low, v_high):
"""
處理圖像的主函數
"""
if image is None:
# 如果沒有上傳圖像,使用測試圖像
image = create_test_image()
return hsv_filter(image, h_low, h_high, s_low, s_high, v_low, v_high)
# 創建 Gradio 界面
with gr.Blocks(title="HSV 顏色過濾器") as demo:
gr.Markdown("# HSV 顏色過濾器")
gr.Markdown("上傳圖像或使用測試圖像,然後調整 HSV 值範圍進行顏色過濾")
with gr.Row():
# 圖像輸入區域
with gr.Column(scale=1):
gr.Markdown("### 輸入圖像")
input_image = gr.Image(type="numpy", label="上傳圖像")
test_btn = gr.Button("使用測試圖像")
# HSV 滑桿控制區域
with gr.Column(scale=1):
gr.Markdown("### HSV 參數控制")
with gr.Row():
with gr.Column():
h_low = gr.Slider(0, 179, 0, step=1, label="H Low(色調最小值)")
h_high = gr.Slider(0, 179, 179, step=1, label="H High(色調最大值)")
with gr.Column():
s_low = gr.Slider(0, 255, 0, step=1, label="S Low(飽和度最小值)")
s_high = gr.Slider(0, 255, 255, step=1, label="S High(飽和度最大值)")
with gr.Column():
v_low = gr.Slider(0, 255, 0, step=1, label="V Low(亮度最小值)")
v_high = gr.Slider(0, 255, 255, step=1, label="V High(亮度最大值)")
# 創建一些預設值按鈕
gr.Markdown("### 常用顏色預設")
with gr.Row():
red_btn = gr.Button("紅色")
green_btn = gr.Button("綠色")
blue_btn = gr.Button("藍色")
yellow_btn = gr.Button("黃色")
# 結果顯示區域
with gr.Row():
original_output = gr.Image(type="numpy", label="原始圖像")
mask_output = gr.Image(type="numpy", label="遮罩")
result_output = gr.Image(type="numpy", label="過濾結果")
# 設置事件處理
# 測試圖像按鈕
test_btn.click(
fn=lambda: create_test_image(),
inputs=[],
outputs=[input_image]
)
# 處理圖像函數
def process_and_update(*args):
return process_image(*args)
# 連接輸入和滑桿到處理函數
inputs = [input_image, h_low, h_high, s_low, s_high, v_low, v_high]
outputs = [original_output, mask_output, result_output]
# 當圖像或任何滑桿變化時觸發處理函數
input_image.change(process_and_update, inputs=inputs, outputs=outputs)
for slider in [h_low, h_high, s_low, s_high, v_low, v_high]:
slider.change(process_and_update, inputs=inputs, outputs=outputs)
# 預設值按鈕
# 紅色 (Hue: ~0-10 或 ~160-179)
red_btn.click(
fn=lambda: [None, 0, 10, 100, 255, 100, 255],
inputs=[],
outputs=[input_image, h_low, h_high, s_low, s_high, v_low, v_high]
).then(
fn=process_and_update,
inputs=inputs,
outputs=outputs
)
# 綠色 (Hue: ~35-85)
green_btn.click(
fn=lambda: [None, 35, 85, 100, 255, 100, 255],
inputs=[],
outputs=[input_image, h_low, h_high, s_low, s_high, v_low, v_high]
).then(
fn=process_and_update,
inputs=inputs,
outputs=outputs
)
# 藍色 (Hue: ~90-130)
blue_btn.click(
fn=lambda: [None, 90, 130, 100, 255, 100, 255],
inputs=[],
outputs=[input_image, h_low, h_high, s_low, s_high, v_low, v_high]
).then(
fn=process_and_update,
inputs=inputs,
outputs=outputs
)
# 黃色 (Hue: ~20-35)
yellow_btn.click(
fn=lambda: [None, 20, 35, 100, 255, 100, 255],
inputs=[],
outputs=[input_image, h_low, h_high, s_low, s_high, v_low, v_high]
).then(
fn=process_and_update,
inputs=inputs,
outputs=outputs
)
# 初始加載時自動生成測試圖像
demo.load(
fn=lambda: [create_test_image()],
inputs=None,
outputs=[input_image]
).then(
fn=process_and_update,
inputs=inputs,
outputs=outputs
)
# 啟動 Gradio 應用
if __name__ == "__main__":
demo.launch()