Source code for ddd_pylib.image_manip._rescale_operator

from ddd_pylib._base import ImageOperator
import xarray as xr
import numpy as np
from scipy.ndimage import zoom


[docs] class RescaleOperator(ImageOperator): """ Applies rescaling to the input image based on the specified scale factors for each axis and the chosen interpolation method. The time axis cannot be rescaled. Different interpolation methods are available, including 'Nearest', 'Linear', and 'Cubic'. """ _INTERPOLATION = {"Nearest": 0, "Linear": 1, "Cubic": 3} def __init__(self): super().__init__() self._scale = self.defaultScale() self._interpolation = self.defaultInterpolation()
[docs] @staticmethod def defaultInterpolation() -> str: return "Linear"
[docs] @staticmethod def defaultScale() -> dict: return {"Z": 1.0, "Y": 1.0, "X": 1.0}
[docs] def getPrefix(self) -> str: return f"Rescaled[{self._interpolation}]-"
[docs] def setScale(self, scale: dict): """ Set the scale factor of each dimensions Args: scale: Dictionary with axis as keys and their scale factor as values """ if scale is None or not ( np.issubdtype(np.array(list(scale.values())).dtype, np.integer) or np.issubdtype(np.array(list(scale.values())).dtype, np.floating) ): raise ValueError("Wrong scale type") conservedValues = self._scale.copy() for axis in conservedValues.keys(): conservedValues[axis] = scale.get(axis, conservedValues[axis]) self._scale = conservedValues
[docs] def setInterpolation(self, interpolation: str): """ Set the interpolation method. Args: interpolation: 'Nearest', 'Linear', or 'Cubic' """ if interpolation not in self._INTERPOLATION: raise ValueError(f"Interpolation method '{interpolation}' is not valid.") self._interpolation = interpolation
[docs] def getInterpolation(self) -> str: """ Return the active interpolation method """ return self._interpolation
[docs] def getScale(self) -> dict: """ Return the new scale in which the image will be rescaled """ return self._scale
[docs] def sanityCheck(self): super().sanityCheck() if self._interpolation not in self._INTERPOLATION: raise ValueError( f"Interpolation method '{self._interpolation}' is not valid." ) if any(np.isclose(scale, 0.0) for scale in self._scale.values()): raise ValueError("Scale factors must not be null")
def _rescaleImage( self, image: xr.DataArray, scale: dict, interpolation: str ) -> xr.DataArray: zoom_factors = [scale.get(dim, 1.0) for dim in image.dims] order = self._INTERPOLATION.get(interpolation, 1) rescaled_data = zoom(image.data, zoom_factors, order=order) new_attrs = image.attrs.copy() if "scale" in new_attrs: for ax in new_attrs["scale"]: new_attrs["scale"][ax] /= scale.get(ax, 1.0) return xr.DataArray(data=rescaled_data, dims=image.dims, attrs=new_attrs) def _applyToFrame(self, frameData, t, nT): imA = frameData[0].copy() return self._rescaleImage(imA, self._scale, self._interpolation)