Source code for sdt.image.threshold
# SPDX-FileCopyrightText: 2020 Lukas Schrangl <lukas.schrangl@tuwien.ac.at>
#
# SPDX-License-Identifier: BSD-3-Clause
import math
import numpy as np
import cv2
from . import utils
[docs]def adaptive_thresh(img, block_size, c, smooth=1.5, method="mean"):
"""Generate binary mask from image using adaptive thresholding
The image will be smoothed using a Gaussian blur. The mask is then
calculated using :py:func:`cv2.adaptiveThreshold` from the `OpenCV`
package.
Parameters
----------
img : array-like
Image data
block_size : int
``2 * block_size + 1`` is passed as the the `block_size` parameter
to :py:func:`cv2.adaptiveThreshold` (as it has to be an odd number).
c : float
Passed as the `C` parameter to :py:func:`cv2.adaptiveThreshold`.
smooth : float, optional
Gaussian smoothing radius. Set to 0 to disable. Defaults to 5.
method : {"gaussian", "mean"}, optional
Adaptive method. Defaults to "mean" (i.e.,
``cv2.ADAPTIVE_THRESH_MEAN_C``).
Returns
-------
numpy.ndarray, dtype(bool)
Boolean mask image
"""
if method == "gaussian":
method = cv2.ADAPTIVE_THRESH_GAUSSIAN_C
elif method == "mean":
method = cv2.ADAPTIVE_THRESH_MEAN_C
else:
raise ValueError("Method has to be either \"gaussian\" or \"mean\".")
img = utils.fill_gamut(img, np.uint8)
if smooth > 0:
img = cv2.GaussianBlur(img, (0, 0), smooth)
mask = cv2.adaptiveThreshold(img, 1, method,
cv2.THRESH_BINARY, 2 * block_size + 1, c)
return mask.astype(bool)
[docs]def otsu_thresh(img, factor=1., smooth=1.5):
"""Generate binary mask from image using Otsu's binarization
The image will be smoothed using a Gaussian blur. Otsu's method is used to
calculate a global threshold, which is then applied to the image data.
Parameters
----------
img : array-like
Image data
factor : float
Multiply the result of Otsu's method with this factor to adjust the
threshold.
smooth : float, optional
Gaussian smoothing radius. Set to 0 to disable. Defaults to 5.
Returns
-------
numpy.ndarray, dtype(bool)
Boolean mask image
"""
img = utils.fill_gamut(img, np.uint8)
if smooth > 0:
img = cv2.GaussianBlur(img, (0, 0), smooth)
thresh, mask = cv2.threshold(img, 0, 1,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return img > thresh * factor
[docs]def percentile_thresh(img, percentile, smooth=1.5):
"""Generate binary mask with a threshold based on a percentile
The image will be smoothed using a Gaussian blur. Calculate the
desired percentile as a global threshold, which is then applied to the
image data.
Parameters
----------
img : array-like
Image data
percentile : float
Percentile to be used as a threshold.
smooth : float, optional
Gaussian smoothing radius. Set to 0 to disable. Defaults to 5.
Returns
-------
numpy.ndarray, dtype(bool)
Boolean mask image
"""
img = utils.fill_gamut(img, np.uint8)
if smooth > 0:
img = cv2.GaussianBlur(img, (0, 0), smooth)
return img > np.percentile(img, percentile)