Source code for ddd_pylib.image_manip._normalize_operator

from ddd_pylib._base import ImageOperator
import xarray as xr
import numpy as np
from typing import Tuple


[docs] class NormalizeOperator(ImageOperator): """ Take an image and normalizes it. If the image has a time axis (T), it is possible with setIndividualTimePoints to normalize them individually or to use the global range of values. It is also possible to set a range in which the image should be normalized with setTargetRange. """ def __init__(self): super().__init__() self._individualTimePoints = self.defaultIndividualTimePoints() self._targetRange = self.defaultTargetRange() self._extremas = None
[docs] @staticmethod def defaultIndividualTimePoints(): return False
[docs] @staticmethod def defaultTargetRange(): return None
[docs] def setIndividualTimePoints(self, individual: bool): """ Set whether to normalize individual time points or use the global range. """ self._individualTimePoints = individual
[docs] def setTargetRange(self, target_range: tuple): """ Set the target range in which the images should be normalized. Args: target_range: The target range as a tuple. """ start, end = target_range if start >= end: raise ValueError("Range length can't be 0 or under") if start < 0: raise ValueError("Range start can't be negative") self._targetRange = target_range
[docs] def getTargetRange(self) -> Tuple: """ Return the target range in which the images should be normalized. """ if self._targetRange is not None: return self._targetRange else: dt = self.getMainImage().dtype if np.issubdtype(dt, np.floating): return (0.0, 1.0) if np.issubdtype(dt, np.integer): info = np.iinfo(dt) return (info.min, info.max) raise ValueError("Cannot determine target range for the image type.")
def _processExtremas(self): img = self.getMainImage() if self._individualTimePoints: self._extremas = [ (img.isel(T=t).values.min(), img.isel(T=t).values.max()) for t in range(self.getNTimePoints()) ] else: self._extremas = [ (img.values.min(), img.values.max()) ] * self.getNTimePoints() def _normalize( self, image: xr.DataArray, extremas: Tuple[int, int] ) -> xr.DataArray: lower, upper = extremas vals = image.values.astype(np.float32) vals = (vals - lower) / (upper - lower) start, end = self.getTargetRange() vals = vals * (end - start) + start return xr.DataArray( data=vals, dims=image.dims, attrs=image.attrs.copy() ).astype(image.dtype) def _applyToFrame(self, frameData, t, nT): if self._extremas is None: raise ValueError( "Extremas have not been processed. Call _processExtremas() before applying normalization." ) return self._normalize(frameData[0], self._extremas[t]) def _run(self): self._processExtremas() yield from super()._run()
[docs] def getPrefix(self): return "Normalized-"