Skip to content

Scars Module

Image artefact correction functions that interpolates values filling the space of any detected scars.

remove_scars(img, filename, removal_iterations=2, threshold_low=0.25, threshold_high=0.666, max_scar_width=4, min_scar_length=16)

Remove scars from an image.

Scars are long, typically 1-4 pixels wide streaks of high or low data in AFM images. They are a problem resulting from random errors in the AFM data collection process and are hard to avoid. This function detects and removes these artefacts by interpolating over them between the pixels above and below them. This method takes no parameters as it uses parameters already established as instance variables when the class was instantiated.

Parameters

img : npt.NDArray A 2-D image to remove scars from. filename : str The filename (used for logging outputs only). removal_iterations : int The number of times the scar removal should run on the image. Running just once sometimes isn't enough to remove some of the more difficult to remove scars. threshold_low : float A value that when multiplied with the standard deviation, acts as a threshold to determine if an increase or decrease in height might constitute the top or bottom of a scar. threshold_high : float A floating point value that is used similarly to threshold_low, however sharp inclines or descents that result in values in the mask higher than this threshold are automatically considered scars. max_scar_width : int A value that dictates the maximum width that a scar can be. Note that this does not mean horizontal width, rather vertical, this is because we consider scars to be laying flat, horizontally, so their width is vertical and their length is horizontal. min_scar_length : int An integer that restricts the algorithm to only mark scars that are as long or longer than this length. This is important for ensuring that noise or legitimate but sharp datapoints do not get detected as scars. Note that length here is horizontal, as scars are thin, horizontal features.

Returns

self.img The original 2-D image with scars removed, unless the config has run set to False, in which case it will not remove the scars.

Source code in topostats/scars.py
def remove_scars(
    img: npt.NDArray,
    filename: str,
    removal_iterations: int = 2,
    threshold_low: float = 0.250,
    threshold_high: float = 0.666,
    max_scar_width: int = 4,
    min_scar_length: int = 16,
):
    """
    Remove scars from an image.

    Scars are long, typically 1-4 pixels wide streaks of high or low data in AFM images. They are a problem
    resulting from random errors in the AFM data collection process and are hard to avoid. This function
    detects and removes these artefacts by interpolating over them between the pixels above and below them.
    This method takes no parameters as it uses parameters already established as instance variables when the
    class was instantiated.

    Parameters
    ----------
    img : npt.NDArray
        A 2-D image to remove scars from.
    filename : str
        The filename (used for logging outputs only).
    removal_iterations : int
        The number of times the scar removal should run on the image.
        Running just once sometimes isn't enough to remove some of the
        more difficult to remove scars.
    threshold_low : float
        A value that when multiplied with the standard deviation, acts as a threshold to determine if an increase
        or decrease in height might constitute the top or bottom of a scar.
    threshold_high : float
        A floating point value that is used similarly to threshold_low, however sharp inclines or descents
        that result in values in the mask higher than this threshold are automatically considered scars.
    max_scar_width : int
        A value that dictates the maximum width that a scar can be. Note that this does not mean horizontal width,
        rather vertical, this is because we consider scars to be laying flat, horizontally, so their width is
        vertical and their length is horizontal.
    min_scar_length : int
        An integer that restricts the algorithm to only mark scars that are as long or longer than this length.
        This is important for ensuring that noise or legitimate but sharp datapoints do not get detected as scars.
        Note that length here is horizontal, as scars are thin, horizontal features.

    Returns
    -------
    self.img
        The original 2-D image with scars removed, unless the config has run set to False, in which case it
        will not remove the scars.
    """
    LOGGER.info(f"[{filename}] : Removing scars")

    first_marked_mask = None
    for i in range(removal_iterations):
        marked_positive = _mark_scars(
            img=img,
            direction="positive",
            threshold_low=threshold_low,
            threshold_high=threshold_high,
            max_scar_width=max_scar_width,
            min_scar_length=min_scar_length,
        )
        marked_negative = _mark_scars(
            img=img,
            direction="negative",
            threshold_low=threshold_low,
            threshold_high=threshold_high,
            max_scar_width=max_scar_width,
            min_scar_length=min_scar_length,
        )
        # Combine the upper and lower scar masks
        marked_both = np.bitwise_or(marked_positive.astype(bool), marked_negative.astype(bool))

        if i == 0:
            first_marked_mask = marked_both

        _remove_marked_scars(img, np.copy(marked_both))

        LOGGER.debug("Scars removed")

    return img, first_marked_mask

handler: python options: docstring_style: numpy rendering: show_signature_annotations: true