Exposure

This module gather some functionalities from the ‘exposure’ module of scikit-image.

These algorithms are useful to stretch intensity images to the whole range of value accessible to a given bit-depth.

timagetk.algorithms.exposure.equalize_adapthist(image, kernel_size=0.2, clip_limit=0.01, nbins=256)[source]

Performs adaptive histogram equalization.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Image from which to extract the slice

  • kernel_size (int or list of int, optional) – Defines the shape of contextual regions used in the algorithm. If iterable is passed, it must have the same number of elements as image.ndim (without color channel). If integer, it is broadcasted to each image dimension. By default, kernel_size is 1/8 of image height by 1/8 of its width.

  • clip_limit (float, optional) – Clipping limit, normalized between 0 and 1 (higher values give more contrast).

  • nbins (int, optional) – Number of gray bins for histogram (“data range”).

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Equalized intensity image

Notes

Obviously this is only for 3D images, with 2D images use global_contrast_stretch.

Beware that, if you don’t specify the threshold, this method will also stretch slices without signal in the case where the observed object is not touching all margins of your image!

Example

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import equalize_adapthist
>>> from timagetk.visu.mplt import grayscale_imshow
>>> from timagetk.visu.stack import stack_browser
>>> from timagetk.visu.mplt import intensity_histogram
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> zsh, ysh, xsh = image.shape
>>> # Slice by slice equalization in 'Z' direction:
>>> out_img = equalize_adapthist(image)
>>> zsl = 15
>>> grayscale_imshow([image, out_img], slice_id=zsl, axis='z', suptitle=f"adaptive histogram equalization (z-slice={zsl}/{zsh})", title=["Original", "Equalized"])
>>> intensity_histogram([image, out_img], suptitle="Effect of adaptive histogram equalization on intensity distribution")
timagetk.algorithms.exposure.gamma_adjust(image, gamma=1.0, gain=1.0)[source]

Performs Gamma Correction on the input image.

Also known as Power Law Transform. This function transforms the input image pixelwise according to the equation O = I**gamma after scaling each pixel to the range 0 to 1.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Input image, can be 2D or 3D.

  • gamma (float, optional) – Non-negative real number. Defaults to 1..

  • gain (float, optional) – The constant multiplier. Defaults to 1..

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Gamma corrected output image.

Notes

For gamma > 1, the output image will be darker than the input image.

For gamma < 1, the output image will be brighter than the input image.

References

Wikipedia - Gamma correction Scikit-image - Adjust gamma

Example

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import gamma_adjust
>>> from timagetk.visu.mplt import grayscale_imshow, image_n_hist
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> zsh, ysh, xsh = image.shape
>>> gamma_range = [0.5, 1.5]
>>> out_imgs = [gamma_adjust(image, gamma) for gamma in gamma_range]
>>> zsl = 15
>>> grayscale_imshow([image] + out_imgs, slice_id=zsl, axis='z', title=["Original"]+[f"Gamma={g}" for g in gamma_range], suptitle=f"Gamma adjustement (z-slice={zsl}/{zsh})")
>>> image_n_hist([image.get_slice(zsl)] + [img.get_slice(zsl) for img in out_imgs], img_title=["Original"]+[f"Gamma={g}" for g in gamma_range], title=f"Gamma adjustement (z-slice={zsl}/{zsh})")
timagetk.algorithms.exposure.global_contrast_stretch(image, pc_min=2, pc_max=99)[source]

Performs global image contrast stretching.

Contrast stretching is here performed using lower and upper percentile of the image intensity values to the min and max value of the image dtype.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Image to stretch, can be 2D or 3D.

  • pc_min (int or float, optional) – Lower percentile to use for image stretching. Defaults to 2.

  • pc_max (int or float, optional) – Upper percentile to use for image stretching. Defaults to 99.

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Stretched image.

Example

>>> from timagetk.algorithms.exposure import global_contrast_stretch
>>> from timagetk.visu.mplt import intensity_histogram
>>> from timagetk.visu.mplt import grayscale_imshow
>>> from timagetk.synthetic_data.wall_image import example_layered_sphere_wall_image
>>> image = example_layered_sphere_wall_image()
>>> stretch_img = global_contrast_stretch(image)
>>> intensity_histogram([image, stretch_img], suptitle="Effect of global stretching on intensity distribution")
>>> grayscale_imshow([image, stretch_img], slice_id=5, title=["Original", "Contrasted"],suptitle="Contrast stretching (z-slice=5/{})".format(img.shape[-1]))
timagetk.algorithms.exposure.log_adjust(image, gain=1, inv=False)[source]

Performs Logarithmic correction on the input image.

This function transforms the input image pixelwise according to the equation O = gain*log(1 + I) after scaling each pixel to the range 0 to 1. For inverse logarithmic correction, the equation is O = gain*(2**I - 1).

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Input image, can be 2D or 3D.

  • gain (float, optional) – The constant multiplier. Default value is 1.

  • inv (float, optional) – If True, it performs inverse logarithmic correction, else correction will be logarithmic. Defaults to False.

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Logarithm corrected output image.

References

Scikit-image - Adjust log

Example

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import log_adjust
>>> from timagetk.visu.mplt import grayscale_imshow, image_n_hist
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> zsh, ysh, xsh = image.shape
>>> gain_range = [0.5, 1.5]
>>> out_imgs = [log_adjust(image, gain) for gain in gain_range]
>>> zsl = 15
>>> grayscale_imshow([image] + out_imgs, slice_id=zsl, axis='z', title=["Original"]+[f"Gain={g}" for g in gain_range], suptitle=f"Log adjustement (z-slice={zsl}/{zsh})")
>>> image_n_hist([image.get_slice(zsl)] + [img.get_slice(zsl) for img in out_imgs], img_title=["Original"]+[f"Gain={g}" for g in gain_range], title=f"Log adjustement (z-slice={zsl}/{zsh})")
timagetk.algorithms.exposure.rescale_intensity(image, in_range='image', out_range='dtype')[source]

Return image after stretching or shrinking its intensity levels.

The desired intensity range of the input and output, in_range and out_range respectively, are used to stretch or shrink the intensity range of the input image.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Input intensity image, can be 2D or 3D.

  • in_range (str or 2-tuple, optional) – Min and max intensity values of input and output image. The possible string values for these parameters are ‘image’ or ‘dtype’.

  • out_range (str or 2-tuple, optional) – Min and max intensity values of input and output image. The possible string values for these parameters are ‘image’ or ‘dtype’.

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Image after intensity rescaling. This image has the same dtype as the input image.

Notes

Details about in_range & out_range values:

  • image: use image min/max as the intensity range.

  • dtype: use min/max of the image’s dtype as the intensity range.

  • 2-tuple: explicit values for min & max intensities.

Examples

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import rescale_intensity
>>> from timagetk.visu.mplt import image_n_hist
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> print(f"Original image range: {image.min()}, {image.max()}")
Original image range: 10, 255
>>> # Example #1: Rescale min/max of image to dtype (here 0-255):
>>> out_img = rescale_intensity(image, in_range='image')
>>> print(f"Rescaled image range: {out_img.min()}, {out_img.max()}")
Rescaled image range: 0, 255
>>> zsl = 15
>>> image_n_hist([image.get_slice(zsl), out_img.get_slice(zsl)], img_title=["Original", "Rescaled"], title="Intensity rescaling")
>>> # Example #2: Rescale image to dtype (here 0-255):
>>> out_img = rescale_intensity(image, in_range=(10, 200))
>>> print(f"Rescaled image range: {out_img.min()}, {out_img.max()}")
>>> zsl = 15
>>> image_n_hist([image.get_slice(zsl), out_img.get_slice(zsl)], img_title=["Original", "Rescaled"], title="Intensity rescaling")
timagetk.algorithms.exposure.sigmoid_adjust(image, cutoff=0.5, gain=10, inv=False)[source]

Performs Sigmoid Correction on the input image.

Also known as Contrast Adjustment. This function transforms the input image pixelwise according to the equation: O = 1/(1 + exp*(gain*(cutoff - I))) after scaling each pixel to the range 0 to 1.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Input image, can be 2D or 3D.

  • cutoff (float, optional) – Cutoff of the sigmoid function that shifts the characteristic curve in horizontal direction. Defaults to 0.5.

  • gain (float, optional) – The constant multiplier in exponential’s power of sigmoid function. Defaults to 10.

  • inv (bool, optional) – If True, returns the negative sigmoid correction. Defaults to False.

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Sigmoid corrected output image.

References

Gustav J. Braun, Image Lightness Rescaling Using Sigmoidal Contrast Enhancement Functions PDF

Scikit-image - Sigmoid adjust

Example

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import sigmoid_adjust
>>> from timagetk.visu.mplt import grayscale_imshow, image_n_hist
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> zsh, ysh, xsh = image.shape
>>> cutoff_range = [0.2, 0.5, 0.8]
>>> out_imgs = [sigmoid_adjust(image, gain) for gain in cutoff_range]
>>> zsl = 15
>>> grayscale_imshow([image] + out_imgs, slice_id=zsl, axis='z', title=["Original"]+[f"Cutoff={co}" for co in cutoff_range], suptitle=f"Sigmoid adjustement (z-slice={zsl}/{zsh})")
>>> image_n_hist([image.get_slice(zsl)] + [img.get_slice(zsl) for img in out_imgs], img_title=["Original"]+[f"Cutoff={co}" for co in cutoff_range], title=f"Sigmoid adjustement (z-slice={zsl}/{zsh})")
timagetk.algorithms.exposure.slice_contrast_stretch(image, pc_min=2, pc_max=99, axis='z', threshold=None)[source]

Performs slice by slice contrast stretching.

Contrast stretching is here performed using lower and upper percentile of the image values to the min and max value of the image dtype.

Parameters:
  • image (timagetk.SpatialImage or timagetk.MultiChannelImage) – Image to stretch, can be 2D or 3D.

  • pc_min (int or float, optional) – Lower percentile to use for image stretching. Defaults to 2.

  • pc_max (int or float, optional) – Upper percentile to use for image stretching. Defaults to 99.

  • axis (str in {'z', 'y', 'x'}, optional) – Selected axe to move along, ‘z’ by default.

  • threshold (int, optional) – Intensity threshold of slice to equalize, slices with a max intensity value below this one will be ignored. By default, no threshold is used

  • channel (str) – If a MultiChannelImage is used as input image, the algorithm will be applied only to this channel. Else it will be applied to all channels of the multichannel image.

Returns:

timagetk.SpatialImage – Stretched image.

Notes

Obviously this is only for 3D images, with 2D images use global_contrast_stretch.

Beware that, if you don’t specify the threshold, this method will also stretch slices without signal in the case where the observed object is not touching all margins of your image!

Example

>>> from timagetk.io.util import shared_dataset
>>> from timagetk.io import imread
>>> from timagetk.algorithms.exposure import slice_contrast_stretch
>>> from timagetk.visu.mplt import grayscale_imshow
>>> from timagetk.visu.mplt import intensity_histogram
>>> image_path = shared_dataset("p58")[0]
>>> image = imread(image_path)
>>> zsh, ysh, xsh = image.shape
>>> # Slice by slice contrast in 'Z' direction:
>>> out_img = slice_contrast_stretch(image)
>>> zsl = 15
>>> grayscale_imshow([image, out_img], slice_id=zsl, axis='z', title=["Original", "Contrasted"], suptitle=f"Contrast stretching (z-slice={zsl}/{zsh})")
>>> intensity_histogram([image, out_img], suptitle="Effect of slice-by-slice stretching on intensity distribution")