import tkinter as tk #used for making gui
from tkinter import filedialog, messagebox
from tkinter import ttk
import cv2 as cv #used for image processing
from functions import (
read_image, threshold_image, histogram, histogram_equalization,
min as img_min, max as img_max, median, spatial_filter, min_filter,
gradient, correlation
) #imports these functions from the functions code
from PIL import Image, ImageTk # also for image processing
import numpy as np #for arrays
import [Link] as plt #for plotting histogram
class ImageProcessorApp:
def __init__(self, root):
# initialize the tkinter root window
[Link] = root
[Link]("Image Processor")
#variables for storing images
[Link] = None
self.processed_img = None
# create GUI widgets
self.create_widgets()
def create_widgets(self):
# frame for buttons
[Link] = [Link]([Link])
[Link](pady=10)
# button for loading image
self.load_button = [Link]([Link], text="Load Image",
command=self.load_image)
self.load_button.grid(row=0, column=0, padx=5) # button for saving
image
self.save_button = [Link]([Link], text="Save Image",
command=self.save_image)
self.save_button.grid(row=0, column=1, padx=5)
# button for resetting imaage
self.reset_button = [Link]([Link], text="Reset Image",
command=self.reset_image)
self.reset_button.grid(row=0, column=2, padx=5)
# menu for selecting image processing functions(threshold,gradient y,
gradient x etc.)
self.function_var = [Link]([Link])
self.function_var.set("Choose Function")
self.function_menu = [Link]([Link],
textvariable=self.function_var)
self.function_menu['values'] = [
"Threshold", "Histogram Equalization", "Median Filter",
"Spatial Filter", "Min Filter", "Gradient X", "Gradient Y", "Correlation"
]
self.function_menu.grid(row=1, column=0, columnspan=2, pady=5)
# button for applying function selected from the menu
self.apply_button = [Link]([Link], text="Apply",
command=self.apply_function)
self.apply_button.grid(row=1, column=2, padx=5)
# canvas for image display
[Link] = [Link]([Link], width=500, height=500, bg="gray")
[Link](pady=10)
# frame for histogram and min,max values
self.info_frame = [Link]([Link])
self.info_frame.pack(pady=10)
# labels for histogram,min and max values
self.hist_label = [Link](self.info_frame, text="Histogram:")
self.hist_label.grid(row=0, column=0) self.min_label =
[Link](self.info_frame, text="Min: N/A")
self.min_label.grid(row=0, column=1, padx=10)
self.max_label = [Link](self.info_frame, text="Max: N/A")
self.max_label.grid(row=0, column=2, padx=10)
# canvas for histogram display
self.hist_canvas = [Link](self.info_frame, width=256, height=100,
bg="white")
self.hist_canvas.grid(row=1, column=0, columnspan=3, pady=5)
def load_image(self):
# load an image from pc
path = [Link](filetypes=[("Image files", "*.jpg *.jpeg
*.png *.bmp")])
if path:
[Link] = read_image(path)
self.display_image([Link])
self.update_histogram_and_min_max([Link])
def save_image(self):
# save the processed image to pc
if self.processed_img is not None:
path = [Link](defaultextension=".png",
filetypes=[("PNG files", "*.png"), ("All files", "*.*")])
if path:
[Link](path, self.processed_img)
[Link]("Image Saved", "Image saved successfully!")
else:
[Link]("No Image", "No processed image to save.")
def reset_image(self):
# reset the displayed image to the original
if [Link] is not None:
self.display_image([Link])
self.update_histogram_and_min_max([Link])
self.processed_img = None
def display_image(self, img): # display the given image on the
canvas(and to resize to fit the canvas)
img = [Link](img, (500, 500))
img = [Link](img, cv.COLOR_GRAY2RGB)
img = [Link](img)
img = [Link](img)
[Link].create_image(0, 0, anchor=[Link], image=img)
[Link] = img
def apply_function(self):
# apply the selected function
if [Link] is None:
[Link]("No Image", "Please load an image first.")
return
function_name = self.function_var.get()
if function_name == "Threshold":
self.processed_img = threshold_image([Link], 127)
elif function_name == "Histogram Equalization":
self.processed_img = histogram_equalization([Link])
elif function_name == "Median Filter":
self.processed_img = median([Link])
elif function_name == "Spatial Filter":
self.processed_img = spatial_filter([Link])
elif function_name == "Min Filter":
self.processed_img = min_filter([Link])
elif function_name == "Gradient X":
self.processed_img = gradient([Link], 'x')
elif function_name == "Gradient Y":
self.processed_img = gradient([Link], 'y')
elif function_name == "Correlation":
self.processed_img = correlation([Link])
else:
[Link]("Invalid Selection", "Please select a valid
function.")
return
self.display_image(self.processed_img) # display the processed image
self.update_histogram_and_min_max(self.processed_img) # update
histogram and min,max values def update_histogram_and_min_max(self,
img):
# calculate histogram
hist = histogram(img)
# plot the histogram
self.plot_histogram(hist)
# calculate min and max pixel values
min_val = img_min(img)
max_val = img_max(img)
self.min_label.config(text=f"Min: {min_val}")
self.max_label.config(text=f"Max: {max_val}")
def plot_histogram(self, hist):
# plot the histogram on the canvas
self.hist_canvas.delete("all")
max_height = max(hist)
for i in range(256):
height = int((hist[i] / max_height) * 100)
self.hist_canvas.create_line(i, 100, i, 100 - height, fill="black")
if __name__ == "__main__":
root = [Link]() # creates the main application window
app = ImageProcessorApp(root) #starts the image processing window
[Link]()
Functions Module:
import cv2 as cv
def read_image(path):
#reads an image from the and resizes it to 500x500 grayscale
img = [Link](path, cv.IMREAD_GRAYSCALE)
img = [Link](img, (500, 500))
return img
def threshold_image(img, threshold):
#applies a binary threshold to the image.
_, img = [Link](img, threshold, 255, cv.THRESH_BINARY)
return imgdef histogram(img):
#calculates and returns the histogram of the image
hist = [Link]([img], [0], None, [256], [0, 256])
return hist
def histogram_equalization(img):
#applies histogram equalization to the image
img = [Link](img)
return img
def min(img):
# returns the minimum pixel value in the image
return [Link]()
def max(img):
# returns the maximum pixel value in the image
return [Link]()
def median(img):
#applies median filter to the image
return [Link](img, 5)
def spatial_filter(img):
# applies spatial filter to the image
kernel = [Link](cv.MORPH_RECT, (3, 3))
img = [Link](img, cv.MORPH_CLOSE, kernel)
return img
def min_filter(img):
# applies a minimum filter to the image
kernel = [Link](cv.MORPH_RECT, (3, 3))
img = [Link](img, kernel)
return img
def gradient(img, edge):
#calculates the gradient of the image (x/y)
if edge == 'x':
kernel = [Link](cv.MORPH_RECT, (1, 3))
elif edge == 'y':
kernel = [Link](cv.MORPH_RECT, (3, 1)) img =
[Link](img, cv.MORPH_GRADIENT, kernel)
return img
def correlation(img):
#applies correlation operation to the image
kernel = [Link](cv.MORPH_RECT, (3, 3))
img = cv.filter2D(img, -1, kernel)
return img