Source code for cbi_toolbox.reconstruct.preprocess

"""
The preprocess module implements functions to preprocess experimental images.
"""

# Copyright (c) 2020 Idiap Research Institute, http://www.idiap.ch/
# Written by François Marelli <francois.marelli@idiap.ch>
#
# This file is part of CBI Toolbox.
#
# CBI Toolbox is free software: you can redistribute it and/or modify
# it under the terms of the 3-Clause BSD License.
#
# CBI Toolbox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 3-Clause BSD License for more details.
#
# You should have received a copy of the 3-Clause BSD License along
# with CBI Toolbox. If not, see https://opensource.org/licenses/BSD-3-Clause.
#
# SPDX-License-Identifier: BSD-3-Clause

import cv2
import numpy as np


[docs]def erase_corners(image_array, corner_size=300): """ Fill the corners of the image with the closest pixel value. This is useful when a diaphragm is visible in the field of view. Parameters ---------- image_array : numpy.ndarray The original image. corner_size : int, optional The size of the corner to fill, by default 300 Returns ------- numpy.ndarray The new image with corners filled. """ if corner_size > 0: image_array[..., :corner_size, :corner_size] = image_array[ ..., corner_size, corner_size, None, None ] image_array[..., :corner_size, -corner_size:] = image_array[ ..., corner_size, -corner_size, None, None ] image_array[..., -corner_size:, -corner_size:] = image_array[ ..., -corner_size, -corner_size, None, None ] image_array[..., -corner_size:, :corner_size] = image_array[ ..., -corner_size, corner_size, None, None ] return image_array
[docs]def transmission_to_absorption(image_array, max_value=4096): """ Convert a transmission image into an absorption one. This inverses the black-white contrast. Parameters ---------- image_array : numpy.ndarray The absorption image. max_value : float, optional The max value for scaling the original image, by default 4096. Returns ------- numpy.ndarray The absorption contrast image. """ scaled_array = image_array / max_value absorption = np.log(1 / scaled_array) return absorption
[docs]def remove_background_illumination( image_array, threshold=0.5, hole_size=250, margin_size=100, border_axis=-1 ): """ Removes the background illumination from images using thresholding and morphological filtering. Parameters ---------- image_array : numpy.ndarray The images to be processed as a 3D array, the first dimension iterates over the different images. threshold : float, optional The relative threshold used to detect background, by default 0.5. hole_size : int, optional Biggest holes removed by filtering, by default 250. margin_size : int, optional Margin kept around the useful information, by default 100. border_axis : int, optional Axis used to detect the outer edge of the image, by default -1. Returns ------- numpy.ndarray The array of images without background illumination. """ mask_bool = image_array < threshold mask_int = mask_bool.astype(np.uint8) kernel_open = np.ones((hole_size, hole_size), dtype=np.uint8) kernel_dilate = np.ones((margin_size, margin_size), dtype=np.uint8) if border_axis < 0: contour_border_axis = border_axis else: contour_border_axis = border_axis - 1 for plane_idx, plane_mask in enumerate(mask_int): find_contours = cv2.findContours( plane_mask, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE ) major = cv2.__version__.split(".")[0] if major == "2": contours = find_contours[1] else: contours = find_contours[0] plane_mask.fill(0) for index, contour in enumerate(contours): if len(contour) > 500 and ( contour[..., contour_border_axis].max() == image_array.shape[border_axis] - 1 or (contour[..., contour_border_axis].min() == 0) ): temp_mask = np.zeros_like(mask_int[plane_idx, ...]) cv2.drawContours(temp_mask, contours, index, 1, cv2.FILLED) temp_mask = cv2.morphologyEx(temp_mask, cv2.MORPH_CLOSE, kernel_open) mask_int[plane_idx, ...] |= temp_mask mask_int[plane_idx, ...] = cv2.morphologyEx( mask_int[plane_idx, ...], cv2.MORPH_ERODE, kernel_dilate ) mask_bool = mask_int.astype(bool) image_array[mask_bool] = 0 return image_array