Untitled

 avatar
unknown
plain_text
2 months ago
14 kB
14
Indexable
import tkinter as tk
from tkinter import filedialog, Button, Canvas
from PIL import Image, ImageTk
import numpy as np


class ImageEditor:
    def __init__(self, root):
        self.root = root
        self.root.title("Image Filters with GUI")
        
        self.canvas = Canvas(root, width=200, height=200, bg="gray")
        self.canvas.pack()

        Button(root, text="Open Image", command=self.open_image).pack(side="left")
        Button(root, text="Negative", command=self.apply_negative).pack(side="left")
        Button(root, text="Decrease Brightness", command=self.decrease_brightness).pack(side="left")
        Button(root, text="Increase Brightness", command=self.increase_brightness).pack(side="left")
        Button(root, text="Power", command=self.apply_power).pack(side="left")
        Button(root, text="Log Transformation", command=self.apply_log).pack(side="left")
        Button(root, text="Average Filter", command=self.apply_average).pack(side="left")
        Button(root, text="Max Filter", command=self.apply_max).pack(side="left")
        Button(root, text="Min Filter", command=self.apply_min).pack(side="left")
        Button(root, text="Median Filter", command=self.apply_median).pack(side="left")
        Button(root, text="Sobel", command=self.apply_sobel).pack(side="left")
        Button(root, text="Prewitt", command=self.apply_prewitt).pack(side="left")
        Button(root, text="Histogram", command=self.apply_histogram).pack(side="left")
        Button(root, text="Gaussian", command=self.apply_gaussian).pack(side="left")
        Button(root, text="Delete Image", command=self.delete_image).pack(side="left")
        Button(root, text="Save Image", command=self.save_image).pack(side="left")
        Button(root, text="Remove Filter", command=self.remove_filter).pack(side="left")

    def open_image(self):
        self.image_path = filedialog.askopenfilename()
        if self.image_path:
            self.original_image = Image.open(self.image_path).convert('L')  
            self.image = self.original_image.copy() 
            self.display_image(self.image)

    def display_image(self, img):
        img = img.resize((200, 200)) 
        self.tk_image = ImageTk.PhotoImage(img)
        self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image)

    def apply_negative(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            img_array = 255 - img_array 
            self.image = Image.fromarray(img_array)
            self.display_image(self.image)

    def decrease_brightness(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            img_array = img_array // 2
            img_array = np.clip(img_array, 0, 255)  
            self.image = Image.fromarray(img_array.astype(np.uint8))
            self.display_image(self.image)

    def increase_brightness(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            img_array = img_array * 2  
            img_array = np.clip(img_array, 0, 255)  
            self.image = Image.fromarray(img_array.astype(np.uint8))
            self.display_image(self.image)

    def apply_power(self, gamma=2.0):
        if self.image:
            img_array = np.array(self.image, dtype=np.float32)
            img_array = ((img_array / 255) ** gamma) * 255
            img_array = np.clip(img_array, 0, 255).astype(np.uint8)
            self.image = Image.fromarray(img_array)
            self.display_image(self.image)

    def apply_log(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.float32)  
            img_array = np.where(img_array > 0, 30 * np.log2(img_array), 0)  
            self.image = Image.fromarray(np.clip(img_array, 0, 255).astype(np.uint8)) 
            self.display_image(self.image)

    def apply_average(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.float32)
            height, width = img_array.shape
            new_image = np.zeros_like(img_array)

            for row in range(1, height - 1):
                for col in range(1, width - 1):
                    new_image[row, col] = (
                        img_array[row, col] * (1/9) +
                        img_array[row-1, col] * (1/9) +
                        img_array[row+1, col] * (1/9) +
                        img_array[row, col-1] * (1/9) +
                        img_array[row, col+1] * (1/9) +
                        img_array[row-1, col-1] * (1/9) +
                        img_array[row-1, col+1] * (1/9) +
                        img_array[row+1, col-1] * (1/9) +
                        img_array[row+1, col+1] * (1/9)
                    )
            self.image = Image.fromarray(np.clip(new_image, 0, 255).astype(np.uint8))
            self.display_image(self.image)

    def apply_max(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            height, width = img_array.shape
            new_image = np.zeros_like(img_array)

            for row in range(1, height - 1):
                for col in range(1, width - 1):
                    neighbors = [
                        img_array[row, col], img_array[row-1, col],
                        img_array[row-1, col+1], img_array[row+1, col],
                        img_array[row+1, col+1], img_array[row+1, col-1],
                        img_array[row-1, col-1], img_array[row][col+1],
                        img_array[row][col-1]
                    ]
                    new_image[row, col] = np.max(neighbors)
            self.image = Image.fromarray(new_image)
            self.display_image(self.image)

    def apply_min(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            height, width = img_array.shape
            new_image = np.zeros_like(img_array)

            for row in range(1, height - 1):
                for col in range(1, width - 1):
                    neighbors = [
                        img_array[row, col], img_array[row-1, col],
                        img_array[row-1, col+1], img_array[row+1, col],
                        img_array[row+1, col+1], img_array[row+1, col-1],
                        img_array[row-1, col-1], img_array[row][col+1],
                        img_array[row][col-1]
                    ]
                    new_image[row, col] = np.min(neighbors)
            self.image = Image.fromarray(new_image)
            self.display_image(self.image)

    def apply_median(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            height, width = img_array.shape
            new_image = np.zeros_like(img_array)

            for row in range(1, height - 1):
                for col in range(1, width - 1):
                    neighbors = [
                        img_array[row, col], img_array[row-1, col],
                        img_array[row-1, col+1], img_array[row+1, col],
                        img_array[row+1, col+1], img_array[row+1, col-1],
                        img_array[row-1, col-1], img_array[row][col+1],
                        img_array[row][col-1]
                    ]
                    new_image[row, col] = np.median(neighbors)  
            self.image = Image.fromarray(new_image)
            self.display_image(self.image)

    def apply_sobel(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8) 
            gx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) 
            gy = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]]) 
            
            h, w = img_array.shape
            new = np.zeros_like(img_array)

            for row in range(1, h - 1):
                for col in range(1, w - 1):
                    Gx = (
                        img_array[row-1][col-1] * gx[0][0] + 
                        img_array[row-1][col] * gx[0][1] + 
                        img_array[row-1][col+1] * gx[0][2] +
                        img_array[row][col-1] * gx[1][0] + 
                        img_array[row][col] * gx[1][1] + 
                        img_array[row][col+1] * gx[1][2] +
                        img_array[row+1][col-1] * gx[2][0] + 
                        img_array[row+1][col] * gx[2][1] + 
                        img_array[row+1][col+1] * gx[2][2]
                    )
                    Gy = (
                        img_array[row-1][col-1] * gy[0][0] + 
                        img_array[row-1][col] * gy[0][1] + 
                        img_array[row-1][col+1] * gy[0][2] +
                        img_array[row][col-1] * gy[1][0] + 
                        img_array[row][col] * gy[1][1] + 
                        img_array[row][col+1] * gy[1][2] +
                        img_array[row+1][col-1] * gy[2][0] + 
                        img_array[row+1][col] * gy[2][1] + 
                        img_array[row+1][col+1] * gy[2][2]
                    )
                    
                    G = np.sqrt(Gx**2 + Gy**2) 
                    new[row, col] = np.clip(G, 0, 255) 
            
            self.image = Image.fromarray(new.astype(np.uint8)) 
            self.display_image(self.image)

    def apply_prewitt(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8) 
            gx = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]]) 
            gy = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]) 
        
            h, w = img_array.shape
            new = np.zeros_like(img_array)

            for row in range(1, h - 1):
                for col in range(1, w - 1):
                    Gx = (
                        img_array[row-1][col-1] * gx[0][0] + 
                        img_array[row-1][col] * gx[0][1] + 
                        img_array[row-1][col+1] * gx[0][2] +
                        img_array[row][col-1] * gx[1][0] + 
                        img_array[row][col] * gx[1][1] + 
                        img_array[row][col+1] * gx[1][2] +
                        img_array[row+1][col-1] * gx[2][0] + 
                        img_array[row+1][col] * gx[2][1] + 
                        img_array[row+1][col+1] * gx[2][2]
                    )
                    Gy = (
                        img_array[row-1][col-1] * gy[0][0] + 
                        img_array[row-1][col] * gy[0][1] + 
                        img_array[row-1][col+1] * gy[0][2] +
                        img_array[row][col-1] * gy[1][0] + 
                        img_array[row][col] * gy[1][1] + 
                        img_array[row][col+1] * gy[1][2] +
                        img_array[row+1][col-1] * gy[2][0] + 
                        img_array[row+1][col] * gy[2][1] + 
                        img_array[row+1][col+1] * gy[2][2]
                    )
                    
                    G = np.sqrt(Gx**2 + Gy**2) 
                    new[row, col] = np.clip(G, 0, 255) 
            
            self.image = Image.fromarray(new.astype(np.uint8)) 
            self.display_image(self.image)

    def apply_histogram(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.uint8)
            hist = np.bincount(img_array.flatten(), minlength=256) 
            s_pdf = hist / np.size(img_array) 
            s_cdf = np.round(np.cumsum(s_pdf) * 255).astype(np.uint8)
            new_image = s_cdf[img_array]
            self.image = Image.fromarray(new_image)
            self.display_image(self.image)

    def apply_gaussian(self):
        if self.image:
            img_array = np.array(self.image, dtype=np.float32)
            G_kernel = np.array([[1, 2, 1],
                                 [2, 4, 2],
                                 [1, 2, 1]]) / 16

            h, w = img_array.shape
            new = np.zeros_like(img_array)

            for row in range(1, h - 1):
                for col in range(1, w - 1):
                    G = (
                        img_array[row - 1, col - 1] * G_kernel[0, 0] +
                        img_array[row - 1, col] * G_kernel[0, 1] +
                        img_array[row - 1, col + 1] * G_kernel[0, 2] +
                        img_array[row, col - 1] * G_kernel[1, 0] +
                        img_array[row, col] * G_kernel[1, 1] +
                        img_array[row, col + 1] * G_kernel[1, 2] +
                        img_array[row + 1, col - 1] * G_kernel[2, 0] +
                        img_array[row + 1, col] * G_kernel[2, 1] +
                        img_array[row + 1, col + 1] * G_kernel[2, 2]
                    )
                    new[row, col] = G
            self.image = Image.fromarray(np.clip(new, 0, 255).astype(np.uint8))
            self.display_image(self.image)

    def remove_filter(self):
        if self.original_image:
            self.image = self.original_image.copy()
            self.display_image(self.image)

    def delete_image(self):
        self.image = None
        self.canvas.delete("all") 

    def save_image(self):
        if self.image:
            save_path = filedialog.asksaveasfilename(defaultextension=".png",
                                                     filetypes=[("PNG files", "*.png"),
                                                                ("JPEG files", "*.jpg"),
                                                                ("All files", "*.*")])
            if save_path:
                self.image.save(save_path)
                print("Image saved to", save_path)


root = tk.Tk()
editor = ImageEditor(root)
root.mainloop()
Leave a Comment