Saturday, October 14, 2023

TKINTER: COLOR SPACE

This is the product of BALIGE ACADEMY TEAM: Vivian Siahaan and Rismon Hasiholan Sianipar.

SEMANGAT BELAJAR dan HORAS!!!

BALIGE CITY, NORTH SUMATERA


SUPPORT OUR CHANNEL BY SUBSCRIBING TO IT:




TKINTER: COLOR SPACE








FULL SOURCE CODE


#main_program.py
import tkinter as tk from main_form import Main_Form from plot_utils import Plot_Utils class Main_Program(): def __init__(self, root): self.initialize(root) def initialize(self, root): self.root = root width = 1520 height = 400 self.root.geometry(f"{width}x{height}") self.root.title("START FROM FROM SCRATCH DIGITAL IMAGE PROCESSING WITH TKINTER") #Creates necessary objects self.obj_main_form = Main_Form() self.obj_plot_utils = Plot_Utils() #Places widgets in root self.obj_main_form.add_widgets(self.root) #Binds events self.binds_event() def binds_event(self): self.obj_plot_utils.binds_fundamentals(self.obj_main_form) if __name__ == "__main__": root = tk.Tk() app = Main_Program(root) root.mainloop() #main_form.py import tkinter as tk from tkinter import ttk class Main_Form: def add_widgets(self, root): #Adds menu self.add_menu(root) def add_menu(self, root): self.menu_bar = tk.Menu(root) #Creates a image fundamentals menu self.fundamentals = tk.Menu(self.menu_bar, tearoff=0) self.fundamentals.add_command(label="Color Space") self.fundamentals.add_command(label="Fast Fourier Transform") self.fundamentals.add_command(label="Discrete Cosine Transform") self.fundamentals.add_command(label="Discrete Sine Transform") self.fundamentals.add_command(label="Discrete Wavelet Transform") self.menu_bar.add_cascade(label="Fundamentals", menu=self.fundamentals) root.config(menu=self.menu_bar) #plot_utils.py import matplotlib.pyplot as plt import tkinter as tk from tkinter import * import seaborn as sns import numpy as np import pandas as pd from form_histogram import Form_Histogram from fundamental_utils import Fundamental_Utils class Plot_Utils: def __init__(self): self.fund_utils = Fundamental_Utils() def plot_histogram(self): win = tk.Toplevel() form_hist = Form_Histogram(win) win.title("Histogram of Color Space") def binds_fundamentals(self, window): window.fundamentals.entryconfigure("Color Space", command =lambda:self.plot_histogram()) #fundamental_utils.py import matplotlib.pyplot as plt import tkinter as tk from tkinter import * import seaborn as sns import numpy as np import pandas as pd import tkinter as tk from tkinter import filedialog import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from PIL import Image, ImageTk import colorsys import cv2 class Fundamental_Utils: def __init__(self): pass def open_image(self, ax, figure, canvas): file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.png;*.jpg;*.jpeg;*.gif;*.bmp")]) if file_path: image = Image.open(file_path) photo = ImageTk.PhotoImage(image) ax.imshow(image) ax.axis('off') ax.set_title("RGB Color Space") figure.tight_layout() canvas.draw() return image def extract_rgb(self, image): # Convert the image to a NumPy array image_array = np.array(image) # Separate the channels r_channel = image_array[:, :, 0] g_channel = image_array[:, :, 1] b_channel = image_array[:, :, 2] return r_channel, g_channel, b_channel def histogram_rgb(self, image, range_val): r_channel, g_channel, b_channel = self.extract_rgb(image) # Calculate histograms for each channel r_hist, ch1_bins = np.histogram(r_channel, bins=range_val, range=(0, range_val)) g_hist, ch2_bins = np.histogram(g_channel, bins=range_val, range=(0, range_val)) b_hist, ch3_bins = np.histogram(b_channel, bins=range_val, range=(0, range_val)) return r_hist, g_hist, b_hist def extract_hsv(self, image): img2 = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) img_hsv = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV) # Separate the channels h_channel = img_hsv[:, :, 0] s_channel = img_hsv[:, :, 1] v_channel = img_hsv[:, :, 2] return h_channel, s_channel, v_channel def histogram_hsv(self, image, range_val): h_channel, s_channel, v_channel = self.extract_hsv(image) h_hist, h_bins = np.histogram(h_channel, bins=range_val, range=(0, range_val)) s_hist, s_bins = np.histogram(s_channel, bins=range_val, range=(0, range_val)) v_hist, v_bins = np.histogram(v_channel, bins=range_val, range=(0, range_val)) return h_hist, s_hist, v_hist def extract_yuv(self, image): img_yuv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2YUV) # Separate the channels y_channel = img_yuv[:, :, 0] u_channel = img_yuv[:, :, 1] v_channel = img_yuv[:, :, 2] return y_channel, u_channel, v_channel def histogram_yuv(self, image, range_val): y_channel, u_channel, v_channel = self.extract_yuv(image) y_hist, h_bins = np.histogram(y_channel, bins=range_val, range=(0, range_val)) u_hist, s_bins = np.histogram(u_channel, bins=range_val, range=(0, range_val)) v_hist, v_bins = np.histogram(v_channel, bins=range_val, range=(0, range_val)) return y_hist, u_hist, v_hist def extract_hsl(self, image): img_hsl = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2HLS) # Separate the channels h_channel = img_hsl[:, :, 0] s_channel = img_hsl[:, :, 1] l_channel = img_hsl[:, :, 2] return h_channel, s_channel, l_channel def histogram_hsl(self, image, range_val): h_channel, s_channel, l_channel = self.extract_hsl(image) h_hist, h_bins = np.histogram(h_channel, bins=range_val, range=(0, range_val)) s_hist, s_bins = np.histogram(s_channel, bins=range_val, range=(0, range_val)) l_hist, v_bins = np.histogram(l_channel, bins=range_val, range=(0, range_val)) return h_hist, s_hist, l_hist def show_histogram_bins(self, ch1, ch2, ch3, label1, label2, label3, title, num_bins, ax, figure, canvas): # Plot histograms for each channel ax.bar(range(num_bins), ch1, color='red', alpha=0.5, label=label1) ax.bar(range(num_bins), ch2, color='green', alpha=0.5, label=label2) ax.bar(range(num_bins), ch3, color='blue', alpha=0.5, label=label3) ax.set_title(title) ax.set_xlabel('Pixel Value') ax.set_ylabel('Frequency') ax.grid(True) ax.set_facecolor('#F0F0F0') ax.legend() figure.tight_layout() canvas.draw() def show_histogram_line(self, ch1, ch2, ch3, label1, label2, label3, title, num_bins, ax, figure, canvas): # Plot histograms for each channel ax.plot(range(num_bins), ch1, color='red', alpha=0.75, label=label1) ax.plot(range(num_bins), ch2, color='green', alpha=0.75, label=label2) ax.plot(range(num_bins), ch3, color='blue', alpha=0.75, label=label3) ax.set_title(title) ax.set_xlabel('Pixel Value') ax.set_ylabel('Frequency') ax.grid(True) ax.set_facecolor('#F0F0F0') ax.legend() figure.tight_layout() canvas.draw() def display_hsv_image(self, image, ax, figure, canvas): # Convert to HSV color space img_bgr = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV) # Convert to display format hsv_image = Image.fromarray(img_hsv) # Display the image on the canvas ax.imshow(hsv_image) ax.axis('off') ax.set_title("HSV Color Space") figure.tight_layout() canvas.draw() def display_yuv_image(self, image, ax, figure, canvas): # Convert to YUV color space img_bgr = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) img_yuv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YUV) # Convert to display format yuv_image = Image.fromarray(img_yuv) # Display the image on the canvas ax.imshow(yuv_image) ax.axis('off') ax.set_title("YUV Color Space") figure.tight_layout() canvas.draw() def display_hsl_image(self, image, ax, figure, canvas): # Convert to RGB color space (if not already in RGB) img_rgb = cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB) # Convert to HSL color space img_hsl = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HLS) # Convert to display format hsl_image = Image.fromarray(img_hsl) # Display the image on the canvas ax.imshow(hsl_image) ax.axis('off') ax.set_title("HSL Color Space") figure.tight_layout() canvas.draw() def plot_each_channel(self, ch, title, ax, cmap, figure, canvas): # Convert to display format ret_im = Image.fromarray(ch) # Display the image on the canvas ax.imshow(ret_im, cmap=cmap) ax.axis('off') ax.set_title(title) figure.tight_layout() canvas.draw() #form_histogram.py import tkinter as tk from tkinter import ttk from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from fundamental_utils import Fundamental_Utils from form_channel import Form_Channel class Form_Histogram: def __init__(self, window): self.window = window width = 1520 height = 770 self.window.geometry(f"{width}x{height}") #Adds label widgets self.add_utilities(self.window) #Adds canvasses self.add_canvas(self.window) #Creates necessary objects self.fund_utils = Fundamental_Utils() #Initial value self.image = None #Binds events self.binds_event() def add_labels(self, master): # Create two labels self.label1 = tk.Label(master, text="MAX INTENSITY") self.label1.grid(row=1, column=0, padx=5, pady=5, sticky="w") self.label2 = tk.Label(master, text="COLOR SPACE") self.label2.grid(row=3, column=0, padx=5, pady=5, sticky="w") def add_button(self, master): #Adds button self.btn1 = tk.Button(master, height=2, width=17, text="CHOOSE IMAGE", command=lambda:self.show_rgb_image()) self.btn1.grid(row=0, column=0, padx=5, pady=5, sticky="w") def add_entries(self, master): # Create entry widgets self.num_bins = tk.Entry(master, width=20, bg="cyan") self.num_bins.grid(row=2, column=0, padx=5, pady=5, sticky="w") self.num_bins.insert(0, "256") self.num_bins.bind('<Return>', self.choose_color_space) def add_combobox(self, root): # Create ComboBoxes self.combo_space = ttk.Combobox(root, width=20) self.combo_space["values"] = ["RGB", "HSV", "YUV", "HSL"] self.combo_space.grid(row=4, column=0, padx=5, pady=5, sticky="w") def add_utilities(self, master): # Create a frame for canvas1 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=0, padx=5, pady=10, sticky="n") self.add_button(frame1) self.add_labels(frame1) self.add_entries(frame1) self.add_combobox(frame1) def add_canvas(self, master): # Create a frame for canvas1 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=1, padx=5, pady=5, sticky="n") # Adds canvas1 widget to frame1 self.figure1 = Figure(figsize=(3.7, 3.7), dpi=100) self.figure1.patch.set_facecolor('#F0F0F0') self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1) self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True) # Create a frame for canvas2 with a border frame2 = ttk.Frame(master, borderwidth=3, relief="groove") frame2.grid(row=1, column=1, padx=5, pady=5, sticky="n") # Adds canvas2 widget to frame2 self.figure2 = Figure(figsize=(3.7, 3.7), dpi=100) self.figure2.patch.set_facecolor('#F0F0F0') self.canvas2 = FigureCanvasTkAgg(self.figure2, master=frame2) self.canvas2.get_tk_widget().pack(fill=tk.BOTH, expand=True) # Create a frame for canvas3 with a border frame3 = ttk.Frame(master, borderwidth=3, relief="groove") frame3.grid(row=0, column=2, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n") # Adds canvas3 widget to frame3 self.figure3 = Figure(figsize=(9.5, 7.55), dpi=100) self.figure3.patch.set_facecolor('#F0F0F0') self.canvas3 = FigureCanvasTkAgg(self.figure3, master=frame3) self.canvas3.get_tk_widget().pack(fill=tk.BOTH, expand=True) def show_rgb_image(self): # Create figure and subplot self.figure1.clear() ax1 = self.figure1.add_subplot(1, 1, 1) self.image = self.fund_utils.open_image(ax1, self.figure1, self.canvas1) #Plot histogram of RGB channel self.plot_rgb_histogram() def read_and_check_input(self, bins): try: num_bins = int(bins) except ValueError: num_bins = 256 self.num_bins.delete(0, tk.END) self.num_bins.insert(0, "256") return num_bins def plot_rgb_histogram(self): #Reads param bins = self.num_bins.get() num_bins = self.read_and_check_input(bins) #Extract histogram of RGB channel r_channel, g_channel, b_channel = self.fund_utils.histogram_rgb(self.image, num_bins) # Create figure and subplot self.figure3.clear() ax1 = self.figure3.add_subplot(2, 1, 1) ax2 = self.figure3.add_subplot(2, 1, 2) self.fund_utils.show_histogram_bins(r_channel, g_channel, b_channel, "Red", "Green", "Blue", "Histogram of RGB Channel", num_bins, ax1, self.figure3, self.canvas3) self.fund_utils.show_histogram_line(r_channel, g_channel, b_channel, "Red", "Green", "Blue", "Histogram of RGB Channel", num_bins, ax2, self.figure3, self.canvas3) def plot_rgb_channel(self): win = tk.Toplevel() form_ch = Form_Channel(win) win.title("Each Channel of RGB Color Space") form_ch.figure1.clear() ax1 = form_ch.figure1.add_subplot(1, 3, 1) ax2 = form_ch.figure1.add_subplot(1, 3, 2) ax3 = form_ch.figure1.add_subplot(1, 3, 3) r_channel, g_channel, b_channel = self.fund_utils.extract_rgb(self.image) self.fund_utils.plot_each_channel(r_channel, "Red Channel", ax1, 'Reds', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(g_channel, "Green Channel", ax2, 'Greens', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(b_channel, "Blue Channel", ax3, 'Blues', form_ch.figure1, form_ch.canvas1) def plot_hsv_histogram(self): #Reads param bins = self.num_bins.get() num_bins = self.read_and_check_input(bins) #Extract histogram of HSV channel h_channel, s_channel, v_channel = self.fund_utils.histogram_hsv(self.image, num_bins) # Create figure and subplot self.figure3.clear() ax1 = self.figure3.add_subplot(2, 1, 1) ax2 = self.figure3.add_subplot(2, 1, 2) self.fund_utils.show_histogram_bins(h_channel, s_channel, v_channel, "Hue", "Saturation", "Value", "Histogram of HSV Channel", num_bins, ax1, self.figure3, self.canvas3) self.fund_utils.show_histogram_line(h_channel, s_channel, v_channel, "Hue", "Saturation", "Value", "Histogram of HSV Channel", num_bins, ax2, self.figure3, self.canvas3) def plot_hsv_channel(self): win = tk.Toplevel() form_ch = Form_Channel(win) win.title("Each Channel of HSV Color Space") form_ch.figure1.clear() ax1 = form_ch.figure1.add_subplot(1, 3, 1) ax2 = form_ch.figure1.add_subplot(1, 3, 2) ax3 = form_ch.figure1.add_subplot(1, 3, 3) h_channel, s_channel, v_channel = self.fund_utils.extract_hsv(self.image) self.fund_utils.plot_each_channel(h_channel, "Hue Channel", ax1, 'Reds', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(s_channel, "Saturation Channel", ax2, 'Greens', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(v_channel, "Value Channel", ax3, 'Blues', form_ch.figure1, form_ch.canvas1) def plot_hsl_histogram(self): #Reads param bins = self.num_bins.get() num_bins = self.read_and_check_input(bins) #Extract histogram of HSL channel h_channel, s_channel, l_channel = self.fund_utils.histogram_hsl(self.image, num_bins) # Create figure and subplot self.figure3.clear() ax1 = self.figure3.add_subplot(2, 1, 1) ax2 = self.figure3.add_subplot(2, 1, 2) self.fund_utils.show_histogram_bins(h_channel, s_channel, l_channel, "Hue", "Saturation", "Lightness", "Histogram of HSL Channel", num_bins, ax1, self.figure3, self.canvas3) self.fund_utils.show_histogram_line(h_channel, s_channel, l_channel, "Hue", "Saturation", "Lightness", "Histogram of HSL Channel", num_bins, ax2, self.figure3, self.canvas3) def plot_hsl_channel(self): win = tk.Toplevel() form_ch = Form_Channel(win) win.title("Each Channel of HSL Color Space") form_ch.figure1.clear() ax1 = form_ch.figure1.add_subplot(1, 3, 1) ax2 = form_ch.figure1.add_subplot(1, 3, 2) ax3 = form_ch.figure1.add_subplot(1, 3, 3) h_channel, s_channel, l_channel = self.fund_utils.extract_hsl(self.image) self.fund_utils.plot_each_channel(h_channel, "Hue Channel", ax1, 'Reds', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(s_channel, "Saturation Channel", ax2, 'Greens', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(l_channel, "Lightness Channel", ax3, 'Blues', form_ch.figure1, form_ch.canvas1) def plot_yuv_histogram(self): #Reads param bins = self.num_bins.get() num_bins = self.read_and_check_input(bins) #Extract histogram of YUV channel y_channel, u_channel, v_channel = self.fund_utils.histogram_yuv(self.image, num_bins) # Create figure and subplot self.figure3.clear() ax1 = self.figure3.add_subplot(2, 1, 1) ax2 = self.figure3.add_subplot(2, 1, 2) self.fund_utils.show_histogram_bins(y_channel, u_channel, v_channel, "Y (Luma)", "U (Chrominance Blue)", "V (Chrominance Red)", "Histogram of YUV Channel", num_bins, ax1, self.figure3, self.canvas3) self.fund_utils.show_histogram_line(y_channel, u_channel, v_channel, "Y (Luma)", "U (Chrominance Blue)", "V (Chrominance Red)", "Histogram of YUV Channel", num_bins, ax2, self.figure3, self.canvas3) def plot_yuv_channel(self): win = tk.Toplevel() form_ch = Form_Channel(win) win.title("Each Channel of YUV Color Space") form_ch.figure1.clear() ax1 = form_ch.figure1.add_subplot(1, 3, 1) ax2 = form_ch.figure1.add_subplot(1, 3, 2) ax3 = form_ch.figure1.add_subplot(1, 3, 3) y_channel, u_channel, v_channel = self.fund_utils.extract_yuv(self.image) self.fund_utils.plot_each_channel(y_channel, "Y (Luma) Channel", ax1, 'Greens', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(u_channel, "U (Chrominance Blue)", ax2, 'Blues', form_ch.figure1, form_ch.canvas1) self.fund_utils.plot_each_channel(v_channel, "V (Chrominance Red)", ax3, 'Reds', form_ch.figure1, form_ch.canvas1) def choose_color_space(self, event): #Reads color space self.chosen_space = self.combo_space.get() if self.chosen_space == "RGB": self.plot_rgb_histogram() self.plot_rgb_channel() if self.chosen_space == "HSV": self.figure2.clear() ax = self.figure2.add_subplot(1, 1, 1) self.fund_utils.display_hsv_image(self.image, ax, self.figure2, self.canvas2) self.plot_hsv_histogram() self.plot_hsv_channel() if self.chosen_space == "YUV": self.figure2.clear() ax = self.figure2.add_subplot(1, 1, 1) self.fund_utils.display_yuv_image(self.image, ax, self.figure2, self.canvas2) self.plot_yuv_histogram() self.plot_yuv_channel() if self.chosen_space == "HSL": self.figure2.clear() ax = self.figure2.add_subplot(1, 1, 1) self.fund_utils.display_hsl_image(self.image, ax, self.figure2, self.canvas2) self.plot_hsl_histogram() self.plot_hsl_channel() def binds_event(self): # Binds combo_wavelet to choose_wavelet() self.combo_space.bind("<<ComboboxSelected>>", self.choose_color_space) if __name__ == "__main__": window = tk.Tk() Form_Histogram(window) window.mainloop() #form_channel.py import tkinter as tk from tkinter import ttk from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg class Form_Channel: def __init__(self, window): self.window = window width = 1500 height = 540 self.window.geometry(f"{width}x{height}") #Adds canvas self.add_canvas(self.window) def add_canvas(self, master): # Create a frame for canvas3 with a border frame1 = ttk.Frame(master, borderwidth=3, relief="groove") frame1.grid(row=0, column=0, columnspan=1, rowspan=25, padx=5, pady=5, sticky="n") # Adds canvas1 widget to frame1 self.figure1 = Figure(figsize=(14.7, 5), dpi=100) self.figure1.patch.set_facecolor('#F0F0F0') self.canvas1 = FigureCanvasTkAgg(self.figure1, master=frame1) self.canvas1.get_tk_widget().pack(fill=tk.BOTH, expand=True) if __name__ == "__main__": window = tk.Tk() Form_Channel(window) window.mainloop()