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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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(
  46. self.T_reversed.dot(self.sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
  47. self.sim_image = np.copy(self.cb_image)
  48. self.sim_image = self.sim_image.astype('uint8')
  49. # Rücktransformation der Gammawerte
  50. for i in range(self.rows):
  51. for j in range(self.cols):
  52. for x in range(3):
  53. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  54. return self.sim_image
  55. class Deuteranopie(Dyschromasie):
  56. sim_mat = np.array([[1, 0, 0],
  57. [0.9513092, 0, 0.04866992],
  58. [0, 0, 1]])
  59. def Simulate(self):
  60. # Gammakorrektur durchfuehren
  61. self.cb_image = np.copy(self.img_mat).astype('float64')
  62. for i in range(self.rows):
  63. for j in range(self.cols):
  64. for x in range(3):
  65. self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
  66. # Einzelne Pixelwertberechnung
  67. for i in range(self.rows):
  68. for j in range(self.cols):
  69. self.cb_image[i, j] = np.flipud(
  70. self.T_reversed.dot(self.sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
  71. self.sim_image = np.copy(self.cb_image)
  72. self.sim_image = self.sim_image.astype('uint8')
  73. # Rücktransformation der Gammawerte
  74. for i in range(self.rows):
  75. for j in range(self.cols):
  76. for x in range(3):
  77. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  78. return self.sim_image
  79. class Tritanopie(Dyschromasie):
  80. sim_mat = np.array([[1, 0, 0],
  81. [0, 1, 0],
  82. [-0.86744736, 1.86727089, 0]])
  83. def Simulate(self):
  84. # Gammakorrektur durchfuehren
  85. self.cb_image = np.copy(self.img_mat).astype('float64')
  86. for i in range(self.rows):
  87. for j in range(self.cols):
  88. for x in range(3):
  89. self.cb_image[i, j, x] = self.gammaCorrection(self.img_mat[i, j, x])
  90. # Einzelne Pixelwertberechnung
  91. for i in range(self.rows):
  92. for j in range(self.cols):
  93. self.cb_image[i, j] = np.flipud(
  94. self.T_reversed.dot(self.sim_mat).dot(self.T).dot(np.flipud(self.cb_image[i, j])))
  95. self.sim_image = np.copy(self.cb_image)
  96. self.sim_image = self.sim_image.astype('uint8')
  97. # Rücktransformation der Gammawerte
  98. for i in range(self.rows):
  99. for j in range(self.cols):
  100. for x in range(3):
  101. self.sim_image[i, j, x] = self.reverseGammaCorrection(self.cb_image[i, j, x])
  102. return self.sim_image
  103. root = tk.Tk()
  104. root.title("Projekt Dyschromasie")
  105. img = np.array([])
  106. rows = 0
  107. cols = 0
  108. kanaele = 0
  109. sim_pro = tk.IntVar(root)
  110. sim_deut = tk.IntVar(root)
  111. sim_tri = tk.IntVar(root)
  112. simGrad = tk.IntVar(root)
  113. simulationsGradient = tk.Scale(root, from_=0, to_=100, variable=simGrad, orient='horizontal')
  114. simulationsGradient.grid(column= 0, row = 1, columnspan=10)
  115. def browse():
  116. # Auswahl des FilePaths
  117. try:
  118. path = tk.filedialog.askopenfilename(filetypes=[("Image File", '.jpg')])
  119. im = Image.open(path)
  120. except:
  121. tk.messagebox.showerror(title='Datenfehler', message='Kein Bild gefunden/ausgewählt')
  122. global simulateButton
  123. if len(path) > 0:
  124. simulateButton.config(state='active')
  125. # Anzeigen des Bildes
  126. tkimage = ImageTk.PhotoImage(im)
  127. myvar = tk.Label(root, image=tkimage)
  128. myvar.image = tkimage
  129. myvar.grid(columnspan=5)
  130. # Einspeichern der Path-Informationen
  131. global img, rows, cols, kanaele
  132. img = cv2.imread(path)
  133. rows, cols, kanaele = img.shape
  134. def simulate():
  135. global img, rows, cols, kanaele, sim_pro, sim_deut, sim_tri
  136. if sim_deut.get():
  137. d = Deuteranopie(img, rows, cols, kanaele)
  138. display_array_deut = cv2.cvtColor(np.copy(d.Simulate()), cv2.COLOR_BGR2RGB)
  139. T = tk.Text(root, height=1, width=15)
  140. T.grid(columnspan=5)
  141. T.insert('current', "Deutranopie:")
  142. conv_SimulationPic_deut = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_deut))
  143. sim_pic_deut = tk.Label(root, image=conv_SimulationPic_deut)
  144. sim_pic_deut.Image = conv_SimulationPic_deut
  145. sim_pic_deut.grid(columnspan=5)
  146. elif sim_tri.get():
  147. t = Tritanopie(img, rows, cols, kanaele)
  148. display_array_tri = cv2.cvtColor(np.copy(t.Simulate()), cv2.COLOR_BGR2RGB)
  149. T = tk.Text(root, height=1, width=15)
  150. T.grid(columnspan=5)
  151. T.insert('current', "Tritanopie:")
  152. conv_SimulationPic_tri = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_tri))
  153. sim_pic_tri = tk.Label(root, image=conv_SimulationPic_tri)
  154. sim_pic_tri.Image = conv_SimulationPic_tri
  155. sim_pic_tri.grid(columnspan=5)
  156. elif sim_pro.get():
  157. p = Protanopie(img, rows, cols, kanaele)
  158. display_array_pro = cv2.cvtColor(np.copy(p.Simulate()), cv2.COLOR_BGR2RGB)
  159. T = tk.Text(root, height=1, width=15)
  160. T.grid(columnspan=5)
  161. T.insert('current', "Protanopie:")
  162. conv_SimulationPic_pro = ImageTk.PhotoImage(image=PIL.Image.fromarray(display_array_pro))
  163. sim_pic_pro = tk.Label(root, image=conv_SimulationPic_pro)
  164. sim_pic_pro.Image = conv_SimulationPic_pro
  165. sim_pic_pro.grid(columnspan=5)
  166. btn = tk.Button(root, text="Browse", width=25, command=browse, bg='light blue')
  167. btn.grid(column=0, row=0, columnspan=2)
  168. simulateButton = tk.Button(root, text="Simulate", width=25, command=simulate, bg='light blue')
  169. simulateButton.grid(column=1, row=0, columnspan=2)
  170. simulateButton.config(state='disabled')
  171. checkButton_p = tk.Checkbutton(root, text="Protanop", variable=sim_pro, onvalue=1, offvalue=0, height=5, width=20)
  172. checkButton_d = tk.Checkbutton(root, text="Deutanop", variable=sim_deut, onvalue=1, offvalue=0, height=5, width=20)
  173. checkButton_t = tk.Checkbutton(root, text="Tritanop", variable=sim_tri, onvalue=1, offvalue=0, height=5, width=20)
  174. checkButton_p.grid(column=0, row=2)
  175. checkButton_d.grid(column=1, row=2)
  176. checkButton_t.grid(column=2, row=2)
  177. root.mainloop()