Compare commits

..
13 Commits
Author SHA1 Message Date
Max Sponsel 1be205389b Kleine Anpassungen 2020-09-21 10:58:20 +02:00
Max Sponsel a206147edf Dalt Algorithmus und Auslagern des Displays
Der Dalt Algorithmus wird nun von dem Dalt-Button ausgeführt. Gleichzeitig wurde die Funktion showImage geschrieben, um Code zu verschlanken und lediglich die Switchfunktionen simulate und daltonize für die Auswahl der Simulationsart zu nutzen.
PS: Mehrere Bilder zum Testen eingefügt
2020-09-19 10:44:07 +02:00
Max Sponsel 137ca981f2 Einfügen eines Dalt-Buttons in die GUI
Zum Aufrufen des Algorithmus in der GUI muss ein Button Objekt der tkinter Klasse erstellt werden. Dieses wird erst nach einem erfolgreich ausgewählten Bild aktiv! Als nächstes steht die Implementation der daltonize-Funktion an, die durch command='daltonize' ausgeführt wird.
2020-09-18 11:40:40 +02:00
Max Sponsel 8498500c68 Daltonization in die Klasse eingefügt
Funktion der Daltonization in die Klasse Dyschromasie eingefügt.
2020-09-18 10:58:28 +02:00
Max Sponsel 638fadeb28 Angepasster Daltonizationalgorithmus
https://github.com/indranilsinharoy/daltonization/blob/master/daltonize.py

Implementierung des gezeigten Algorithmus. Wichtig ist die Int64 Konvertierung , um Überläufe zu verhindern.
2020-09-17 12:23:02 +02:00
Max Sponsel b78f3c2908 Erster Daltonizationalgorithmus 2020-09-17 11:41:00 +02:00
Max Sponsel 804bc74885 Lookup-Table für die Entfrenung der Gamma Korrektur implementiert
Zur Besseren Performance wird eine Lookup Table benötigt. Diese gleicht dynamisch alles Werte ab anstatt bei jedem einzelnen Pixelwert die Berechnung durchzuführen.
2020-09-15 11:51:22 +02:00
Max Sponsel 105b6689b8 Gaussian Blur entfernt 2020-09-14 10:42:36 +02:00
Max Sponsel 250cf3fd32 Import angepasst 2020-09-14 10:22:52 +02:00
Max Sponsel fd0161e320 Genauere Berechnung der Oberen Werte
Änderung des Return-Wertes auf 255 - dem Delta zwischen Übersteuerung und dem Maximialwert zur besseren Farbdarstellung
2020-09-14 10:21:33 +02:00
Max Sponsel 1cc63c6a30 Entfernen der Print Befehle für's Debugging 2020-09-13 12:56:46 +02:00
Max Sponsel 0795db1f96 Merge remote-tracking branch 'origin/master' 2020-09-13 12:53:51 +02:00
Max Sponsel 31ed0825c3 Weitere Anpassungen für Tritanopie
Anders als bei den anderen Fehlsichtigkeiten ist ein Überlauf des Wertebereichs möglich. Somit werden Werte, die 255 überschreiten standardmäßig auf diesen Maximalwert gesetzt.
2020-09-13 12:53:35 +02:00
7 changed files with 107 additions and 59 deletions

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+43 -40
View File
@@ -1,10 +1,9 @@
from PIL import Image, ImageTk
import PIL
import tkinter as tk
from tkinter import filedialog, messagebox
import cv2
import numpy as np
from Farbaenderung import gammaCorrection, reverseGammaCorrection, Dyschromasie
from Farbaenderung import Dyschromasie
from Scrollbar import ScrollFrame
root = tk.Tk()
@@ -26,6 +25,7 @@ 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:
@@ -36,6 +36,7 @@ def browse():
global simulateButton
if len(path) > 0:
simulateButton.config(state='active')
daltonButton.config(state='active')
# Anzeigen des Bildes
tkimage = ImageTk.PhotoImage(im)
@@ -47,60 +48,62 @@ def browse():
global img, rows, cols, kanaele
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#img = cv2.GaussianBlur(img, (3, 3), 0)
rows, cols, kanaele = img.shape
def showImage(img, rows, cols, kanaele, sim_faktor, sim_kind, sim_art):
color_blindness = Dyschromasie(img, rows, cols, kanaele, sim_faktor, sim_kind)
if sim_art == 'Sim':
color_blindness_mat = np.copy(color_blindness.Simulate()).astype('uint8')
else:
color_blindness_mat = np.copy(color_blindness.daltonize()).astype('uint8')
T = tk.Text(SB.frame, height=1, width=15)
T.grid(columnspan=5)
print_string = sim_kind + ' ' + str(round(color_blindness.sim_faktor * 100)) + "%"
T.insert('current', print_string)
conv_SimulationPic = ImageTk.PhotoImage(image=PIL.Image.fromarray(color_blindness_mat))
sim_pic = tk.Label(SB.frame, image=conv_SimulationPic)
sim_pic.Image = conv_SimulationPic
sim_pic.grid(columnspan=5)
def simulate():
global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
if sim_deut.get():
d = Dyschromasie(img, rows, cols, kanaele, simGrad.get()/100, 'd')
display_array_deut = np.copy(d.Simulate()).astype('uint8')
showImage(img, rows, cols, kanaele, simGrad.get()/100, 'Deuteranop', 'Sim')
T = tk.Text(SB.frame, height=1, width=15)
T.grid(columnspan=5)
print_string = "Deutranop(" + str(round(d.sim_faktor*100)) + "%)"
T.insert('current', print_string)
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 = Dyschromasie(img, rows, cols, kanaele, simGrad.get()/100, 't')
display_array_tri = np.copy(t.Simulate()).astype('uint8')
showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Tritanop', 'Sim')
T = tk.Text(SB.frame, height=1, width=15)
T.grid(columnspan=5)
print_string = "Tritanop(" + str(round(t.sim_faktor * 100)) + "%)"
T.insert('current', print_string)
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 = Dyschromasie(img, rows, cols, kanaele, simGrad.get()/100, 'p')
display_array_pro = np.copy(p.Simulate()).astype('uint8')
T = tk.Text(SB.frame, height=1, width=15)
T.grid(columnspan=5)
print_string = "Protanop(" + str(round(p.sim_faktor * 100)) + "%)"
T.insert('current', print_string)
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)
showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Protanop', 'Sim')
btn = tk.Button(SB.frame, text="Browse", width=25, command=browse, bg='light blue')
btn.grid(column=0, row=0, columnspan=2)
def daltonize():
global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
if sim_deut.get():
showImage(img, rows, cols, kanaele, simGrad.get()/100, 'Deuteranop', 'Dalt')
elif sim_tri.get():
showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Tritanop', 'Dalt')
elif sim_pro.get():
showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Protanop', 'Dalt')
browseButton = tk.Button(SB.frame, text="Browse", width=25, command=browse, bg='light blue')
browseButton.grid(column=0, row=0, columnspan=1)
simulateButton = tk.Button(SB.frame, text="Simulate", width=25, command=simulate, bg='light blue')
simulateButton.grid(column=1, row=0, columnspan=2)
simulateButton.grid(column=1, row=0, columnspan=1)
simulateButton.config(state='disabled')
daltonButton = tk.Button(SB.frame, text="Daltonize", width=25, command=daltonize, bg='light blue')
daltonButton.grid(column=2, row=0, columnspan=1)
daltonButton.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)
+64 -19
View File
@@ -2,28 +2,36 @@ import numpy as np
import cv2
def gammaCorrection(v):
def createGammaLookup():
return np.array([removeGammaCorrection(i) for i in np.arange(0, 256)]).astype("float64")
def createReverseGammaLookup():
return np.array([applyGammaCorrection(i / 255) for i in np.arange(0.0, 256.0)]).astype("uint8")
def removeGammaCorrection(v):
if v <= 0.04045 * 255:
return (v / 255) / 12.92
elif v > 0.04045 * 255:
return (((v / 255) + 0.055) / 1.055) ** 2.4
def reverseGammaCorrection(v_reverse):
def applyGammaCorrection(v_reverse):
if abs(v_reverse) <= 0.0031308:
return round(255 * (12.92 * abs(v_reverse)))
elif abs(v_reverse) > 0.0031308:
else:
if (round(255 * (1.055 * abs(v_reverse) ** 0.41666 - 0.055))) > 255:
return 255
return 255 - (round(255 * (1.055 * abs(v_reverse) ** 0.41666 - 0.055)) - 255)
else:
return round(255 * (1.055 * abs(v_reverse) ** 0.41666 - 0.055))
class Dyschromasie:
cb_image = np.array([]).astype('float64')
sim_image = np.array([]).astype('uint8')
sim_image = np.array([]).astype('int64')
def __init__(self, img_mat=np.array([]), rows=0, cols=0, kanaele=0, sim_faktor=0, sim_kind='d'):
def __init__(self, img_mat=np.array([]), rows=0, cols=0, kanaele=0, sim_faktor=0, sim_kind='Deuteranop'):
self.rows = rows
self.cols = cols
self.kanaele = kanaele
@@ -40,15 +48,17 @@ class Dyschromasie:
[0.02980165, -0.19318073, 1.16364789]])
def Simulate(self):
if self.sim_kind == 'p':
removeGammaCorrectionLUT = createGammaLookup()
if self.sim_kind == 'Protanop':
sim_mat = np.array([[(1 - self.sim_faktor), 1.05118294 * self.sim_faktor, -0.05116099 * self.sim_faktor],
[0, 1, 0],
[0, 0, 1]])
elif self.sim_kind == 'd':
elif self.sim_kind == 'Deuteranop':
sim_mat = np.array([[1, 0, 0],
[0.9513092 * self.sim_faktor, (1 - self.sim_faktor), 0.04866992 * self.sim_faktor],
[0, 0, 1]])
else:
elif self.sim_kind == 'Tritanop':
sim_mat = np.array([[1, 0, 0],
[0, 1, 0],
[-0.86744736 * self.sim_faktor, 1.86727089 * self.sim_faktor, (1 - self.sim_faktor)]])
@@ -56,26 +66,61 @@ class Dyschromasie:
# 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] = gammaCorrection(self.img_mat[i, j, x])
self.cb_image = cv2.LUT(self.img_mat, removeGammaCorrectionLUT)
rechen_Mat = np.copy(self.T_reversed.dot(sim_mat).dot(self.T))
print(rechen_Mat)
# Einzelne Pixelwertberechnung
for i in range(self.rows):
for j in range(self.cols):
self.cb_image[i, j] = rechen_Mat.dot(self.cb_image[i, j])
self.sim_image = np.copy(self.cb_image)
self.sim_image = self.sim_image.astype('uint8')
self.sim_image = self.sim_image.astype('int64')
# 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] = reverseGammaCorrection(self.cb_image[i, j, x])
self.sim_image[i, j, x] = applyGammaCorrection(self.cb_image[i, j, x])
return self.sim_image.astype('uint8')
def daltonize(self):
err2mod = np.array([[0, 0, 0], [0.7, 1, 0], [0.7, 0, 1]])
simulated_image = self.Simulate()
E = np.copy(simulated_image).astype('int32')
for i in range(self.rows):
for j in range(self.cols):
for x in range(3):
E[i, j, x] = abs(int(self.img_mat[i, j, x]) - int(simulated_image[i, j, x]))
ERR = np.zeros_like(self.img_mat).astype('int32')
for i in range(self.rows):
for j in range(self.cols):
err = E[i, j, :3]
ERR[i, j, :3] = np.dot(err2mod, err)
dtpn = np.copy(self.img_mat).astype('int32')
for i in range(self.rows):
for j in range(self.cols):
for x in range(3):
dtpn[i, j, x] = abs(int(ERR[i, j, x]) + int(self.img_mat[i, j, x]))
for i in range(self.rows):
for j in range(self.cols):
dtpn[i, j, 0] = max(0, dtpn[i, j, 0])
dtpn[i, j, 0] = min(255, dtpn[i, j, 0])
dtpn[i, j, 1] = max(0, dtpn[i, j, 1])
dtpn[i, j, 1] = min(255, dtpn[i, j, 1])
dtpn[i, j, 2] = max(0, dtpn[i, j, 2])
dtpn[i, j, 2] = min(255, dtpn[i, j, 2])
result = dtpn.astype('uint8')
dalt = Dyschromasie(result, self.rows, self.cols, self.kanaele, self.sim_faktor, self.sim_kind)
return dalt.Simulate()
print(self.img_mat[78, 86])
print(self.sim_image[78, 86])
return self.sim_image
Binary file not shown.