diff --git a/GUI.py b/GUI.py
index 6d6fa51b906ce7e0957886cb191a6c73d7a49f71..a48cdf92c6d267de75e66d1e03e2ef19adb76cfe 100644
--- a/GUI.py
+++ b/GUI.py
@@ -1,4 +1,4 @@
-from tkinter import Tk, Label, Button, StringVar, OptionMenu
+from tkinter import StringVar, Label, Button, OptionMenu, Tk
 from tkinter.filedialog import askopenfilename
 from tokenize import String
 
@@ -11,6 +11,10 @@ from filter import *
 class GUI(object):
 
     def __init__(self, master):
+        """
+        This class defines the GUI as one.
+        :param master: The Tk root.
+        """
         self.master = master
         self.master.title('Filter')
 
@@ -50,7 +54,13 @@ class GUI(object):
         self.original_image_label.grid(row=1, column=0)
         self.filtered_image_label.grid(row=1, column=1)
 
-    def read_image(self, path: String):
+    def read_image(self, path: String) -> ImageTk.PhotoImage:
+        """
+        This reads an image from a given path and resize it.
+
+        :param path: The path to the image.
+        :return: A image to be used in the frontend
+        """
         return ImageTk.PhotoImage(
             Image.open(path).resize(
                 (self.image_label_width, self.image_label_height),
@@ -58,15 +68,28 @@ class GUI(object):
             )
         )
 
-    def _update_label_image(self, label: Label, new_image, row: int, column: int):
+    def _update_label_image(self, label: Label, new_image, row: int, column: int) -> None:
+        """
+        This method updates to label with a new image.
+
+        :param label: The reference to the label which should be changes.
+        :param new_image: The reference to the new image.
+        :param row: Row in the GUI.
+        :param column: Column in the GUI.
+        :return: None
+        """
         label.destroy()
         label = Label(self.master, image=new_image)
         label.image = new_image
         label.pack()
         label.grid(row=row, column=column)
 
-    def set_new_file(self):
-        # Todo: Specify more formats
+    def set_new_file(self) -> None:
+        """
+        This sets the new file and refreshed the paths as well with the lables.
+
+        :return: None
+        """
         self.image_path: String = askopenfilename(initialdir='/', title='Select file',
                                                   filetypes=(('jpeg files', '*.jpeg'), ('all files', '*.*')))
 
@@ -77,17 +100,39 @@ class GUI(object):
         self.filter.set(FILTER.empty.value)
         self._update_label_image(self.filtered_image_label, new_image, 1, 1)
 
-    def change_filter(self, *args):
+    def change_filter(self, *args) -> None:
+        """
+        This changes the filter and updates the label for the edited images.
+
+        :param args: Arguments of the listener.
+        :return: None
+        """
         self.edit_image()
         edited_image = self.read_image(self.edit_path)
         self._update_label_image(self.filtered_image_label, edited_image, 1, 1)
 
-    def edit_image(self):
+    def edit_image(self) -> None:
+        """
+        This method edits a given image and saves it.
+
+        :return: None
+        """
         print('From: ' + self.image_path + ' to ' + self.edit_path + ' with ' + self.filter.get())
         Editor(self.image_path, self.edit_path).do_convolution_with(self.filter.get())
+        print('Done...')
 
 
 if __name__ == '__main__':
+    """
+    This program is for editing images with a given filter.
+    The user can choose between all filters defined in the FILTER enum.
+    
+    To use the program run:
+        $ python3 GUI.py
+    
+    Notice: The edited image will be saved in ./images/edited.py. Each new filter will overwrite this image. This may
+    take a while.
+    """
     root = Tk()
     root.resizable(False, False)
     my_gui = GUI(root)
diff --git a/color.py b/color.py
deleted file mode 100644
index d940325aec3c7da36879a1b8ec63c5be5077071e..0000000000000000000000000000000000000000
--- a/color.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from enum import Enum
-
-
-class COLOR(Enum):
-    red = 0
-    green = 1
-    blue = 2
diff --git a/color_enum.py b/color_enum.py
new file mode 100644
index 0000000000000000000000000000000000000000..b9e0e1e601484faf51ca21ed4de746721dd9d449
--- /dev/null
+++ b/color_enum.py
@@ -0,0 +1,11 @@
+from enum import Enum
+
+
+class COLOR(Enum):
+    """
+    This enum defines the index-range of the colors in the image.
+    Notice: All images must be a RGB-image (MxNx3).
+    """
+    red = 0
+    green = 1
+    blue = 2
diff --git a/editor.py b/editor.py
index 8be8a9e9f3e5216e7de1f6bc8a6c1c452fa5953b..762bd6b5a03ccaa73c5d5573adbcf7910e7e8402 100644
--- a/editor.py
+++ b/editor.py
@@ -1,3 +1,6 @@
+import copy
+from tokenize import String
+
 from skimage import io
 
 from pixel import *
@@ -5,14 +8,26 @@ from pixel import *
 
 class Editor(object):
 
-    def __init__(self, origin_path, edit_path):
+    def __init__(self, origin_path: String, edit_path: String):
+        """
+        This class is the editor which edits a given image and stores a new one.
+
+        :param origin_path: The original image which should be edited.
+        :param edit_path: The edited image which should be stored.
+        """
         self.image_path = origin_path
         self.edit_path = edit_path
 
-    def do_convolution_with(self, option):
+    def do_convolution_with(self, option: String) -> None:
+        """
+        This method iterates over the image and changes each pixel by a given method.
+        Notice, that the image must be a RGB-image (MxNx3).
+
+        :param option: The options defined in FILTER.
+        :return: None
+        """
         image = io.imread(fname=self.image_path)
-        edited_image = io.imread(fname=self.image_path)  # copy.deepcopy(image)
-        # if image is grey scale then there is only width and height
+        edited_image = copy.deepcopy(image)  # io.imread(fname=self.image_path)
         height, width, _ = image.shape
 
         for v in range(height):
diff --git a/filter.py b/filter.py
index 0c9ba5433bb0d9a6d5a9c779ac4faf9b1a4e633c..58ca9cfbab9a9f4f449d6191bb05a673cb430535 100644
--- a/filter.py
+++ b/filter.py
@@ -1,35 +1,55 @@
 import numpy as np
+from enum import Enum
+from tokenize import String
+from typing import List, Tuple
+from unittest.test.testmock.testpatch import function
 
-from color import *
-from mask import *
-
+import imageio
 
-class FILTER(Enum):
-    empty = '---'
-    mod_laplacian = 'Modified Laplacian'
-    laplacian = 'Laplacian'
-    gaussian = 'Gaussian'
-    median = 'Median'
-    box = 'Box'
-    min = 'Min'
-    max = 'Max'
+from color_enum import *
+from filter_enum import *
+from mask import *
 
 
 class Filter(object):
 
-    def __init__(self, image, v, u):
+    def __init__(self, image: imageio.core.util.Array, v: int, u: int) -> None:
+        """
+        This class edits a pixel in a image with a given filter.
+
+        :param image: The image in which the filter should be used.
+        :param v: The v coordinate
+        :param u: The u coordinate
+        """
         self.image = image
         self.v = v
         self.u = u
 
-    def use(self, option, linear=True, dim=(5, 5)):
+    def use(self, option: String = FILTER.empty.value, linear: bool = True, dim: Tuple = (5, 5),
+            f: function = np.min) -> List:
+        """
+        With this method it can be decided if a linear or non-linear filter should be used.
+
+        :param f: The filter function to be used.
+        :param option: The name of the filter to be used.
+        :param linear: Is the filter linear.
+        :param dim: The dimension of the filter.
+        :return: A new rgb-pixel
+        """
         if linear:
             return self.linear_filter(option)
         else:
-            return self.non_linear_filter(option, dim)
+            return self.non_linear_filter(f, dim)
+
+    def linear_filter(self, option: String) -> List:
+        """
+        This method is for filtering with linear filters.
+        Notice: All filter-matrices must have a uneven dimension.
+
+        :param option: The name of the filter to be used.
+        :return: A modified rgb-pixel
+        """
 
-    def linear_filter(self, option):
-        # just filter with uneven dimensions
         height_I, width_I, _ = self.image.shape
 
         H = np.matrix(Mask().H[option])
@@ -50,9 +70,16 @@ class Filter(object):
                                                   np.multiply(1 / divider, H[center_j + j, center_i + i])
         return new_pixel
 
-    def non_linear_filter(self, option, dim=(5, 5)):
+    def non_linear_filter(self, f: function, dim: Tuple = (5, 5)) -> List:
+        """
+        This method is for filtering with linear filters.
+        Notice: All filter-regions R must have a uneven dimension.
+
+        :param f: The filter function to be used.
+        :param dim: The dimension of filter-region R.
+        :return: A modified rgb-pixel
+        """
 
-        # just filter with uneven dimensions
         height_I, width_I, _ = self.image.shape
         height_R, width_R = dim
         center_i = center_j = int(height_R / 2)
@@ -65,21 +92,8 @@ class Filter(object):
                     for color in COLOR:
                         colors_neighbors[color.value] += [self.image[self.v + j, self.u + i, color.value]]
 
-        if option == FILTER.median.value:
-            return [
-                np.median(colors_neighbors[COLOR.red.value]),
-                np.median(colors_neighbors[COLOR.green.value]),
-                np.median(colors_neighbors[COLOR.blue.value])
-            ]
-        elif option == FILTER.min.value:
-            return [
-                np.min(colors_neighbors[COLOR.red.value]),
-                np.min(colors_neighbors[COLOR.green.value]),
-                np.min(colors_neighbors[COLOR.blue.value])
-            ]
-        elif option == FILTER.max.value:
-            return [
-                np.max(colors_neighbors[COLOR.red.value]),
-                np.max(colors_neighbors[COLOR.green.value]),
-                np.max(colors_neighbors[COLOR.blue.value])
-            ]
+        return [
+            f(colors_neighbors[COLOR.red.value]),
+            f(colors_neighbors[COLOR.green.value]),
+            f(colors_neighbors[COLOR.blue.value])
+        ]
diff --git a/filter_enum.py b/filter_enum.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc8c77e5ffbb7a121b012b6bd456d64c641a5728
--- /dev/null
+++ b/filter_enum.py
@@ -0,0 +1,15 @@
+from enum import Enum
+
+
+class FILTER(Enum):
+    """
+    This enum defines all filters.
+    """
+    empty = '---'
+    mod_laplacian = 'Modified Laplacian'
+    laplacian = 'Laplacian'
+    gaussian = 'Gaussian'
+    median = 'Median'
+    box = 'Box'
+    min = 'Min'
+    max = 'Max'
diff --git a/images/edit.jpeg b/images/edit.jpeg
index 8782bb9b020ec6fbecf2a5b2d9919486ec4e4739..60dc966838f446baf89a8d602d08a3b0f49ceb32 100644
Binary files a/images/edit.jpeg and b/images/edit.jpeg differ
diff --git a/mask.py b/mask.py
index 77cfbc1d18b07db71e9e83603267e14c8490f622..b1926a7c01fdc77fe9c6daafbbb7776ed965c488 100644
--- a/mask.py
+++ b/mask.py
@@ -1,9 +1,14 @@
+from typing import List
+
 from filter import *
 
 
 class Mask(object):
 
     def __init__(self):
+        """
+        This class contains all filter matrices which can be accessed via H.
+        """
         self.H = {
             FILTER.gaussian.value: self._gaussian(),
             FILTER.laplacian.value: self._laplacian(),
@@ -12,7 +17,11 @@ class Mask(object):
         }
 
     @staticmethod
-    def _gaussian():
+    def _gaussian() -> List[List]:
+        """
+        Gaussian-Blur for smoothing images.
+        :return: Gaussian-Blur-Matrix
+        """
         return [[0, 1, 2, 1, 0],
                 [1, 3, 5, 3, 1],
                 [2, 5, 9, 5, 2],
@@ -20,15 +29,24 @@ class Mask(object):
                 [0, 1, 2, 1, 0]]
 
     @staticmethod
-    def _laplacian():
+    def _laplacian() -> List[List]:
+        """
+        Laplacian-Filter is a difference-filter for finding edges.
+        :return:  Laplacian-Filter-Matrix
+        """
         return [[0, 0, -1, 0, 0],
                 [0, -1, -2, -1, 0],
-                [-1, -2, 10, -2, -1],
+                [-1, -2, 16, -2, -1],
                 [0, -1, -2, -1, 0],
                 [0, 0, -1, 0, 0]]
 
     @staticmethod
-    def _modified_laplacian():
+    def _modified_laplacian() -> List[List]:
+        """
+        Modified Laplacian-Filter is a difference-filter for finding edges.
+        It emphasizes the edges more.
+        :return:  Modified-Laplacian-Filter-Matrix
+        """
         return [[0, 0, -1, 0, 0],
                 [0, -1, -200, -1, 0],
                 [-1, -200, 1000, -200, -1],
@@ -36,7 +54,11 @@ class Mask(object):
                 [0, 0, -1, 0, 0]]
 
     @staticmethod
-    def _box():
+    def _box() -> List[List]:
+        """
+        Box-Blur for smoothing images.
+        :return: Box-Blur-Filter-Matrix
+        """
         return [[0, 0, 0, 0, 0],
                 [0, 1, 1, 1, 0],
                 [0, 1, 1, 1, 0],
diff --git a/pixel.py b/pixel.py
index d6bfe21c459754daaaf50254956d33ca9cca9ca5..97e585cae2c8a30cc50fa5ec56c712f4874d0ae4 100644
--- a/pixel.py
+++ b/pixel.py
@@ -1,13 +1,31 @@
-from filter import *
+import numpy as np
+from typing import List
+
+import imageio
+
+from filter import FILTER, Filter
 
 
 class Pixel(object):
-    def __init__(self, image, v, u):
+    def __init__(self, image: imageio.core.util.Array, v: int, u: int):
+        """
+        This class edits a pixel in a image with a given filter.
+
+        :param image: The image in which the filter should be used.
+        :param v: The v coordinate
+        :param u: The u coordinate
+        """
         self.image = image
         self.v = v
         self.u = u
 
-    def filter_with(self, option: str):
+    def filter_with(self, option: str) -> List:
+        """
+        This method gets the new pixel edited with a given filter.
+
+        :param option: The name of the filter to be used.
+        :return: New pixel edited with a given filter
+        """
         if option == FILTER.empty.value:
             return self.image[self.v, self.u]
         elif option == FILTER.laplacian.value:
@@ -19,8 +37,8 @@ class Pixel(object):
         elif option == FILTER.box.value:
             return Filter(self.image, self.v, self.u).use(FILTER.box.value)
         elif option == FILTER.median.value:
-            return Filter(self.image, self.v, self.u).use(FILTER.median.value, linear=False, dim=(5, 5))
+            return Filter(self.image, self.v, self.u).use(linear=False, dim=(5, 5), f=np.median)
         elif option == FILTER.min.value:
-            return Filter(self.image, self.v, self.u).use(FILTER.min.value, linear=False, dim=(5, 5))
+            return Filter(self.image, self.v, self.u).use(linear=False, dim=(5, 5), f=np.min)
         elif option == FILTER.max.value:
-            return Filter(self.image, self.v, self.u).use(FILTER.max.value, linear=False, dim=(5, 5))
+            return Filter(self.image, self.v, self.u).use(linear=False, dim=(5, 5), f=np.max)
diff --git a/requirements.txt b/requirements.txt
index 32ba7c44ffc8bed6578d56c33d4f9efee0272108..0f25081e9120a9155e068763ee1ee1990fe5c119 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
+imageio==2.5.0
 Pillow==6.0.0
 scikit-image==0.15.0
 numpy == 1.16.2
\ No newline at end of file