import gradio as gr from PIL import Image, ImageFilter import numpy as np import cv2 from skimage import morphology import matplotlib.pyplot as plt import io # Images manipulation functions #Image loading def load_image(image_path): '''Load image with PIL''' image=Image.open(image_path) return image #Negative APPLYING def apply_negative(image): ''' input: PIL Image output : PIL Image Image loaded with PIL is turned to numpy format. Then, we calculate the new pixels values and image gotten is return to PIL format''' img_np = np.array(image) negative = 255 - img_np return Image.fromarray(negative) #binarization def binarize_image(image, threshold_value): ''' inputs : PIL image ; threshold_value output : PIL image Image in PIL format is converted into grayscale format and then into numpy format.Now we make a binary threshold base on threshold value. Image gotten is returned to Image format''' img_np = np.array(image.convert('L')) _, binary = cv2.threshold(img_np, threshold_value, 255, cv2.THRESH_BINARY) return Image.fromarray(binary) #image resizing def resize_image(image, width, height): '''Resizing is doing by using PIL resizing method''' return image.resize((width, height)) #image rotation def rotate_image(image, angle): '''Rotation is doing by using PIL rotation method''' return image.rotate(angle) #Image histogram def histogram(image): img = np.array(image.convert('L')) hist = cv2.calcHist([img],[0],None,[256],[0,256]) plt.plot(hist) img_buf = io.BytesIO() plt.savefig(img_buf, format='png') return Image.open(img_buf) #Gaussian filter def g_filter(image): img_gauss = image.filter(ImageFilter.GaussianBlur(5) ) return img_gauss #Sobel def sobel_f(image): i = np.array(image) img = cv2.GaussianBlur(i, (3, 3), sigmaX=0, sigmaY=0) edge_sobel = cv2.Sobel(src=img, ddepth=cv2.CV_8U, dx=1, dy=1, ksize=5) return Image.fromarray(edge_sobel) #erosion def erosion(image): i=np.array(image.convert('L')) ero_img= morphology.binary_erosion(i, morphology.disk(1)) return Image.fromarray(ero_img) #dilatation def dilatation(image): i=np.array(image.convert('L')) ero_img= morphology.binary_dilation(i, morphology.disk(1)) return Image.fromarray(ero_img) #contour def contour(image): return image.filter(ImageFilter.CONTOUR) #lumineux def lumineux(image): return image.filter(ImageFilter.EDGE_ENHANCE) #Netteté def nette(image): return image.filter(ImageFilter.SHARPEN) # 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": return histogram(image) elif operation == "Gaussian Filter": return g_filter(image) elif operation == "Sobel": return sobel_f(image) elif operation == "Erosion": return erosion(image) elif operation == "Dilatation": return erosion(image) elif operation == "Contour": return contour(image) elif operation == "Luminosité": return lumineux(image) elif operation == "Netteté": return nette(image) return image # Gradio Interface with gr.Blocks() as demo: gr.Markdown("## Mini photoshop") with gr.Row(): image_input = gr.Image(type="pil", label="Charger Image") operation = gr.Radio(["Négatif", "Binarisation", "Redimensionner", "Rotation","Histogramme","Gaussian Filter","Sobel", "Erosion","Dilatation","Luminosité","Contour", "Netteté"], label="Opération") threshold = gr.Slider(0, 255, 128, label="Seuil de binarisation", visible=True) width = gr.Number(value=100, label="Largeur de redimensionnement", visible=True) height = gr.Number(value=100, label="Hauteur de redimensionnement", visible=True) angle = gr.Number(value=0, label="Angle de Rotation", visible=True) image_output = gr.Image(label="Image Modifiée") submit_button = gr.Button("Appliquer") submit_button.click(image_processing, inputs=[image_input, operation, threshold, width, height, angle], outputs=image_output) # Launch application demo.launch()