Ynvers commited on
Commit
bd7f794
·
1 Parent(s): b6ecda4

initial commit

Browse files
Files changed (2) hide show
  1. app.py +167 -0
  2. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image
3
+ import numpy as np
4
+ import cv2
5
+ import matplotlib.pyplot as plt
6
+
7
+ # Fonctions de traitement d'image
8
+ def load_image(image):
9
+ return image
10
+
11
+ def apply_negative(image):
12
+ """
13
+ Transforme l'image en son négatif en inversant les valeurs de chaque pixel.
14
+ En résumé chaque pixel est soustrait de 255.
15
+ """
16
+ img = np.array(image)
17
+ negative = 255 - img
18
+ return Image.fromarray(negative)
19
+
20
+ def binarize_image(image, threshold):
21
+ """
22
+ D'abord l'image est convertie en niveau de gris.
23
+ Puis on utilise un seuil moyen pour la binarison de l'image.
24
+ """
25
+ img = np.array(image)
26
+ img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
27
+ img_binary = np.where( img_gray < threshold, 0, 255).astype(np.uint8)
28
+ return Image.fromarray(img_binary)
29
+
30
+ def resize_image(image, width, height):
31
+ """
32
+ Demande à l'utilisateur de choisir la hauteur et la largeur finale de l'image.
33
+ Ensuite resize cette image à partir de ces informations
34
+ """
35
+ return image.resize((width, height))
36
+
37
+ def rotate_image(image, angle):
38
+ """
39
+ Faire tourner l'image sur des angles données
40
+ """
41
+ return image.rotate(angle)
42
+
43
+ def histogramme(image):
44
+ """
45
+ Afficher l'histogramme de l'image.
46
+ La fonction fait la différence entre les images à un canal et celles à trois
47
+ """
48
+ img_array = np.array(image)
49
+ fig, axis = plt.subplots(figsize=(8, 4))
50
+ axis.set_title("Histogramme")
51
+
52
+ if len(img_array.shape) == 2:
53
+ histo = cv2.calcHist([img_array], [0], None, [256], [0, 256])
54
+ axis.plot(histo, color='black')
55
+ else:
56
+ rgbcolors = ["blue", "green", "red"]
57
+ for i, col in enumerate(rgbcolors):
58
+ histo = cv2.calcHist([img_array], [i], None, [256], [0, 256])
59
+ axis.plot(histo, color=col)
60
+
61
+ fig.canvas.draw()
62
+ data = np.frombuffer(fig.canvas.buffer_rgba(), dtype=np.uint8)
63
+ data = data.reshape(fig.canvas.get_width_height()[::-1] + (4,))
64
+ plt.close(fig)
65
+
66
+ return Image.fromarray(data[:,:,:3])
67
+
68
+ def contours_detector(image):
69
+ """
70
+ Détecter et afficher les contours des images
71
+ """
72
+ img = np.array(image)
73
+ gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
74
+ edge = cv2.Canny(gray, 100, 200)
75
+ return Image.fromarray(edge)
76
+
77
+ def floutage(image, kernel_size=5):
78
+ """
79
+ Appliquer un floutage avec une matrice définissable par l'utilisateur à l'image
80
+ """
81
+ img = np.array(image)
82
+ flou = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)
83
+ return Image.fromarray(flou)
84
+
85
+ def all_chanels(image):
86
+ pass
87
+
88
+
89
+ def update_fields(operation):
90
+ if operation == "Redimensionner":
91
+ return (gr.update(visible=True),
92
+ gr.update(visible=True),
93
+ gr.update(visible=False),
94
+ gr.update(visible=False),
95
+ gr.update(visible=False))
96
+ elif operation == "Binarisation":
97
+ return (gr.update(visible=False),
98
+ gr.update(visible=False),
99
+ gr.update(visible=True),
100
+ gr.update(visible=False),
101
+ gr.update(visible=False))
102
+ elif operation == "Rotation":
103
+ return (gr.update(visible=False),
104
+ gr.update(visible=False),
105
+ gr.update(visible=False),
106
+ gr.update(visible=True),
107
+ gr.update(visible=False))
108
+ elif operation == "Floutage":
109
+ return (gr.update(visible=False),
110
+ gr.update(visible=False),
111
+ gr.update(visible=False),
112
+ gr.update(visible=False),
113
+ gr.update(visible=True))
114
+ else:
115
+ return (gr.update(visible=False),
116
+ gr.update(visible=False),
117
+ gr.update(visible=False),
118
+ gr.update(visible=False),
119
+ gr.update(visible=False))
120
+
121
+
122
+ def image_processing(image, operation, threshold=128, width=100, height=100, angle=0, kernel_size=5):
123
+ if operation == "Négatif":
124
+ return apply_negative(image)
125
+ elif operation == "Binarisation":
126
+ return binarize_image(image, threshold)
127
+ elif operation == "Redimensionner":
128
+ return resize_image(image, width, height)
129
+ elif operation == "Rotation":
130
+ return rotate_image(image, angle)
131
+ elif operation == "Détection de Contours":
132
+ return contours_detector(image)
133
+ elif operation == "Floutage":
134
+ return floutage(image, kernel_size)
135
+
136
+ return image
137
+
138
+ def load_image_and_histogram(image):
139
+ hist_image = histogramme(image)
140
+ return hist_image
141
+
142
+ # Interface Gradio
143
+ with gr.Blocks() as demo:
144
+ gr.Markdown("## Image Master")
145
+
146
+ with gr.Row():
147
+ image_input = gr.Image(type="pil", label="Charger Image")
148
+ operation = gr.Radio(["Négatif", "Binarisation", "Redimensionner", "Rotation", "Channel", "Détection de Contours", "Floutage"], label="Opération")
149
+ threshold = gr.Slider(0, 255, 128, label="Seuil de binarisation", visible=False)
150
+ width = gr.Slider(minimum=50, maximum=1000, value=100, step=10, label="Largeur", visible=False)
151
+ height = gr.Slider(minimum=50, maximum=1000, value=100, step=10, label="Hauteur", visible=False)
152
+ angle = gr.Slider(minimum=-180, maximum=180, value=0, step=1, label="Angle de Rotation", visible=False)
153
+ kernel_size = gr.Slider(minimum=1, maximum=21, value=5, step=2, label="Taille du Noyau (Flou)", visible=False)
154
+
155
+ image_output = gr.Image(label="Image Modifiée")
156
+
157
+ histogram_output = gr.Image(label="Histogramme")
158
+
159
+ submit_button = gr.Button("Appliquer")
160
+
161
+ operation.change(update_fields, inputs=[operation], outputs=[width, height, threshold, angle, kernel_size])
162
+
163
+ image_input.change(load_image_and_histogram, inputs=image_input, outputs=histogram_output)
164
+
165
+ submit_button.click(image_processing, inputs=[image_input, operation, threshold, width, height, angle, kernel_size], outputs=image_output)
166
+
167
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio
2
+ Pillow
3
+ opencv-python-headless
4
+ matplotlib
5
+ numpy