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)