def layout_analysis_output(args):
    ground_truth_folder = args.ground_truth_folder
    network_output_folder = args.network_output_folder
    output_folder = os.path.join(args.output_folder,
                                 'layout_analysis_evaluation')

    gt_img_paths = get_img_paths(ground_truth_folder)
    segm_img_paths = get_img_paths(network_output_folder)

    if not output_folder:
        output_folder = os.path.join(os.path.dirname(segm_img_paths),
                                     'layout_analysis_evaluation')

    for gt, segm in zip(gt_img_paths, segm_img_paths):
        gt_image = np.array(pil_loader(gt))
        segm_image = np.array(pil_loader(segm))

        generate_layout_analysis_output(output_folder, gt_image, segm_image,
                                        os.path.basename(gt))

    # create a legend and save it
    make_colour_legend_image(
        os.path.join(output_folder, "layout_analysis_eval_legend"),
        CLASS_COLOUR_ENCODINGS)
def generate_layout_analysis_output(output_folder,
                                    gt_image,
                                    segm_image,
                                    output_name,
                                    legend=False):
    """
    This function generates and saves an output like the one generated from the Output image as described in https://github.com/DIVA-DIA/DIVA_Layout_Analysis_Evaluator

    Parameters
    ----------
    output_folder: string
        folder where the output is saved to
    gt_image: numpy array
        ground truth image in RGB
    segm_image: numpy array
        segmentation output in RGB
    output_name: string
        name of the output image
    legend: Boolaen
        set to true if legend should also be generated
    Returns
    -------
    None (saves output)
    """
    dest_filename = os.path.join(output_folder, output_name)
    if not os.path.exists(os.path.dirname(dest_filename)):
        os.makedirs(os.path.dirname(dest_filename))

    img_la = np.zeros(segm_image.shape)

    # Extract just blue channel
    out_blue = segm_image[:, :, 2]  #[2140:2145, 1570:1575]
    gt_blue = gt_image[:, :, 2]  #[2140:2145, 1570:1575]

    # subtract the boundary pixel from the gt
    boundary_pixel = gt_image[:, :, 0].astype(np.uint8) == 128
    gt_blue[boundary_pixel] = 1

    # get the colour masks
    masks = {
        c: _get_mask(c, out_blue, gt_blue)
        for c in CLASS_COLOUR_ENCODINGS.keys()
    }

    # colour the pixels according to the masks
    for c, mask in masks.items():
        img_la[mask] = CLASS_COLOUR_ENCODINGS[c]

    # correct for boundary pixels
    boundary_masks = _get_boundary_masks(out_blue, gt_blue, boundary_pixel)
    # colour the pixels according to the masks
    for c, mask in boundary_masks.items():
        img_la[mask] = CLASS_COLOUR_ENCODINGS[c]

    # save the output
    result = Image.fromarray(img_la.astype(np.uint8))
    result.save(dest_filename)

    if legend:
        make_colour_legend_image(
            os.path.join(os.path.dirname(dest_filename),
                         "layout_analysis_eval_legend"),
            CLASS_COLOUR_ENCODINGS)
def _save_output_evaluation(class_encodings, output_encoded, gt_image, tag, multi_run=None):
    """Utility function to save image in the output folder and also log it to Tensorboard.

    Parameters
    ----------
    class_encodings : List
        Contains the range of encoded classes
    tag : str
        Name of the image.
    output_encoded : ndarray [W x H x C] in RGB
        Image to be saved
    gt_image : ndarray [W x H x C] in RGB
        Image to be saved
    multi_run : int
        Epoch/Mini-batch counter.

    Returns
    -------
    None

    """
    # ##################################################################################################################
    # 1. Create true output

    # Get output folder using the FileHandler from the logger.
    # (Assumes the file handler is the last one)
    output_folder = os.path.dirname(logging.getLogger().handlers[-1].baseFilename)
    dest_filename = os.path.join(output_folder, 'images', "output", tag  if multi_run is None else tag + '_{}'.format(multi_run))
    if not os.path.exists(os.path.dirname(dest_filename)):
        os.makedirs(os.path.dirname(dest_filename))

    # Save the output
    Image.fromarray(output_encoded.astype(np.uint8)).save(dest_filename)

    # ##################################################################################################################
    # 2. Make a more human readable output -> one colour per class
    tag_col = "coloured/" + tag

    dest_filename = os.path.join(output_folder, 'images', tag_col if multi_run is None else tag_col + '_{}'.format(multi_run))
    if not os.path.exists(os.path.dirname(dest_filename)):
        os.makedirs(os.path.dirname(dest_filename))

    img = np.copy(output_encoded)
    blue = output_encoded[:, :, 2]  # Extract just blue channel

    # Colours are in RGB
    cmap = matplotlib.cm.get_cmap('Spectral')
    colors = [cmap(i / len(class_encodings), bytes=True)[:3] for i in range(len(class_encodings))]

    # Get the mask for each colour
    masks = {color: (blue == i) > 0 for color, i in zip(colors, class_encodings)}

    # Color the image with relative colors
    for color, mask in masks.items():
        img[mask] = color

    # Make and save the class color encoding
    color_encoding = {str(i): color for color, i in zip(colors, class_encodings)}

    make_colour_legend_image(os.path.join(os.path.dirname(dest_filename), "output_visualizations_colour_legend.png"),
                             color_encoding)

    # Write image to output folder
    Image.fromarray(img.astype(np.uint8)).save(dest_filename)

    # ##################################################################################################################
    # 3. Layout analysis evaluation
    # Output image as described in https://github.com/DIVA-DIA/DIVA_Layout_Analysis_Evaluator

    tag_la = "layout_analysis_evaluation/" + tag

    dest_filename = os.path.join(output_folder, 'images', tag_la if multi_run is None else tag_la + '_{}'.format(multi_run))
    if not os.path.exists(os.path.dirname(dest_filename)):
        os.makedirs(os.path.dirname(dest_filename))

    generate_layout_analysis_output(os.path.join(output_folder, 'images'), gt_image, output_encoded, dest_filename, legend=True)