File size: 5,787 Bytes
2a3b938
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d63390
 
2a3b938
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d63390
2a3b938
3d63390
2a3b938
 
 
 
 
 
 
 
3d63390
2a3b938
 
 
 
 
 
 
3d88718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16d1348
 
 
 
 
 
 
 
 
 
 
b2f5bfb
2a3b938
 
 
 
 
 
 
16d1348
 
 
 
1707930
48e84e1
 
 
16d1348
b2f5bfb
 
 
 
 
 
 
 
48e84e1
b2f5bfb
16d1348
290213e
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
import cv2  
import gradio as gr  
import numpy as np  


def original_image(input_image):
    return input_image

def grayscale(input_image):
    gray_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
    return gray_image

def edge_detection(input_image):
    edges = cv2.Canny(input_image, 100, 200)
    return edges

def sobel_edge_detection(input_image):
    gray_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
    sobel_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=5)
    sobel_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=5)
    sobel_magnitude = cv2.magnitude(sobel_x, sobel_y)
    sobel_magnitude = np.uint8(255 * sobel_magnitude / np.max(sobel_magnitude))
    return sobel_magnitude

def invert_colors(input_image):
    inverted_image = cv2.bitwise_not(input_image)
    return inverted_image

def erosion(input_image, iterations):
    kernel = np.ones((5, 5), np.uint8)
    eroded_image = cv2.erode(input_image, kernel, iterations=iterations)
    return eroded_image

def dilation(input_image, dilation_iterations):
    kernel = np.ones((5, 5), np.uint8)
    dilated_image = cv2.dilate(input_image, kernel, iterations=dilation_iterations)
    return dilated_image

def gaussian_blur(image, blur_degree):

    blur_degree = int(blur_degree) | 1 

    result = cv2.GaussianBlur(image, (blur_degree, blur_degree), 0)
    
    return result


def custom_filter(input_image):
    kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])
    return cv2.filter2D(input_image, -1, kernel)


def mosaic(image, block_size):
    if image is None:
        return None
    
    height, width = image.shape[:2]
    for y in range(0, height, block_size):
        for x in range(0, width, block_size):
            # Define the region of interest (ROI), ensuring it doesn't go out of bounds
            roi = image[y:min(y + block_size, height), x:min(x + block_size, width)]
            
            # Compute the average color of the ROI
            color = np.mean(roi, axis=(0, 1)).astype(int)
            
            # Set the block region to the average color
            image[y:min(y + block_size, height), x:min(x + block_size, width)] = color
    
    return image



def apply_opencv_methods(input_image, method, iterations, blur_degree, dilation_iterations, mosaic_block_size):
    if method == "default":
        return original_image(input_image)
    elif method == "erosion":
        return erosion(input_image, iterations)
    elif method == "dilation":
        return dilation(input_image, dilation_iterations)
    elif method == "邊緣檢測1(Sobel)":
        return sobel_edge_detection(input_image)
    elif method == "風格變換":
        return custom_filter(input_image)
    elif method == "模糊":
        return gaussian_blur(input_image, blur_degree) 
    elif method == "馬賽克":
        return mosaic(input_image,mosaic_block_size)  
    else:
        methods = {
            "灰階": grayscale,
            "邊緣檢測2(Canny)": edge_detection,
            "反轉顏色": invert_colors,
        }
        return methods[method](input_image)


def update_slider_visibility(method):
    return (
        gr.update(visible=(method == "erosion")),
        gr.update(visible=(method == "模糊")),
        gr.update(visible=(method == "dilation")),
        gr.update(visible=(method == "馬賽克"))
    )

css="""
        @import url('https://fonts.googleapis.com/css2?family=LXGW+WenKai+TC&display=swap');
        
        .gradio-container {
            font-family: 'LXGW WenKai TC', sans-serif;  /* 將字體套用到整個 Gradio 介面 */
        }
        
        .gradio-container h1 {  /* 修改 title 標題樣式 */
            font-family: 'LXGW WenKai TC', sans-serif;  /* 字體 */
            font-size: 32px;  /* 字體大小 */
            color: #F5F5DC;  /* 字體顏色 */
            text-align: center;  /* 置中對齊 */
        }
    
        .dark-light-toggle {  /* 隱藏主題切換按鈕 */
            display: none !important;
        }
        """

with gr.Blocks(css=css) as demo:
    input_image = gr.Image(type="numpy", label="input image")
    method = gr.Radio(
        choices=["default", "灰階", "反轉顏色", "erosion", "dilation", "模糊", "馬賽克" ,"邊緣檢測1(Sobel)", "邊緣檢測2(Canny)", "風格變換"],
        value="default",
        label="選擇操作方法")
    iterations = gr.Slider(minimum=0, maximum=10, step=1, value=1, label="參數大小", visible=False)
    blur_degree = gr.Slider(minimum=1, maximum=25, step=2, value=1, label="模糊程度", visible=False)
    dilation_iterations = gr.Slider(minimum=0, maximum=10, step=1, value=1, label="參數大小", visible=False)
    mosaic_block_size = gr.Slider(minimum=5, maximum=50, step=5, value=5, label="馬賽克塊大小", visible=False)
    output_image = gr.Image(type="numpy", label="output image")

    

    method.change(
        fn=update_slider_visibility,
        inputs=[method],
        outputs=[iterations, blur_degree, dilation_iterations, mosaic_block_size]
    )

    gr.Interface(
        fn=apply_opencv_methods,
        inputs=[input_image, method, iterations, blur_degree, dilation_iterations, mosaic_block_size],
        outputs=output_image,
        live=True,
        title="各種影像處理",
        description="上傳一張圖片並選擇想要處理影像的方法",
        
    )
    
    examples = gr.Examples(
        examples=[
            ["chikawa.jpg", "erosion", 2, None, None, None],
            ["cat.jpg", "風格變換", None, None, None, None],
            ["pui.jpg", "模糊", None, 15, None, None]
        ],
        inputs=[input_image, method, iterations, blur_degree, dilation_iterations, mosaic_block_size],
        label="example",
    )

demo.launch()