Source code for crackdect.image_functions

"""
Preprocessing functions for single images

In this module image processing functions for single images are grouped as well as helper functions.
"""
import numpy as np
from skimage.exposure import rescale_intensity
from skimage.util.dtype import dtype_range


[docs]def scale_to(x, x_min=0, x_max=1): """ Linear scaling to new range of values. This function scales the input values from their current range to the given range. Parameters ---------- x: array-like x_min: float Lower boarder of the new range x_max: float Upper boarder of the new range Returns ------- out: Scaled values Examples -------- >>> y = np.array((-1,2,5,7)) >>> scale_to(y, x_min=0, x_max=1) array([0. , 0.375, 0.75 , 1. ]) """ if x.min() == x_min and x.max() == x_max: return x else: temp = (x - np.min(x)) / (np.max(x) - np.min(x)) return temp * (x_max - x_min) + x_min
def _fast_astype(img, dtype): if np.issubdtype(img.dtype.type, dtype): return img else: return img.astype(dtype)
[docs]def detect_changes_division(img1, img2, output_range=None): """ Detect the changes between two images by division. Areas with a lot of change will appear darker and areas with little change bright. The change from img1 to img2 is computed with. :math:`I_d = \\frac{ img2 + 1}{img1 + 1}` The range of the output image is scaled to the range of the datatype of the input image. Parameters ---------- img1: np.ndarray img2: np.ndarray output_range: tuple, optional Range of the output image. This range must be within the possible range of the dtype of the input images. E.g. (0,1) for float images. Returns ------- out: np.ndarray Input dtpye is only converved when an output_range is given. Else the result will have dtype float with a maximal possible range of 0.5-2 """ inp_dtype = img1.dtype.type img1 = _fast_astype(img1, np.floating) img2 = _fast_astype(img2, np.floating) temp = (scale_to(img2) + 1) / (scale_to(img1) + 1) if output_range is not None: return _fast_astype(rescale_intensity(temp, out_range=output_range), inp_dtype) else: return temp
[docs]def detect_changes_subtraction(img1, img2, output_range=None): """ Simple change detection by image subtracting. Areas with a lot of change will appear darker and areas with little change bright. :math:`I_d = I_2 - I_1` Parameters ---------- img1: np.ndarray img2: np.ndarray output_range: tuple, optional Range of the output image. This range must be within the possible range of the dtype of the input images E.g. (0,1) for float images. Returns ------- out: np.ndarray Image as input dtype """ inp_dtype = img1.dtype.type img1 = _fast_astype(img1, np.floating) img2 = _fast_astype(img2, np.floating) if output_range is not None: return _fast_astype(rescale_intensity(img2 - img1, out_range=output_range[::-1]), inp_dtype) else: return _fast_astype(img2-img1, inp_dtype)