From 3ee51d0be4412210836e0da3886eb495b917dfdc Mon Sep 17 00:00:00 2001 From: Maximilian Sponsel Date: Fri, 21 Aug 2020 09:23:03 +0000 Subject: [PATCH] Applikation zur Simulation der verschiedenen Fehlsichtigkeiten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nachdem nun die Theorie hinter der Simulation geklärt ist, wenden wir uns jetzt dem Applikationbau zu. --- Code/Dyschromasie-Applikation.py | 219 +++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 Code/Dyschromasie-Applikation.py diff --git a/Code/Dyschromasie-Applikation.py b/Code/Dyschromasie-Applikation.py new file mode 100644 index 0000000..8332eae --- /dev/null +++ b/Code/Dyschromasie-Applikation.py @@ -0,0 +1,219 @@ +from PIL import Image, ImageTk +import PIL +import tkinter as tk +from tkinter import filedialog, messagebox +import cv2 +import numpy as np + + +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): + self.rows = rows + self.cols = cols + self.kanaele = kanaele + self.img_mat = img_mat + + 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): + sim_mat = np.array([[0, 1.05118294, -0.05116099], + [0, 1, 0], + [0, 0, 1]]) + + def Simulate(self): + # 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(self.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): + sim_mat = np.array([[1, 0, 0], + [0.9513092, 0, 0.04866992], + [0, 0, 1]]) + + def Simulate(self): + # 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(self.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): + sim_mat = np.array([[1, 0, 0], + [0, 1, 0], + [-0.86744736, 1.86727089, 0]]) + + def Simulate(self): + # 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(self.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 + +root = tk.Tk() +root.title("Projekt Dyschromasie") + +img = np.array([]) +rows = 0 +cols = 0 +kanaele = 0 + +sim_pro = tk.IntVar(root) +sim_deut = tk.IntVar(root) +sim_tri = tk.IntVar(root) + +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(root, 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) + display_array_deut = cv2.cvtColor(np.copy(d.Simulate()), cv2.COLOR_BGR2RGB) + + T = tk.Text(root,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(root, 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) + display_array_tri = cv2.cvtColor(np.copy(t.Simulate()), cv2.COLOR_BGR2RGB) + + T = tk.Text(root, 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(root, 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) + display_array_pro = cv2.cvtColor(np.copy(p.Simulate()), cv2.COLOR_BGR2RGB) + + T = tk.Text(root, 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(root, image=conv_SimulationPic_pro) + sim_pic_pro.Image = conv_SimulationPic_pro + sim_pic_pro.grid(columnspan=5) + + + +btn = tk.Button(root, text="Browse", width=25, command=browse, bg='light blue') +btn.grid(column = 0, row = 0,columnspan=2) + +simulateButton = tk.Button(root, 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(root, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20) +checkButton_d = tk.Checkbutton(root, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20) +checkButton_t = tk.Checkbutton(root, text="Tritanop", variable=sim_tri, onvalue=1, offvalue=0, height=5, width=20) + +checkButton_p.grid(column = 0, row = 1) +checkButton_d.grid(column = 1, row = 1) +checkButton_t.grid(column = 2, row = 1) + +root.mainloop()