Spaces:
Runtime error
Runtime error
import gradio as gr | |
from PIL import Image | |
import numpy as np | |
import cv2 | |
import matplotlib.pyplot as plt | |
# Fonctions de traitement d'image | |
def load_image(image): | |
return image | |
def apply_negative(image): | |
""" | |
Transforme l'image en son négatif en inversant les valeurs de chaque pixel. | |
En résumé chaque pixel est soustrait de 255. | |
""" | |
img = np.array(image) | |
negative = 255 - img | |
return Image.fromarray(negative) | |
def binarize_image(image, threshold): | |
""" | |
D'abord l'image est convertie en niveau de gris. | |
Puis on utilise un seuil moyen pour la binarison de l'image. | |
""" | |
img = np.array(image) | |
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | |
img_binary = np.where( img_gray < threshold, 0, 255).astype(np.uint8) | |
return Image.fromarray(img_binary) | |
def resize_image(image, width, height): | |
""" | |
Demande à l'utilisateur de choisir la hauteur et la largeur finale de l'image. | |
Ensuite resize cette image à partir de ces informations | |
""" | |
return image.resize((width, height)) | |
def rotate_image(image, angle): | |
""" | |
Faire tourner l'image sur des angles données | |
""" | |
return image.rotate(angle) | |
def histogramme(image): | |
""" | |
Afficher l'histogramme de l'image. | |
La fonction fait la différence entre les images à un canal et celles à trois | |
""" | |
img_array = np.array(image) | |
gray_image = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY) | |
fig, axis = plt.subplots(figsize=(8, 4)) | |
axis.set_title("Histogramme des niveaux de gris") | |
histo = cv2.calcHist([img_array], [0], None, [256], [0, 256]) | |
axis.plot(histo, color='black') | |
fig.canvas.draw() | |
data = np.frombuffer(fig.canvas.buffer_rgba(), dtype=np.uint8) | |
data = data.reshape(fig.canvas.get_width_height()[::-1] + (4,)) | |
plt.close(fig) | |
return Image.fromarray(data[:,:,:3]) | |
def contours_Sobel(image): | |
""" | |
Détecter et afficher les contours des images | |
""" | |
img = np.array(image) | |
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) | |
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5) | |
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5) | |
sobel = np.sqrt(sobel_x**2 + sobel_y**2) | |
sobel = np.uint8(sobel) | |
return Image.fromarray(sobel) | |
def filtre_Gaussien(image, kernel_size=5): | |
""" | |
Appliquer un Filtre Gaussien avec une matrice définissable par l'utilisateur à l'image | |
""" | |
img = np.array(image) | |
flou = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0) | |
return Image.fromarray(flou) | |
def erosion(image): | |
croix = np.array([ | |
[0,1,0], | |
[1,1,1], | |
[0,1,0]], dtype=np.uint8) | |
croix = croix*255 | |
image_test = np.array(image) | |
img_erosion = cv2.erode(image_test, croix) | |
return Image.fromarray(img_erosion) | |
def dilatation(image): | |
croix = np.array([ | |
[0,1,0], | |
[1,1,1], | |
[0,1,0]], dtype=np.uint8) | |
croix = croix*255 | |
image_test = np.array(image) | |
img_dilate = cv2.dilate(image_test, croix) | |
return Image.fromarray(img_dilate) | |
def update_fields(operation): | |
if operation == "Redimensionner": | |
return (gr.update(visible=True), | |
gr.update(visible=True), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False)) | |
elif operation == "Binarisation": | |
return (gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=True), | |
gr.update(visible=False), | |
gr.update(visible=False)) | |
elif operation == "Rotation": | |
return (gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=True), | |
gr.update(visible=False)) | |
elif operation == "Filtre Gaussien": | |
return (gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=True)) | |
else: | |
return (gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False)) | |
def image_processing(image, operation, threshold=128, width=100, height=100, angle=0, kernel_size=5): | |
if operation == "Négatif": | |
return apply_negative(image) | |
elif operation == "Binarisation": | |
return binarize_image(image, threshold) | |
elif operation == "Redimensionner": | |
return resize_image(image, width, height) | |
elif operation == "Rotation": | |
return rotate_image(image, angle) | |
elif operation == "Contours Sobel": | |
return contours_Sobel(image) | |
elif operation == "Filtre Gaussien": | |
return filtre_Gaussien(image, kernel_size) | |
elif operation == "Erosion": | |
return erosion(image) | |
elif operation == "Dilatation": | |
return dilatation(image) | |
return image | |
def load_image_and_histogram(image): | |
hist_image = histogramme(image) | |
return hist_image | |
# Interface Gradio | |
with gr.Blocks() as demo: | |
gr.Markdown("## Image Master") | |
with gr.Row(): | |
image_input = gr.Image( | |
type="pil", | |
label="Charger Image" | |
) | |
operation = gr.Radio( | |
["Négatif", | |
"Binarisation", | |
"Redimensionner", | |
"Rotation", | |
"Contours Sobel", | |
"Filtre Gaussien", | |
"Erosion", | |
"Dilatation" | |
], | |
label="Opération") | |
threshold = gr.Slider(0, 255, 128, label="Seuil de binarisation", visible=False) | |
width = gr.Slider(minimum=50, maximum=1000, value=100, step=10, label="Largeur", visible=False) | |
height = gr.Slider(minimum=50, maximum=1000, value=100, step=10, label="Hauteur", visible=False) | |
angle = gr.Slider(minimum=-180, maximum=180, value=0, step=1, label="Angle de Rotation", visible=False) | |
kernel_size = gr.Slider(minimum=1, maximum=21, value=5, step=2, label="Taille du Noyau (Flou)", visible=False) | |
image_output = gr.Image(label="Image Modifiée") | |
submit_button = gr.Button("Appliquer") | |
histogram_output = gr.Image(label="Histogramme") | |
operation.change(update_fields, inputs=[operation], outputs=[width, height, threshold, angle, kernel_size]) | |
image_input.change(load_image_and_histogram, inputs=image_input, outputs=histogram_output) | |
submit_button.click(image_processing, inputs=[image_input, operation, threshold, width, height, angle, kernel_size], outputs=image_output) | |
demo.launch() | |