Dieses Projekt dient der digitalen Umwandlung von Bildern in simulierte Darstellung aus Sicht eines rot-grün-blinden Menschen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Dyschromasie-Applikation.py 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. from PIL import Image, ImageTk
  2. import PIL
  3. import tkinter as tk
  4. from tkinter import filedialog, messagebox
  5. import cv2
  6. import numpy as np
  7. class Dyschromasie:
  8. cb_image = np.array([]).astype('float64')
  9. sim_image = np.array([]).astype('uint8')
  10. def __init__(self, img_mat=np.array([]), rows=0, cols=0, kanaele=0):
  11. self.rows = rows
  12. self.cols = cols
  13. self.kanaele = kanaele
  14. self.img_mat = img_mat
  15. T = np.array([[0.31399022, 0.63951294, 0.04649755],
  16. [0.15537241, 0.75789446, 0.08670142],
  17. [0.01775239, 0.10944209, 0.87256922]])
  18. T_reversed = np.array([[5.47221206, -4.6419601, 0.16963708],
  19. [-1.1252419, 2.29317094, -0.1678952],
  20. [0.02980165, -0.19318073, 1.16364789]])
  21. def gammaCorrection(self, v):
  22. if v <= 0.04045 * 255:
  23. return float(((v / 255) / 12.92))
  24. elif v > 0.04045 * 255:
  25. return float((((v / 255) + 0.055) / 1.055) ** 2.4)
  26. def reverseGammaCorrection(self, v_reverse):
  27. if v_reverse <= 0.0031308:
  28. return int(255 * (12.92 * v_reverse))
  29. elif v_reverse > 0.0031308:
  30. return int(255 * (1.055 * v_reverse ** 0.41666 - 0.055))
  31. class Protanopie(Dyschromasie):
  32. sim_mat = np.array([[0, 1.05118294, -0.05116099],
  33. [0, 1, 0],
  34. [0, 0, 1]])
  35. def Simulate(self):
  36. # Gammakorrektur durchfuehren
  37. self.cb_image = np.copy(self.img_mat).astype('float64')
  38. for i in range(self.rows):
  39. for j in range(self.cols):
  40. for x in range(3):
  41. self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
  42. # Einzelne Pixelwertberechnung
  43. for i in range(self.rows):
  44. for j in range(self.cols):
  45. 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])))
  46. self.sim_image = np.copy(self.cb_image)
  47. self.sim_image = self.sim_image.astype('uint8')
  48. # Rücktransformation der Gammawerte
  49. for i in range(self.rows):
  50. for j in range(self.cols):
  51. for x in range(3):
  52. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  53. return self.sim_image
  54. class Deuteranopie(Dyschromasie):
  55. sim_mat = np.array([[1, 0, 0],
  56. [0.9513092, 0, 0.04866992],
  57. [0, 0, 1]])
  58. def Simulate(self):
  59. # Gammakorrektur durchfuehren
  60. self.cb_image = np.copy(self.img_mat).astype('float64')
  61. for i in range(self.rows):
  62. for j in range(self.cols):
  63. for x in range(3):
  64. self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
  65. # Einzelne Pixelwertberechnung
  66. for i in range(self.rows):
  67. for j in range(self.cols):
  68. 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])))
  69. self.sim_image = np.copy(self.cb_image)
  70. self.sim_image = self.sim_image.astype('uint8')
  71. # Rücktransformation der Gammawerte
  72. for i in range(self.rows):
  73. for j in range(self.cols):
  74. for x in range(3):
  75. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  76. return self.sim_image
  77. class Tritanopie(Dyschromasie):
  78. sim_mat = np.array([[1, 0, 0],
  79. [0, 1, 0],
  80. [-0.86744736, 1.86727089, 0]])
  81. def Simulate(self):
  82. # Gammakorrektur durchfuehren
  83. self.cb_image = np.copy(self.img_mat).astype('float64')
  84. for i in range(self.rows):
  85. for j in range(self.cols):
  86. for x in range(3):
  87. self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
  88. # Einzelne Pixelwertberechnung
  89. for i in range(self.rows):
  90. for j in range(self.cols):
  91. 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])))
  92. self.sim_image = np.copy(self.cb_image)
  93. self.sim_image = self.sim_image.astype('uint8')
  94. # Rücktransformation der Gammawerte
  95. for i in range(self.rows):
  96. for j in range(self.cols):
  97. for x in range(3):
  98. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  99. return self.sim_image
  100. root = tk.Tk()
  101. root.title("Projekt Dyschromasie")
  102. img = np.array([])
  103. rows = 0
  104. cols = 0
  105. kanaele = 0
  106. sim_pro = tk.IntVar(root)
  107. sim_deut = tk.IntVar(root)
  108. sim_tri = tk.IntVar(root)
  109. def browse():
  110. # Auswahl des FilePaths
  111. try:
  112. path = tk.filedialog.askopenfilename(filetypes=[("Image File", '.jpg')])
  113. im = Image.open(path)
  114. except:
  115. tk.messagebox.showerror(title='Datenfehler', message='Kein Bild gefunden/ausgewählt')
  116. global simulateButton
  117. if len(path) > 0:
  118. simulateButton.config(state='active')
  119. # Anzeigen des Bildes
  120. tkimage = ImageTk.PhotoImage(im)
  121. myvar = tk.Label(root, image=tkimage)
  122. myvar.image = tkimage
  123. myvar.grid(columnspan=5)
  124. # Einspeichern der Path-Informationen
  125. global img, rows, cols, kanaele
  126. img = cv2.imread(path)
  127. rows, cols, kanaele = img.shape
  128. def simulate():
  129. global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
  130. if sim_deut.get():
  131. d = Deuteranopie(img, rows, cols, kanaele)
  132. display_array_deut = cv2.cvtColor(np.copy(d.Simulate()), cv2.COLOR_BGR2RGB)
  133. T = tk.Text(root,height=1,width=15)
  134. T.grid(columnspan=5)
  135. T.insert('current',"Deutranopie:")
  136. conv_SimulationPic_deut = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_deut))
  137. sim_pic_deut = tk.Label(root, image=conv_SimulationPic_deut)
  138. sim_pic_deut.Image = conv_SimulationPic_deut
  139. sim_pic_deut.grid(columnspan=5)
  140. elif sim_tri.get():
  141. t = Tritanopie(img, rows, cols, kanaele)
  142. display_array_tri = cv2.cvtColor(np.copy(t.Simulate()), cv2.COLOR_BGR2RGB)
  143. T = tk.Text(root, height=1, width=15)
  144. T.grid(columnspan=5)
  145. T.insert('current', "Tritanopie:")
  146. conv_SimulationPic_tri = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_tri))
  147. sim_pic_tri = tk.Label(root, image=conv_SimulationPic_tri)
  148. sim_pic_tri.Image = conv_SimulationPic_tri
  149. sim_pic_tri.grid(columnspan=5)
  150. elif sim_pro.get():
  151. p = Protanopie(img, rows, cols, kanaele)
  152. display_array_pro = cv2.cvtColor(np.copy(p.Simulate()), cv2.COLOR_BGR2RGB)
  153. T = tk.Text(root, height=1, width=15)
  154. T.grid(columnspan=5)
  155. T.insert('current', "Protanopie:")
  156. conv_SimulationPic_pro = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_pro))
  157. sim_pic_pro = tk.Label(root, image=conv_SimulationPic_pro)
  158. sim_pic_pro.Image = conv_SimulationPic_pro
  159. sim_pic_pro.grid(columnspan=5)
  160. btn = tk.Button(root, text="Browse", width=25, command=browse, bg='light blue')
  161. btn.grid(column = 0, row = 0,columnspan=2)
  162. simulateButton = tk.Button(root, text="Simulate", width=25, command=simulate, bg='light blue')
  163. simulateButton.grid(column = 1, row = 0,columnspan=2)
  164. simulateButton.config(state='disabled')
  165. checkButton_p = tk.Checkbutton(root, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20)
  166. checkButton_d = tk.Checkbutton(root, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20)
  167. checkButton_t = tk.Checkbutton(root, text="Tritanop", variable=sim_tri, onvalue=1, offvalue=0, height=5, width=20)
  168. checkButton_p.grid(column = 0, row = 1)
  169. checkButton_d.grid(column = 1, row = 1)
  170. checkButton_t.grid(column = 2, row = 1)
  171. root.mainloop()