Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| from PIL import Image | |
| import numpy as np | |
| import cv2 | |
| import matplotlib.pyplot as plt | |
| from skimage import exposure | |
| from scipy import signal | |
| from skimage.color import rgb2gray | |
| # Fonctions de traitement d'image | |
| def load_image(image): | |
| return image | |
| def apply_negative(image): | |
| img_np = np.array(image) | |
| negative = 255 - img_np | |
| return Image.fromarray(negative) | |
| def binarize_image(image, threshold): | |
| img_np = np.array(image.convert('L')) | |
| _, binary = cv2.threshold(img_np, threshold, 255, cv2.THRESH_BINARY) | |
| return Image.fromarray(binary) | |
| def resize_image(image, width, height): | |
| return image.resize((width, height)) | |
| def rotate_image(image, angle): | |
| return image.rotate(angle) | |
| def histogram(image): | |
| img_np = np.array(image) | |
| gray = rgb2gray(img_np) | |
| hist, _ = exposure.histogram(gray) | |
| plt.figure(figsize=(6, 4)) | |
| plt.title('Histogramme en nuances de gris') | |
| plt.xlabel('Intensité des pixels') | |
| plt.ylabel('Nombre de pixels') | |
| plt.bar(np.arange(len(hist)), hist, width=0.5, color='gray') | |
| plt.tight_layout() | |
| plt.show() | |
| def mean_filter(image): | |
| img_np = np.array(image) | |
| mean_filtered = cv2.blur(img_np, (5, 5)) # Filtre moyen 5x5 | |
| return Image.fromarray(mean_filtered) | |
| def gaussian_filter(image): | |
| img_np = np.array(image) | |
| gaussian_filtered = cv2.GaussianBlur(img_np, (5, 5), 0) # Filtre gaussien 5x5 | |
| return Image.fromarray(gaussian_filtered) | |
| def contour_extract(image): | |
| img_np = np.array(image.convert('L')) | |
| kernel = np.array([[0, 0, 0], [-1, 1, 0], [0, 0, 0]]) | |
| img_contour = signal.convolve2d(img_np, kernel, boundary='symm', mode='same') | |
| return Image.fromarray(np.uint8(np.absolute(img_contour))) | |
| def morph_erosion(image): | |
| img_np = np.array(image.convert('L')) # Conversion en niveaux de gris | |
| kernel = np.ones((5, 5), np.uint8) # Noyau 5x5 pour l'érosion | |
| erosion = cv2.erode(img_np, kernel, iterations=1) | |
| return Image.fromarray(erosion) | |
| def morph_dilation(image): | |
| img_np = np.array(image.convert('L')) # Conversion en niveaux de gris | |
| kernel = np.ones((5, 5), np.uint8) # Noyau 5x5 pour la dilatation | |
| dilation = cv2.dilate(img_np, kernel, iterations=1) | |
| return Image.fromarray(dilation) | |
| # Sauvegarder l'image sur l'ordinateur | |
| def save_image(image): | |
| img_np = np.array(image) | |
| save_path = "image_modifiee.png" | |
| cv2.imwrite(save_path, cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)) # Sauvegarder en format PNG | |
| return save_path | |
| # Interface Gradio | |
| def image_processing(image, operation, threshold=128, width=100, height=100, angle=0): | |
| 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 == "Histogramme": | |
| histogram(image) # Affichage seulement | |
| return image | |
| elif operation == "Filtre moyen": | |
| return mean_filter(image) | |
| elif operation == "Filtre gaussien": | |
| return gaussian_filter(image) | |
| elif operation == "Contours": | |
| return contour_extract(image) | |
| elif operation == "Erosion": | |
| return morph_erosion(image) | |
| elif operation == "Dilatation": | |
| return morph_dilation(image) | |
| return image | |
| # Mise à jour dynamique de la visibilité des champs en fonction de l'opération | |
| def update_visibility(operation): | |
| return { | |
| "threshold": operation == "Binarisation", | |
| "width": operation == "Redimensionner", | |
| "height": operation == "Redimensionner", | |
| "angle": operation == "Rotation" | |
| } | |
| # Interface Gradio avec style | |
| custom_css = """ | |
| #main-header { | |
| color: #4CAF50; /* Vert clair */ | |
| font-family: 'Arial', sans-serif; | |
| text-align: center; | |
| } | |
| #upload-area { | |
| border: 2px solid #FF9800; /* Orange */ | |
| background-color: #FFF3E0; | |
| } | |
| #result-area { | |
| border: 2px solid #4CAF50; | |
| background-color: #E8F5E9; | |
| } | |
| #process-button { | |
| background-color: #FF9800; /* Orange */ | |
| color: white; | |
| font-size: 16px; | |
| } | |
| """ | |
| with gr.Blocks(css=custom_css) as demo: | |
| gr.Markdown("## 🌈 PixelCrafter: Transformez vos images avec style 🎨") | |
| with gr.Row(): | |
| image_input = gr.Image(type="pil", label="Charger Image") | |
| operation = gr.Radio( | |
| ["Négatif", "Binarisation", "Redimensionner", "Rotation", "Histogramme", "Filtre moyen", "Filtre gaussien", "Contours", "Erosion", "Dilatation"], | |
| label="Opération", value="Négatif" | |
| ) | |
| threshold = gr.Slider(0, 255, 128, label="Seuil de binarisation", visible=False) | |
| width = gr.Number(value=100, label="Largeur", visible=False) | |
| height = gr.Number(value=100, label="Hauteur", visible=False) | |
| angle = gr.Number(value=0, label="Angle de Rotation", visible=False) | |
| image_output = gr.Image(label="Image Modifiée") | |
| # Mise à jour de la visibilité des champs | |
| operation.change(update_visibility, inputs=operation, outputs=[threshold, width, height, angle]) | |
| # Bouton d'application | |
| submit_button = gr.Button("Appliquer") | |
| submit_button.click(image_processing, inputs=[image_input, operation, threshold, width, height, angle], outputs=image_output) | |
| # Sauvegarde de l'image | |
| save_button = gr.Button("Sauvegarder l'image") | |
| save_button.click(save_image, inputs=image_output, outputs=gr.File(label="Télécharger l'image")) | |
| # Lancer l'application Gradio | |
| demo.launch() | |