Source code for darsia.signals.reduction.monochromatic
"""
Module providing dimension reductions to monochromatic/scalar signals.
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np
import skimage
import darsia
[docs]
class MonochromaticReduction(darsia.SignalReduction):
def __init__(self, **kwargs) -> None:
self.color = kwargs.get("color", "gray")
self.verbosity = kwargs.get("verbosity", 0)
if self.color in ["hsv"]:
self.hue_lower_bound = kwargs.get("hue lower bound", 0.0)
self.hue_upper_bound = kwargs.get("hue upper bound", 360.0)
self.saturation_lower_bound = kwargs.get("saturation lower bound", 0.0)
self.saturation_upper_bound = kwargs.get("saturation upper bound", 1.0)
# FIXME and remove
if self.color == "hsv-after":
raise ValueError("Rename to 'hsv'.")
def __call__(self, img: np.ndarray) -> np.ndarray:
"""
Make a mono-colored image from potentially multi-colored image.
Args:
img (np.ndarray): image
Returns:
np.ndarray: monochromatic reduction of the array
"""
if self.color == "hsv":
hsv = skimage.color.rgb2hsv(img)
# Plot Hue and Saturation channels, allowing to manually tune
# the concentration analysis.
if self.verbosity >= 2:
plt.figure("hue")
plt.imshow(hsv[:, :, 0])
plt.figure("saturation")
plt.imshow(hsv[:, :, 1])
# Restrict to user-defined thresholded hue and saturation values.
mask_hue = np.logical_and(
hsv[:, :, 0] > self.hue_lower_bound,
hsv[:, :, 0] < self.hue_upper_bound,
)
mask_saturation = np.logical_and(
hsv[:, :, 1] > self.saturation_lower_bound,
hsv[:, :, 1] < self.saturation_upper_bound,
)
mask = np.logical_and(mask_hue, mask_saturation)
# Consider value
img_v = hsv[:, :, 2]
img_v[~mask] = 0
return img_v
elif self.color == "gray":
# Assume RGB input. NOTE: Make sure that the input is in correct
# format (CV2 requires np.float32).
return cv2.cvtColor(img.astype(np.float32), cv2.COLOR_RGB2GRAY)
elif self.color == "red":
return img[:, :, 0]
elif self.color == "green":
return img[:, :, 1]
elif self.color == "blue":
return img[:, :, 2]
elif self.color == "red+green":
return img[:, :, 0] + img[:, :, 1]
elif self.color == "negative-key":
cmy = 1 - img
key = np.min(cmy, axis=2)
return 1 - key
elif callable(self.color):
return self.color(img)
elif self.color == "":
return img
else:
raise ValueError(f"Mono-colored space {self.color} not supported.")