123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- from PIL import Image, ImageTk
- import PIL
- import tkinter as tk
- from tkinter import filedialog, messagebox
- import cv2
- import numpy as np
-
- root = tk.Tk()
- simGrad = tk.IntVar(root)
-
- class Dyschromasie:
- cb_image = np.array([]).astype('float64')
- sim_image = np.array([]).astype('uint8')
-
- def __init__(self, img_mat=np.array([]), rows=0, cols=0, kanaele=0,sim_faktor=0):
- self.rows = rows
- self.cols = cols
- self.kanaele = kanaele
- self.img_mat = img_mat
- self.sim_faktor = sim_faktor
-
- T = np.array([[0.31399022, 0.63951294, 0.04649755],
- [0.15537241, 0.75789446, 0.08670142],
- [0.01775239, 0.10944209, 0.87256922]])
-
- T_reversed = np.array([[5.47221206, -4.6419601, 0.16963708],
- [-1.1252419, 2.29317094, -0.1678952],
- [0.02980165, -0.19318073, 1.16364789]])
-
- def gammaCorrection(self, v):
- if v <= 0.04045 * 255:
- return float(((v / 255) / 12.92))
- elif v > 0.04045 * 255:
- return float((((v / 255) + 0.055) / 1.055) ** 2.4)
-
- def reverseGammaCorrection(self, v_reverse):
- if v_reverse <= 0.0031308:
- return int(255 * (12.92 * v_reverse))
- elif v_reverse > 0.0031308:
- return int(255 * (1.055 * v_reverse ** 0.41666 - 0.055))
-
-
- class Protanopie(Dyschromasie):
- def Simulate(self):
-
- sim_mat = np.array([[(1 - self.sim_faktor), 1.05118294 * self.sim_faktor, -0.05116099 * self.sim_faktor],
- [0, 1, 0],
- [0, 0, 1]])
-
- # Gammakorrektur durchfuehren
- self.cb_image = np.copy(self.img_mat).astype('float64')
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
-
- # Einzelne Pixelwertberechnung
- for i in range(self.rows):
- for j in range(self.cols):
- self.cb_image[i, j] = np.flipud(
- self.T_reversed.dot(sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
-
- self.sim_image = np.copy(self.cb_image)
- self.sim_image = self.sim_image.astype('uint8')
-
- # Rücktransformation der Gammawerte
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
-
- return self.sim_image
-
-
- class Deuteranopie(Dyschromasie):
- def Simulate(self):
-
- sim_mat = np.array([[1, 0, 0],
- [0.9513092 * self.sim_faktor, (1 - self.sim_faktor), 0.04866992 * self.sim_faktor],
- [0, 0, 1]])
-
- # Gammakorrektur durchfuehren
- self.cb_image = np.copy(self.img_mat).astype('float64')
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
-
- # Einzelne Pixelwertberechnung
- for i in range(self.rows):
- for j in range(self.cols):
- self.cb_image[i, j] = np.flipud(
- self.T_reversed.dot(sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
-
- self.sim_image = np.copy(self.cb_image)
- self.sim_image = self.sim_image.astype('uint8')
-
- # Rücktransformation der Gammawerte
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
-
- return self.sim_image
-
-
- class Tritanopie(Dyschromasie):
- def Simulate(self):
-
- sim_mat = np.array([[1, 0, 0],
- [0, 1, 0],
- [-0.86744736 * self.sim_faktor, 1.86727089 * self.sim_faktor, (1 - self.sim_faktor)]])
-
- # Gammakorrektur durchfuehren
- self.cb_image = np.copy(self.img_mat).astype('float64')
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
-
- # Einzelne Pixelwertberechnung
- for i in range(self.rows):
- for j in range(self.cols):
- self.cb_image[i, j] = np.flipud(
- self.T_reversed.dot(sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
-
- self.sim_image = np.copy(self.cb_image)
- self.sim_image = self.sim_image.astype('uint8')
-
- # Rücktransformation der Gammawerte
- for i in range(self.rows):
- for j in range(self.cols):
- for x in range(3):
- self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
-
- return self.sim_image
-
- class AutoScrollbar(tk.Scrollbar):
- # A scrollbar that hides itself if it's not needed.
- # Only works if you use the grid geometry manager!
- def set(self, lo, hi):
- if float(lo) <= 0.0 and float(hi) >= 1.0:
- # grid_remove is currently missing from Tkinter!
- self.tk.call("grid", "remove", self)
- else:
- self.grid()
- tk.Scrollbar.set(self, lo, hi)
- def pack(self, **kw):
- raise TclError("cannot use pack with this widget")
- def place(self, **kw):
- raise TclError("cannot use place with this widget")
-
- class ScrollFrame:
- def __init__(self, master):
-
- self.vscrollbar = AutoScrollbar(master)
- self.vscrollbar.grid(row=0, column=1, sticky='ns')
- self.hscrollbar = AutoScrollbar(master, orient='horizontal')
- self.hscrollbar.grid(row=1, column=0, sticky='ew')
-
- self.canvas = tk.Canvas(master, yscrollcommand=self.vscrollbar.set,
- xscrollcommand=self.hscrollbar.set)
- self.canvas.grid(row=0, column=0, sticky='nsew')
-
- self.vscrollbar.config(command=self.canvas.yview)
- self.hscrollbar.config(command=self.canvas.xview)
-
- # make the canvas expandable
- master.grid_rowconfigure(0, weight=1)
- master.grid_columnconfigure(0, weight=1)
-
- # create frame inside canvas
- self.frame = tk.Frame(self.canvas)
- self.frame.rowconfigure(1, weight=1)
- self.frame.columnconfigure(1, weight=1)
-
- # update the frame
- self.frame.bind("<Configure>", self.reset_scrollregion)
-
- def reset_scrollregion(self, event):
- self.canvas.configure(scrollregion=self.canvas.bbox('all'))
-
- def update(self):
- self.canvas.create_window(0, 0, anchor='nw', window=self.frame)
- self.frame.update_idletasks()
- self.canvas.config(scrollregion=self.canvas.bbox("all"))
-
- if self.frame.winfo_reqwidth() != self.canvas.winfo_width():
- # update the canvas's width to fit the inner frame
- self.canvas.config(width = self.frame.winfo_reqwidth())
- if self.frame.winfo_reqheight() != self.canvas.winfo_height():
- # update the canvas's width to fit the inner frame
- self.canvas.config(height = self.frame.winfo_reqheight())
-
-
- root.title("Projekt Dyschromasie")
-
- SB = ScrollFrame(root)
-
- img = np.array([])
- rows = 0
- cols = 0
- kanaele = 0
-
- sim_pro = tk.IntVar(root)
- sim_deut = tk.IntVar(root)
- sim_tri = tk.IntVar(root)
-
- simulationsGradient = tk.Scale(SB.frame, from_=0, to_=100, variable=simGrad, orient='horizontal')
- simulationsGradient.grid(column= 0, row = 1, columnspan=10)
-
- def browse():
- # Auswahl des FilePaths
- try:
- path = tk.filedialog.askopenfilename(filetypes=[("Image File", '.jpg')])
- im = Image.open(path)
- except:
- tk.messagebox.showerror(title='Datenfehler', message='Kein Bild gefunden/ausgewählt')
- global simulateButton
- if len(path) > 0:
- simulateButton.config(state='active')
-
- # Anzeigen des Bildes
- tkimage = ImageTk.PhotoImage(im)
- myvar = tk.Label(SB.frame, image=tkimage)
- myvar.image = tkimage
- myvar.grid(columnspan=5)
-
- # Einspeichern der Path-Informationen
- global img, rows, cols, kanaele
- img = cv2.imread(path)
- rows, cols, kanaele = img.shape
-
-
- def simulate():
- global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
- if sim_deut.get():
- d = Deuteranopie(img, rows, cols, kanaele, simGrad.get()/100)
- display_array_deut = cv2.cvtColor(np.copy(d.Simulate()), cv2.COLOR_BGR2RGB)
-
- T = tk.Text(SB.frame, height=1, width=15)
- T.grid(columnspan=5)
- T.insert('current', "Deutranopie:")
-
- conv_SimulationPic_deut = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_deut))
- sim_pic_deut = tk.Label(SB.frame, image=conv_SimulationPic_deut)
- sim_pic_deut.Image = conv_SimulationPic_deut
- sim_pic_deut.grid(columnspan=5)
- elif sim_tri.get():
- t = Tritanopie(img, rows, cols, kanaele, simGrad.get()/100)
- display_array_tri = cv2.cvtColor(np.copy(t.Simulate()), cv2.COLOR_BGR2RGB)
-
- T = tk.Text(SB.frame, height=1, width=15)
- T.grid(columnspan=5)
- T.insert('current', "Tritanopie:")
-
- conv_SimulationPic_tri = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_tri))
- sim_pic_tri = tk.Label(SB.frame, image=conv_SimulationPic_tri)
- sim_pic_tri.Image = conv_SimulationPic_tri
- sim_pic_tri.grid(columnspan=5)
- elif sim_pro.get():
- p = Protanopie(img, rows, cols, kanaele, simGrad.get()/100)
- display_array_pro = cv2.cvtColor(np.copy(p.Simulate()), cv2.COLOR_BGR2RGB)
-
- T = tk.Text(SB.frame, height=1, width=15)
- T.grid(columnspan=5)
- T.insert('current', "Protanopie:")
-
- conv_SimulationPic_pro = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_pro))
- sim_pic_pro = tk.Label(SB.frame, image=conv_SimulationPic_pro)
- sim_pic_pro.Image = conv_SimulationPic_pro
- sim_pic_pro.grid(columnspan=5)
-
-
- btn = tk.Button(SB.frame, text="Browse", width=25, command=browse, bg='light blue')
- btn.grid(column=0, row=0, columnspan=2)
-
- simulateButton = tk.Button(SB.frame, text="Simulate", width=25, command=simulate, bg='light blue')
- simulateButton.grid(column=1, row=0, columnspan=2)
- simulateButton.config(state='disabled')
-
- checkButton_p = tk.Checkbutton(SB.frame, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20)
- checkButton_d = tk.Checkbutton(SB.frame, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20)
- checkButton_t = tk.Checkbutton(SB.frame, text="Tritanop", variable=sim_tri, onvalue=1, offvalue=0, height=5, width=20)
-
- checkButton_p.grid(column=0, row=2)
- checkButton_d.grid(column=1, row=2)
- checkButton_t.grid(column=2, row=2)
-
- SB.update()
- root.mainloop()
|