import gradio as gr from PIL import Image import numpy as np import cv2 imageScale = 1 # 圖片縮小功能 def resize_image(img, scale): if img is None: return None global imageScale imageScale = scale # 縮小圖片後,要記得圖片已變化的形狀 width, height = img.size new_width = int(width * scale) new_height = int(height * scale) resized_img = img.resize((new_width, new_height)) return resized_img # Canny 邊緣偵測 def canny_edge1(img,min_val,max_val): if img is None: return None global imageScale img = resize_image(img, imageScale) img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) edges = cv2.Canny(img_gray, min_val, max_val) return Image.fromarray(edges) def canny_edge2(img,min_val,max_val): if img is None: return None global imageScale img = resize_image(img, imageScale) img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) edges = cv2.Canny(img_gray, min_val, max_val) edges_colored = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR) edges_colored[:, :, 1:] = 0 combined = cv2.addWeighted(img_cv, 0.8, edges_colored, 0.8, 0) return Image.fromarray(combined) def sobel_operators1(img): if img is None: return None global imageScale img = resize_image(img, imageScale) img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) kernel=np.array([ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]) SobelXImage=cv2.filter2D(src=img_gray,ddepth=-1,kernel=kernel) kernel=np.array([ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) SobelYImage=cv2.filter2D(src=img_gray,ddepth=-1,kernel=kernel) SobelImage=cv2.addWeighted(SobelXImage,1,SobelYImage,1,0) return Image.fromarray(SobelImage) def sobel_operators2(img): if img is None: return None global imageScale img = resize_image(img, imageScale) img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) # Sobel X kernel_x = np.array([ [-1, -2, -1], [0, 0, 0], [1, 2, 1] ]) SobelXImage = cv2.filter2D(src=img_gray, ddepth=-1, kernel=kernel_x) # Sobel Y kernel_y = np.array([ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1] ]) SobelYImage = cv2.filter2D(src=img_gray, ddepth=-1, kernel=kernel_y) SobelImage = cv2.addWeighted(SobelXImage, 1, SobelYImage, 1, 0) # 上色 SobelColored = cv2.cvtColor(SobelImage, cv2.COLOR_GRAY2BGR) SobelColored[:, :, 1:] = 0 combined = cv2.addWeighted(img_cv, 0.8, SobelColored, 0.8, 0) return Image.fromarray(combined) def Laplacian1(img): if img is None: return None global imageScale img = resize_image(img, imageScale) # 圖片大小保持 img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) kernel=np.array([ [ 0, -1, 0], [-1, 4, -1], [ 0, -1, 0]]) Image1=cv2.filter2D(src=img_gray,ddepth=-1,kernel=kernel) return Image.fromarray(Image1) def Laplacian2(img): if img is None: return None global imageScale img = resize_image(img, imageScale) img_cv = np.array(img) img_gray = cv2.cvtColor(img_cv, cv2.COLOR_RGB2GRAY) kernel = np.array([ [0, -1, 0], [-1, 4, -1], [0, -1, 0] ]) Image1 = cv2.filter2D(src=img_gray, ddepth=-1, kernel=kernel) ColoredImage = cv2.cvtColor(Image1, cv2.COLOR_GRAY2BGR) ColoredImage[:, :, 1:] = 0 combined = cv2.addWeighted(img_cv, 0.8, ColoredImage, 0.8, 0) return Image.fromarray(combined) # 設定 Gradio 介面 default_image = Image.open("./flower-color.jpg") default_image2 = Image.open("./butterfly.jpg") with gr.Blocks() as demo: gr.Markdown("## 圖片縮小與邊緣偵測演示") gr.Markdown("底下有範例圖片") with gr.Row(): img_input = gr.Image(type="pil", label="點擊上傳圖片 (webp或jpg)") with gr.Column(): img_output2 = gr.Image(label="處理後的圖片1") img_output1 = gr.Image(label="處理後的圖片2") with gr.Row(equal_height=True): slider = gr.Slider(0.1, 1.0, step=0.1, value=0.5, label="縮小比例", scale=4) resize_button = gr.Button("縮小圖片", scale=1, elem_id="button_scale") with gr.Row(): canny_button = gr.Button("Canny 邊緣偵測", elem_id="button1") sobel_button = gr.Button("索伯算子 邊緣偵測", elem_id="button2") laplacian_button = gr.Button("Laplacian 邊緣偵測", elem_id="button3") with gr.Row(): slider_canny1 = gr.Slider(1, 150, step=1, value=100, label="canny threshold 1 (min val)") slider_canny2 = gr.Slider(150, 300, step=1, value=200, label="canny threshold 2 (max val)") with gr.Row(): img_input2 = gr.Image(type="pil", label="範例圖片1", value=default_image2, interactive=False) img_input2 = gr.Image(type="pil", label="範例圖片2", value=default_image, interactive=False) # 連結功能 resize_button.click(fn=resize_image, inputs=[img_input, slider], outputs=img_output2) resize_button.click(fn=resize_image, inputs=[img_input, slider], outputs=img_output1) canny_button.click(fn=canny_edge1, inputs=[img_input,slider_canny1,slider_canny2], outputs=img_output1) canny_button.click(fn=canny_edge2, inputs=[img_input,slider_canny1,slider_canny2], outputs=img_output2) sobel_button.click(fn=sobel_operators1, inputs=[img_input], outputs=img_output1) sobel_button.click(fn=sobel_operators2, inputs=[img_input], outputs=img_output2) laplacian_button.click(fn=Laplacian1, inputs=[img_input], outputs=img_output1) laplacian_button.click(fn=Laplacian2, inputs=[img_input], outputs=img_output2) # 自訂 CSS demo.css = """ #button1, #button2, #button3 { background: linear-gradient(to right, #FFDAB9, #FFFFFF); color: black !important; border: 1px solid #ccc !important; font-weight: bold !important; border-radius: 5px; } #button1:hover, #button2:hover, #button3:hover { background: black !important; color: white !important; } #button_scale { font-size: inherit; transition: font-size 1s ease; } #button_scale:hover { font-size: 20px; } """ # 啟動應用 demo.launch()