Compare commits

...
30 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
Max Sponsel ff420dc77c 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:52:49 +02:00
Max Sponsel 9b76b10e32 Lösung des Aliasing Problems
Betrachtung des Pixels (40,152) im Fall Tree Bild ergab die Lösung für das Aliasing:
Bei negativen Werten in der Matrix T^1*sim_mat*T ergeben sich Überläufe. Lösung durch Anpassen der GammaKorrektur auf Abstände statt Absolutwerte.
2020-09-13 11:51:17 +02:00
Max Sponsel d5252ea2be Weiter CodeCleanup 2020-09-12 11:52:40 +02:00
Max Sponsel 30d0e61ca7 Auslagern der Scrollbar-Funktion und Einfügen von Beispielbildern 2020-09-12 11:45:49 +02:00
Max Sponsel f176685f0b Beispielbild aus Paper hinzugefügt 2020-09-11 17:35:34 +02:00
Max Sponsel 98e6b56bd3 CodeCleanup
Funktionen ausgelagert und drei Farbarten zu einer großen Klasse zusammengefasst
2020-09-10 14:44:29 +02:00
Max Sponsel 08881f47cf Vereinfachung des Codes mit cv2.cvtColor
Statt das Array doppelt mit der flipud Funktion zu spiegeln, wird es direkt im Einleseprozess von BGR(OpenCV) zu RGB(Pillow und Algorithmus) konvertiert.
2020-09-10 11:34:04 +02:00
Max Sponsel e62ea2a23e Anpassung des Print Befehls
Ausgabe des Bildes erfolgt nun auch mit der Stärke der Farbblindheitssimulation (von 0 bis 100%)
2020-09-07 10:47:17 +02:00
SponselMa71420 3b5798b143 Verschiedene Testreihen zur Abschwächung sowie die Grundidee mit Formelanpassung 2020-09-04 10:01:05 +00:00
Max Sponsel a1ebdb827c Abschwächung der Simulationsstärke
Durch Anpassungen in den Simulationsmatrizen ergeben sich Abschwächungsmuster. Somit können für verschiedene Probanden unterschiedliche Stärken der Sehschwäche simuliert werden.
2020-09-04 11:59:25 +02:00
Max Sponsel 9980f03bdd Dynamische vertikale und horizontale Scrollbar
Durch Hilfe von Stack Overflow wurde eine dynamische Scrollbar implementiert. Diese erscheint je nach Windowgröße dynamisch. 
(siehe hierzu: https://stackoverflow.com/questions/47008899/tkinter-dynamic-scrollbar-for-a-dynamic-gui-not-updating-with-gui)
2020-08-29 10:10:11 +02:00
Max Sponsel 62b16b4a96 Erste Tests mit Slider und Umwandlungsfunktion
Erste Funktionen in den Klassen implementiert; Erste Test gemacht. Ergebnisse noch nicht zufriedenstellend. Auch Implementierung einer Scrollbar nötig!!
2020-08-25 10:45:12 +02:00
Max Sponsel bbc3aafeb3 Merge remote-tracking branch 'origin/master' 2020-08-25 09:40:33 +02:00
Max Sponsel da88618ce6 Einfügen eines Sliders
Um den Grad der Faarbblindheit korrekt zu Simulieren, muss ein Widget eingebaut werden, welches den prozentualen Anteil der Differenz zwischen Simulation und echtem Wert vergleicht und mit dem ausgewählten Wert (z. B. 80%) neu gewichtet.
2020-08-25 09:40:27 +02:00
Max Sponsel f1348cfef2 Einfügen eines Sliders
Um den Grad der Faarbblindheit korrekt zu Simulieren, muss ein Widget eingebaut werden, welches den prozentualen Anteil der Differenz zwischen Simulation und echtem Wert vergleicht und mit dem ausgewählten Wert (z. B. 80%) neu gewichtet.
2020-08-25 09:40:16 +02:00
Max Sponsel d1cd073fde Merge remote-tracking branch 'origin/master' 2020-08-21 11:23:26 +02:00
Max Sponsel 8c4760c75d Kommentar entfernt 2020-08-15 09:18:51 +02:00
18 changed files with 247 additions and 166 deletions

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

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: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+61 -164
View File
@@ -1,132 +1,18 @@
from PIL import Image, ImageTk from PIL import Image, ImageTk
import PIL import PIL
import tkinter as tk import tkinter as tk
from tkinter import filedialog, messagebox
import cv2 import cv2
import numpy as np import numpy as np
from Farbaenderung import Dyschromasie
from Scrollbar import ScrollFrame
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 = tk.Tk()
simGrad = tk.IntVar(root)
root.title("Projekt Dyschromasie") root.title("Projekt Dyschromasie")
SB = ScrollFrame(root)
img = np.array([]) img = np.array([])
rows = 0 rows = 0
cols = 0 cols = 0
@@ -136,84 +22,95 @@ sim_pro = tk.IntVar(root)
sim_deut = tk.IntVar(root) sim_deut = tk.IntVar(root)
sim_tri = 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(): def browse():
# Auswahl des FilePaths # Auswahl des FilePaths
try: try:
path = tk.filedialog.askopenfilename(filetypes=[("Image File", '.jpg')]) path = tk.filedialog.askopenfilename(filetypes=[("Image File", '.jpg'), ("Image File", '.png')])
im = Image.open(path) im = Image.open(path)
except: except:
tk.messagebox.showerror(title='Datenfehler', message='Kein Bild gefunden/ausgewählt') tk.messagebox.showerror(title='Datenfehler', message='Kein Bild gefunden/ausgewählt')
global simulateButton global simulateButton
if len(path) > 0: if len(path) > 0:
simulateButton.config(state='active') simulateButton.config(state='active')
daltonButton.config(state='active')
# Anzeigen des Bildes # Anzeigen des Bildes
tkimage = ImageTk.PhotoImage(im) tkimage = ImageTk.PhotoImage(im)
myvar = tk.Label(root, image=tkimage) myvar = tk.Label(SB.frame, image=tkimage)
myvar.image = tkimage myvar.image = tkimage
myvar.grid(columnspan=5) myvar.grid(columnspan=5)
# Einspeichern der Path-Informationen # Einspeichern der Path-Informationen
global img, rows, cols, kanaele global img, rows, cols, kanaele
img = cv2.imread(path) img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
rows, cols, kanaele = img.shape 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(): def simulate():
global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
if sim_deut.get(): if sim_deut.get():
d = Deuteranopie(img, rows, cols, kanaele) showImage(img, rows, cols, kanaele, simGrad.get()/100, 'Deuteranop', 'Sim')
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(): elif sim_tri.get():
t = Tritanopie(img, rows, cols, kanaele) showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Tritanop', 'Sim')
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(): elif sim_pro.get():
p = Protanopie(img, rows, cols, kanaele) showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Protanop', 'Sim')
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)
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')
btn = tk.Button(root, text="Browse", width=25, command=browse, bg='light blue') elif sim_tri.get():
btn.grid(column = 0, row = 0,columnspan=2) showImage(img, rows, cols, kanaele, simGrad.get() / 100, 'Tritanop', 'Dalt')
simulateButton = tk.Button(root, text="Simulate", width=25, command=simulate, bg='light blue') elif sim_pro.get():
simulateButton.grid(column = 1, row = 0,columnspan=2) 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=1)
simulateButton.config(state='disabled') simulateButton.config(state='disabled')
checkButton_p = tk.Checkbutton(root, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20) daltonButton = tk.Button(SB.frame, text="Daltonize", width=25, command=daltonize, bg='light blue')
checkButton_d = tk.Checkbutton(root, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20) daltonButton.grid(column=2, row=0, columnspan=1)
checkButton_t = tk.Checkbutton(root, text="Tritanop", variable=sim_tri, onvalue=1, offvalue=0, height=5, width=20) daltonButton.config(state='disabled')
checkButton_p.grid(column = 0, row = 1) checkButton_p = tk.Checkbutton(SB.frame, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20)
checkButton_d.grid(column = 1, row = 1) checkButton_d = tk.Checkbutton(SB.frame, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20)
checkButton_t.grid(column = 2, row = 1) 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() root.mainloop()
+1 -2
View File
@@ -77,8 +77,7 @@ S_t = np.array([[1, 0, 0], #Simulationsmatrix fuer Tritanopi
#Multiplikation der einzelnen Pixel #Multiplikation der einzelnen Pixel
for i in range(rows): for i in range(rows):
for j in range(cols): for j in range(cols):
cb_image[i,j] = T_reversed.dot(S_p).dot(T).dot(cb_image[i,j]) cb_image[i,j] = T_reversed.dot(S_t).dot(T).dot(cb_image[i,j])
# Da OpenCV Pixelwerte in RGB speichert, aber BGR für den Algorithmus nötig ist, muss die Matrix mit flipud gedreht werden
sim_image = np.copy(cb_image) sim_image = np.copy(cb_image)
sim_image = sim_image.astype('uint8') sim_image = sim_image.astype('uint8')
+126
View File
@@ -0,0 +1,126 @@
import numpy as np
import cv2
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 applyGammaCorrection(v_reverse):
if abs(v_reverse) <= 0.0031308:
return round(255 * (12.92 * abs(v_reverse)))
else:
if (round(255 * (1.055 * abs(v_reverse) ** 0.41666 - 0.055))) > 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('int64')
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
self.img_mat = img_mat
self.sim_faktor = sim_faktor
self.sim_kind = sim_kind
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 Simulate(self):
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 == '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]])
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)]])
# Gammakorrektur durchfuehren
self.cb_image = np.copy(self.img_mat).astype('float64')
self.cb_image = cv2.LUT(self.img_mat, removeGammaCorrectionLUT)
rechen_Mat = np.copy(self.T_reversed.dot(sim_mat).dot(self.T))
# 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('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] = 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()
+59
View File
@@ -0,0 +1,59 @@
import tkinter as tk
from tkinter import filedialog, messagebox
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())
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB