Spaces:
Sleeping
Sleeping
File size: 6,887 Bytes
fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb be1d691 fba74bb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
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() |