import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
import cv2
import numpy as np
from PIL import Image, ImageTk
class MainWindow:
def __init__(self, master):
self.master = master
master.title("OpenCV Image Processor")
self.original_image = None
self.current_image = None
self.hist_image = None
self.processed_image = None
self.coefficients = None
self.left_frame = tk.Frame(master)
self.left_frame.grid(row=0, column=0, padx=5, pady=5)
self.right_frame = tk.Frame(master)
self.right_frame.grid(row=0, column=1, padx=5, pady=5)
self.load_button = ttk.Button(self.left_frame, text="Load Image", command=self.load_image)
self.load_button.pack(side="top", padx=5, pady=5, fill="x")
self.save_button = ttk.Button(self.left_frame, text="Save Image", command=self.save_image)
self.save_button.pack(side="top", padx=5, pady=5, fill="x")
self.filter_label = ttk.Label(self.left_frame, text="Filters")
self.filter_label.pack(side="top", padx=5, pady=5)
self.filter_variable = tk.StringVar()
self.filter_combobox = ttk.Combobox(self.left_frame, textvariable=self.filter_variable, state="readonly", values=("None", "Gray Scale", "Histogram Equalization", "Sharpen", "Edge Detection"))
self.filter_combobox.current(0)
self.filter_combobox.pack(side="top", padx=5, pady=5, fill="x")
self.coefficients_label = ttk.Label(self.left_frame, text="Filter Coefficients")
self.coefficients_label.pack(side="top", padx=5, pady=5)
self.coefficients_variable = tk.StringVar()
self.coefficients_entry = ttk.Entry(self.left_frame, textvariable=self.coefficients_variable)
self.coefficients_entry.pack(side="top", padx=5, pady=5, fill="x")
self.process_button = ttk.Button(self.left_frame, text="Process Image", command=self.process_image)
self.process_button.pack(side="top", padx=5, pady=5, fill="x")
self.original_label = ttk.Label(self.right_frame, text="Original")
self.original_label.pack(side="top", padx=5, pady=5)
self.original_canvas = tk.Canvas(self.right_frame)
self.original_canvas.pack(side="top", padx=5, pady=5, fill="both", expand=True)
self.current_label = ttk.Label(self.right_frame, text="Current")
self.current_label.pack(side="top", padx=5, pady=5)
self.current_canvas = tk.Canvas(self.right_frame)
self.current_canvas.pack(side="top", padx=5, pady=5, fill="both", expand=True)
self.hist_label = ttk.Label(self.right_frame, text="Histogram")
self.hist_label.pack(side="top", padx=5, pady=5)
self.hist_canvas = tk.Canvas(self.right_frame)
self.hist_canvas.pack(side="top", padx=5, pady=5, fill="both", expand=True)
self.master.columnconfigure(1, weight=1)
self.master.rowconfigure(0, weight=1)
def load_image(self):
filetypes = [("JPEG Images", "*.jpg"), ("PNG Images", "*.png")]
file_path = filedialog.askopenfilename(title="Load Image", filetypes=filetypes)
if file_path:
self.original_image = cv2.imread(file_path)
self.update_canvases()
def save_image(self):
if self.processed_image is not None:
filename = filedialog.asksaveasfilename(title="Save Image", defaultextension=".png", filetypes=[("PNG Images", "*.png")])
if filename:
cv2.imwrite(filename, self.processed_image)
def process_image(self):
if self.original_image is not None:
filter_name = self.filter_variable.get()
filter_coefficients = self.coefficients_variable.get()
img = self.original_image.copy()
if filter_name == "None":
self.current_image = img
self.hist_image = None
self.processed_image = None
elif filter_name == "Gray Scale":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
self.current_image = gray
self.hist_image = cv2.calcHist([gray], [0], None, [256], [0, 256])
self.processed_image = gray
elif filter_name == "Histogram Equalization":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
equ = cv2.equalizeHist(gray)
self.current_image = equ
self.hist_image = cv2.calcHist([equ], [0], None, [256], [0, 256])
self.processed_image = equ
elif filter_name == "Sharpen":
kernel = np.array(eval(filter_coefficients))
sharp = cv2.filter2D(img, -1, kernel)
self.current_image = sharp
self.hist_image = cv2.calcHist([sharp], [0], None, [256], [0, 256])
self.processed_image = sharp
elif filter_name == "Edge Detection":
blurred = cv2.medianBlur(img, 5)
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
self.current_image = edges
self.hist_image = cv2.calcHist([edges], [0], None, [256], [0, 256])
self.processed_image = edges
self.update_canvases()
def update_canvases(self):
if self.original_image is not None:
self.original_canvas.delete("all")
img = cv2.resize(self.original_image, (300, 300))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
img = ImageTk.PhotoImage(img)
self.original_canvas.config(width=img.width(), height=img.height())
self.original_canvas.create_image(0, 0, anchor="nw", image=img)
self.original_canvas.image = img
if self.current_image is not None:
self.current_canvas.delete("all")
img = cv2.resize(self.current_image, (300, 300))
if len(img.shape) == 2:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
else:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
img = ImageTk.PhotoImage(img)
self.current_canvas.config(width=img.width(), height=img.height())
self.current_canvas.create_image(0, 0, anchor="nw", image=img)
self.current_canvas.image = img
if self.hist_image is not None:
self.hist_canvas.delete("all")
hist = self.hist_image
hist = cv2.normalize(hist, hist, 0, 255, cv2.NORM_MINMAX)
hist = np.float32(np.cumsum(hist))
hist /= hist[-1]
hist = np.uint8(np.around(hist * 255))
h = hist.reshape((256, 1))
hist_image = np.tile(h, (1, 300, 3))
hist_image = Image.fromarray(hist_image)
hist_image = ImageTk.PhotoImage(hist_image)
self.hist_canvas.config(width=hist_image.width(), height=hist_image.height())
self.hist_canvas.create_image(0, 0, anchor="nw", image=hist_image)
self.hist_canvas.image = hist_image
root = tk.Tk()
window = MainWindow(root)
root.mainloop()