Spaces:
Sleeping
Sleeping
| 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() |