Source code for src.helpers.describe_leaf

"""
Script to provide descriptive information on images of leaves (in the project
format)
"""
__author__ = "Tristan Naidoo"
__maintainer__ = "Tristan Naidoo"
__version__ = "0.0.1"
__email__ = "ndxtri015@myuct.ac.za"
__status__ = "development"

import logging
from typing import List, Tuple

import numpy as np

LOGGER = logging.getLogger(__name__)


[docs]def get_embolism_percent(image: np.array) -> int: """ Returns the % of the image that are embolisms :param image: np.array of a mask :return: percentage of embolisms """ return np.count_nonzero(image == 255) / image.size
[docs]def get_unique_range(image: np.array) -> np.array: """ Gets the unique list of pixel intensities for an image :param image: np.array of a mask :return: an array of unique pixel intensities """ return np.unique(np.array(image))
[docs]def get_unique_leaf_range(images: List[np.array]) -> np.array: """ Gets the unique list of pixel intensities from a list of images :param images: np.array of a mask :return: an array of unique pixel intensities """ unique_range = np.array([]) for i, image in enumerate(images): try: image_range = image pixel_ints_to_add = np.setdiff1d(image_range, unique_range) if pixel_ints_to_add.size != 0: unique_range = np.append(unique_range, pixel_ints_to_add) except TypeError as e: LOGGER.exception(f"image {i} had an issue: \t", e) continue return unique_range
[docs]def binarise_image(image: np.array, lower_bound_255: int = 200, upper_bound_0: int = 55) -> np.array: """ Converts all pixels intensities within range of (lower_bound_255; 255) to 255 and all pixels intensities between (0; upper_bound_0) to 0. The aim is to binarise the image but this depends on the correct choice of boundary parameters. :param image: np.array of a mask :param lower_bound_255: lower bound of the range of values to be casted to 255 :param upper_bound_0: upper bound of the range of values to be casted to 0 :return: an np.array of a mask with only two pixel intensities: 0 and 255 """ image[(image > lower_bound_255) & (image < 255)] = 255 image[(image > 0) & (image < upper_bound_0)] = 0 return image
[docs]def get_intersection(image: np.array, combined_image: np.array) -> Tuple[int, np.array]: """ Calculates the intersection between the current mask and all embolisms contained in previous masks :param image: np.array of a mask :param combined_image: np.array of a combined mask :return: intersection as a % of the image size and an updated combined image """ intersection = np.count_nonzero((combined_image == 255) & (image == 255)) intersection = (intersection / image.size) combined_image[image == 255] = 255 return intersection, combined_image