def hausdorff_distance(path, color, fill_color, path_to_result_file):
    """ Calculate the hausdorff distance.

        Args:
            path (str): tha path where the images reside
            color (gimpcolor.RGB): the outline color
            fill_color (gimpcolor.RGB): the filling color
            path_to_result_file (str): the path where the `results.csv` file will be saved

        Returns:
            Nothing
    """

    # Increases the recursion limit of python,
    # due to it's limit of 1000 recursion call
    sys.setrecursionlimit(1000000)

    # Indicates the start of the process
    gimp.progress_init("Initializing Hausdorff distance...")

    try:
        # Calculates the numbers of images saved in the specified directory
        numbers_of_images = len([name for name in os.listdir(path) \
            if '.png' in name and 'a' in name])
        with open("%s/results.csv" % path_to_result_file, 'w') as file:
            file.write("Reference image;Deviated image;Distance\n")

        for index in range(1, numbers_of_images + 1):
            # Loads the reference image in memory
            base_image = pdb.file_png_load('%s/a%d.png' % (path, index), '')
            ref_layer = base_image.layers[0]  # Retrieves the ref layer

            # Loads the deviated image as layer to the image
            dev_layer = pdb.gimp_file_load_layer(base_image,
                                                 '%s/b%d.png' % (path, index))
            pdb.gimp_image_insert_layer(base_image, dev_layer, None, 0)

            # Creates the outline of the reference layer
            try:
                ref_layer_outline_pixels_positions = get_outline_pixels_positions(
                    base_image, ref_layer, color, fill_color)
            except Exception as e:
                # Writes the results
                with open("%s/results.csv" % path_to_result_file, 'a') as file:
                    file.write("A%d;B%d;%s\n" % (index, index, e.message))
                continue

            try:
                # Creates the outline of the deviated layer
                dev_layer_outline_pixels_positions = get_outline_pixels_positions(
                    base_image, dev_layer, color, fill_color)
            except Exception as e:
                # Writes the results
                with open("%s/results.csv" % path_to_result_file, 'a') as file:
                    file.write("A%d;B%d;%s\n" % (index, index, e.message))
                continue

            # Retrieves the maxmin distance of first layer, with the two points...
            ref_layer_distance, ref_pixel_one, ref_pixel_two = get_maximum_distance(
                ref_layer_outline_pixels_positions,
                dev_layer_outline_pixels_positions)

            # ...and the maxmin distance and the points of the second layer.
            dev_layer_distance, dev_pixel_one, dev_pixel_two = get_maximum_distance(
                dev_layer_outline_pixels_positions,
                ref_layer_outline_pixels_positions)

            # Merges the layers to point out the maximum distance
            pdb.gimp_layer_set_mode(dev_layer, 7)
            pdb.gimp_image_merge_down(base_image, dev_layer, 1)
            merged_layer = base_image.layers[0]

            distance = 0.0
            if ref_layer_distance >= dev_layer_distance:
                distance = ref_layer_distance
                draw_line(merged_layer, [ref_pixel_one, ref_pixel_two],
                          [dev_pixel_one, dev_pixel_two])
            else:
                distance = dev_layer_distance
                draw_line(merged_layer, [dev_pixel_one, dev_pixel_two],
                          [ref_pixel_one, ref_pixel_two])

            # Inserts the text layer
            pdb.gimp_context_set_foreground(RGB(1.0, 1.0, 1.0, 1.0))
            text_layer = pdb.gimp_text_layer_new(
                base_image, "Hausdorff distance: %f" % distance, "Verdana", 14,
                0)
            pdb.gimp_image_insert_layer(base_image, text_layer, None, 0)
            pdb.gimp_layer_translate(text_layer, 5, 5)

            # Merging the layers
            pdb.gimp_layer_set_mode(text_layer, 7)
            pdb.gimp_image_merge_down(base_image, text_layer, 1)
            merged_layer = base_image.layers[0]

            # Saves the merged image
            pdb.gimp_file_save(base_image, merged_layer,
                               '%s/c%d.png' % (path, index), '')

            # Writes the results
            with open("%s/results.csv" % path_to_result_file, 'a') as file:
                file.write("A%d;B%d;%f\n" % (index, index, distance))

            # Close the generated image
            pdb.gimp_image_delete(base_image)
    except Exception as e:
        gimp.message("Unexpected error: %s." % e.message)
        gimp.message("It was not possible to calculate the distance.")
def get_outline_pixels_positions(image, layer, color, fill_color):
    """ Create the outline and search the pixels of the outline.

        Args:
            image (gimp.Image): the image over we make the transformation
            layer (gimp.Drawable): the layer we transformate
            color (gimpcolor.RGB): the outline's color
            fill_color (gimpcolor.tuple): the other color

        Returns:
            list: the list of the outline pixels
    """

    gimp.progress_init("Searching the outline pixels for the layer...")

    # Firstly retrieves the bounding box of the area of interest
    pdb.gimp_image_select_color(image, 0, layer, color)
    no_null_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image)

    # Initially searches the first pixel colored with the target color
    target_pixels = []

    # Searches left to right, up and down
    target_pixels.append(first_discovered_pixel(layer, color, x1, y1, x2, y2))

    # Searches right to left, up and down
    target_pixels.append(first_discovered_pixel(layer, color, x2, y1, x1, y2))

    # Searches left to right, down to up
    target_pixels.append(first_discovered_pixel(layer, color, x1, y2, x2, y1))

    # Searches right to left, down to up
    target_pixels.append(first_discovered_pixel(layer, color, x2, y2, x1, y1))

    for target_pixel in target_pixels:

        # Selects the target area
        pdb.gimp_image_select_contiguous_color(image, 0, layer,
                                               target_pixel[0],
                                               target_pixel[1])

        # Shrinks the selection
        pdb.gimp_selection_shrink(image, 1)

        # Sets the target color in the palette
        pdb.gimp_context_set_foreground(
            RGB(fill_color.r if fill_color.r < 1.0 else fill_color.r / 255.0,
                fill_color.g if fill_color.g < 1.0 else fill_color.g / 255.0,
                fill_color.b if fill_color.b < 1.0 else fill_color.b / 255.0,
                fill_color.a if fill_color.a < 1.0 else fill_color.a / 255.0))

        # Fills the selection with the target color
        pdb.gimp_edit_bucket_fill(layer, 0, 0, 100, 0, False, 0, 0)

    # Previous returns the outline pixels, controls if there is only
    # one element in the image
    for target_pixel in target_pixels:
        for other_pixel in target_pixels:
            if target_pixel != other_pixel:
                if not are_pixels_connected(layer, color, target_pixel, None,
                                            target_pixel, other_pixel, []):
                    raise Exception(
                        "There are disconnected elements in the image.")

    # Clears an eventual selection on the image
    pdb.gimp_selection_clear(image)

    gimp.progress_init("Saving the outline pixels...")

    return search_outline_pixels(layer, color, target_pixels[0], None, [])