diff --git a/A2/GUI.py b/A2/GUI.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb3dc7402e68fe9ffe7a768375a069cebd8fb31c
--- /dev/null
+++ b/A2/GUI.py
@@ -0,0 +1,155 @@
+from tkinter import StringVar, Label, OptionMenu, Tk, Button, Entry, IntVar
+from tkinter.filedialog import askopenfilename
+from tokenize import String
+
+from PIL import ImageTk, Image
+
+from histogram import Histogram
+from histogram_enum import HISTOGRAMS
+
+
+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')
+
+        self.image_label_width = 500
+        self.image_label_height = 500
+
+        self.filter_choices = {HISTOGRAMS.h1.value,
+                               HISTOGRAMS.h2.value}
+
+        self.filter_name = StringVar(root)
+        self.filter_name.set(HISTOGRAMS.empty.value)
+        self.filter_name.trace('w', self.change_filter)
+
+        # Images
+        self.image_path = './images/original.jpeg'
+        self.edit_path = './images/histogram.jpeg'
+        self.image = self.read_image(self.image_path)
+
+        # Labels
+        self.original_image_label = Label(self.master, image=self.image)
+        self.original_image_label.pack()
+        self.filtered_image_label = Label(self.master, image=self.image)
+        self.filtered_image_label.pack()
+
+        # Buttons
+        self.option_menu = OptionMenu(self.master, self.filter_name, *self.filter_choices)
+        self.file_dialog = Button(master, text='Choose', command=lambda: self.set_new_file())
+
+        # Spinner
+        self.b_value = IntVar(self.master)
+        self.b_value.set(1)
+        self.b_menu = Entry(self.master, textvariable=self.b_value)
+
+        # Layout
+        self.file_dialog.grid(row=0, column=0)
+        self.option_menu.grid(row=0, column=1)
+        self.b_menu.grid(row=0, column=2)
+        self.original_image_label.grid(row=1, column=0)
+        self.filtered_image_label.grid(row=1, column=2)
+
+    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),
+                Image.ANTIALIAS
+            )
+        )
+
+    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, *args) -> 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')
+
+        new_image = self.read_image(self.image_path)
+
+        self._update_label_image(self.original_image_label, new_image, 1, 0)
+
+        self.filter_name.set(HISTOGRAMS.empty.value)
+        self.b_value.set(1)
+        self._update_label_image(self.filtered_image_label, new_image, 1, 2)
+
+    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, 2)
+
+    def edit_image(self) -> None:
+        """
+        This method edits a given image and saves it as a grey-scale image.
+
+        :return: None
+        """
+        print('From: ' + self.image_path +
+              ' to ' + self.edit_path +
+              ' with ' + self.filter_name.get() +
+              ' and sigma: '
+              + str(self.b_value.get()))
+
+        Histogram(
+            self.image_path, self.edit_path, self.b_value.get()
+        ).get_histogram(self.filter_name.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.
+    The user can choose between all images defined in the IMAGE enum.
+    
+    Preparation:
+        Make sure you have already installed all packages by running:
+        $ pip3 install -r requirements.txt
+    
+    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.
+    
+    This version uses a padding-method with mean. It makes the usage of the Kirsch-operator much faster.
+    """
+    root = Tk()
+    root.resizable(False, False)
+    my_gui = GUI(root)
+    root.mainloop()
diff --git a/A2/__init__.py b/A2/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/A2/histogram.py b/A2/histogram.py
new file mode 100644
index 0000000000000000000000000000000000000000..1887bddfd762826a0cf09a81f38e914e7b09e2bc
--- /dev/null
+++ b/A2/histogram.py
@@ -0,0 +1,123 @@
+from tokenize import String
+from typing import Dict, List
+
+import imageio
+import matplotlib.pyplot as plt
+import numpy as np
+from skimage import color
+
+from histogram_enum import HISTOGRAMS
+
+
+class Histogram(object):
+
+    def __init__(self, origin_path: String, edit_path: String, b: int = 0):
+        """
+        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.
+        :param b: Is only used if the LoG-Operator is used.
+        """
+        self.image_path = origin_path
+        self.edit_path = edit_path
+        self.b = b
+
+    @staticmethod
+    def __get_bins(image: imageio.core.util.Array) -> Dict:
+        """
+        This method counts each value in the image.
+        h(i) = card{(u,v) | I(u,v) = i}
+        0 <= i <= K - 1
+
+        :param image: the greyscale image
+        :return: Dict where the keys are the values and the key-value is the count
+        """
+        K = 256
+        count = {}
+        for k in range(K):
+            count[str(k)] = 0
+        height, width = image.shape
+        for v in range(height):
+            for u in range(width):
+                count[str(image[v, u])] += 1
+        return count
+
+    @staticmethod
+    def __get_intervals(B: int):
+        intervals = {}
+        splits = np.arange(0, 256, 255 / B)
+        for b in range(B):
+            intervals[str(b)] = list(splits[b:b + 2])
+
+        return intervals
+
+    def __get_bins_in_interval(self, image: imageio.core.util.Array, B: int) -> Dict:
+        """
+        This method counts each value in the image.
+        h(i) = card{(u,v) | a_j < I(u,v) < a_j+1}
+        0 <= j <= B
+
+        :param image: the greyscale image
+        :return: Dict where the keys are the values and the key-value is the count
+        """
+        intervals = self.__get_intervals(B)
+        count = {}
+        for b in range(B):
+            count[str(b)] = 0
+        height, width = image.shape
+        for v in range(height):
+            for u in range(width):
+                for b in range(B):
+                    if intervals[str(b)][0] < image[v, u] < intervals[str(b)][1]:
+                        count[str(b)] += 1
+        return count
+
+    @staticmethod
+    def __bins_to_list(bins: Dict) -> List:
+        """
+        This method converts a dict into a sorted list of tuples.
+
+        :param bins: Bins of the histogram
+        :return: Sorted list of tuples containing all key and key-value pairs.
+        """
+        bins_list = []
+        for key in bins.keys():
+            bins_list += [(int(key), bins[str(key)])]
+        return bins_list
+
+    def __plot_h1(self, keys: List, values: List, option: String):
+        ticks = 6
+        indices = np.arange(len(keys))
+        plt.bar(indices, values, color='black')
+
+        if option == HISTOGRAMS.h1.value:
+            plt.xticks(np.arange(min(keys), 256, step=255 / (ticks - 1)))
+        elif option == HISTOGRAMS.h2.value:
+            plt.xticks(np.arange(0, self.b))
+        plt.savefig('images/histogram.jpeg', dpi=100)
+
+    def get_histogram(self, option: String) -> None:
+        """
+        This method iterates over the image and changes each pixel by a given method.
+        Notice, that the image writes the result as a grey-scale image.
+
+        :param option: The options defined in HISTOGRAMS.
+        :return: None
+        """
+        image = imageio.imread(uri=self.image_path)
+        plt.imshow(image)
+        plt.show()
+        grey_scale_image = color.rgb2gray(image)
+
+        # convert greyscale to interval
+        result = np.multiply(255, grey_scale_image).astype(int)
+        bins = {'4': '2'}
+        if option == HISTOGRAMS.h1.value:
+            bins = self.__get_bins(result)
+        elif option == HISTOGRAMS.h2.value:
+            bins = self.__get_bins_in_interval(result, self.b)
+
+        bins = self.__bins_to_list(bins)
+        keys, values = zip(*bins)
+        self.__plot_h1(keys, values, option)
diff --git a/A2/histogram_enum.py b/A2/histogram_enum.py
new file mode 100644
index 0000000000000000000000000000000000000000..f669869bb3307d15b0ca6ccb9ebd9fa348402453
--- /dev/null
+++ b/A2/histogram_enum.py
@@ -0,0 +1,10 @@
+from enum import Enum
+
+
+class HISTOGRAMS(Enum):
+    """
+    This enum defines all filters.
+    """
+    empty = '---'
+    h1 = 'H1'
+    h2 = 'H2'
diff --git a/A2/images/chalsea/Kadse.jpeg b/A2/images/chalsea/Kadse.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..aa6964c4b7a6dc0dd0629fab3a768a292bee8cf8
Binary files /dev/null and b/A2/images/chalsea/Kadse.jpeg differ
diff --git a/A2/images/histogram.jpeg b/A2/images/histogram.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..0a2a569281288c76f24682066c75ad38e1e32d96
Binary files /dev/null and b/A2/images/histogram.jpeg differ
diff --git a/A2/images/martian/martian.jpg b/A2/images/martian/martian.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fc71f5f2f030729f05583c8a7ca09d8d0f1e980f
Binary files /dev/null and b/A2/images/martian/martian.jpg differ
diff --git a/A2/images/original.jpeg b/A2/images/original.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..9716f6562697103a3a5086ae98493eb8e5fbb46b
Binary files /dev/null and b/A2/images/original.jpeg differ