import cv2
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import numpy as np

# Set a fixed display size for the images
display_size = (700, 700)

# Function to load and process image
def process_image(filter_type):
    global image, panelA, path
    
    if path:
        # Load the image and convert it to grayscale
        image = cv2.imread(path)
        
        # Resize the image to fit the display size
        image_resized = cv2.resize(image, display_size, interpolation=cv2.INTER_AREA)
        
        if image_resized.ndim == 3 and filter_type != 'original':
            # Convert to grayscale for filtering if needed
            image_resized = cv2.cvtColor(image_resized, cv2.COLOR_BGR2GRAY)

       # Kernel (custom filtering)
kernel = np.array([[0, -1, 0],
                   [-1, 5, -1],
                   [0, -1, 0]])
sharpened_img = cv2.filter2D(resized_img, -1, kernel)

# Sobel operator
sobelx = cv2.Sobel(resized_img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(resized_img, cv2.CV_64F, 0, 1, ksize=3)

# Laplacian
laplacian = cv2.Laplacian(resized_img, cv2.CV_64F)

# Canny edge detection
canny_edges = cv2.Canny(resized_img, threshold1=100, threshold2=200)

# Motion Blur
size = 15
motion_blur_kernel = np.zeros((size, size))
motion_blur_kernel[int((size-1)/2), :] = np.ones(size)
motion_blur_kernel = motion_blur_kernel / size
motion_blurred = cv2.filter2D(resized_img, -1, motion_blur_kernel)

# Embossing
embossing_kernel = np.array([[-2, -1, 0],
                             [-1, 1, 1],
                             [0, 1, 2]])
embossed_img = cv2.filter2D(resized_img, -1, embossing_kernel)
        if processed_image.ndim == 2:
            # Convert to BGR for color consistency
            processed_image = cv2.cvtColor(processed_image, cv2.COLOR_GRAY2BGR)

        # Convert the image to PIL format and then to ImageTk format
        processed_image = Image.fromarray(processed_image)
        processed_image = ImageTk.PhotoImage(processed_image)
        
        # If the panel A is None, initialize it
        if panelA is None:
            panelA = tk.Label(image=processed_image)
            panelA.image = processed_image
            panelA.pack(side="top", padx=10, pady=10)
        else:  # Update the panel
            panelA.configure(image=processed_image)
            panelA.image = processed_image

# Function to open file dialog and load an image
def open_image():
    global path
    path = filedialog.askopenfilename()
    if path:  # If a file was selected
        process_image('original')

# Initialize the window
root = tk.Tk()
root.title("Edge Detection GUI")
# Set the initial width of the window
# Set the window to full screen
root.attributes('-fullscreen', True)
# Initialize panelA (to display the image)
panelA = None

# Initialize image path
path = None
def exit_application():
    root.destroy()
# Create exit button
btn_exit = tk.Button(root, text="Exit", command=exit_application)
btn_exit.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
# Create buttons for different edge detection methods

btn_sobel = tk.Button(root, text="Sobel", command=lambda: process_image('sobel'))
btn_sobel.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")

btn_laplacian = tk.Button(root, text="Laplacian", command=lambda: process_image('laplacian'))
btn_laplacian.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")

btn_canny = tk.Button(root, text="Canny", command=lambda: process_image('canny'))
btn_canny.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")

btn_blur = tk.Button(root, text="Blur", command=lambda: process_image('blur'))
btn_blur.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")

btn_embossing = tk.Button(root, text="Embossing", command=lambda: process_image('embossing'))
btn_embossing.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")
# Function to exit the application
btn_open = tk.Button(root, text="Open Image", command=open_image)
btn_open.pack(side='bottom', fill="both", expand="yes", padx="10", pady="10")

# Start the GUI loop
root.mainloop()