Source code for wsireg.parameter_maps.preprocessing

from enum import Enum
from typing import Callable, Dict, List, NamedTuple, Optional, Tuple, Union

from pydantic import BaseModel, validator


[docs] class ImageType(str, Enum): """Set the photometric interpretation of the image * "FL": background is black (fluorescence) * "BF": Background is white (brightfield) """ DARK = "FL" LIGHT = "BF"
[docs] class CoordinateFlip(str, Enum): """Coordinate flip options * "h" : horizontal flip * "v" : vertical flip """ HORIZONTAL = "h" VERTIAL = "v"
[docs] class BoundingBox(NamedTuple): """ Bounding box named tuple. """ X: int Y: int WIDTH: int HEIGHT: int
def _transform_to_bbox(mask_bbox: Union[Tuple[int, int, int, int], List[int]]): if mask_bbox is not None: return BoundingBox(*mask_bbox) def _index_to_list(ch_indices: Union[int, List[int]]): if isinstance(ch_indices, int): ch_indices = [ch_indices] return ch_indices def _transform_custom_proc( custom_procs: Union[List[Callable], Tuple[Callable, ...]] ): return { f"custom processing {str(idx+1).zfill(2)}": proc for idx, proc in enumerate(custom_procs) }
[docs] class ImagePreproParams(BaseModel): """Preprocessing parameter model Attributes ---------- image_type: ImageType Whether image is dark or light background. Light background images are intensity inverted by default max_int_proj: bool Perform max intensity projection number of channels > 1. contrast_enhance: bool Enhance contrast of image ch_indices: list of int or int Channel indicies to use for registartion, 0-index, so ch_indices = 0, pulls the first channel as_uint8: bool Whether to byte scale registration image data for memory saving invert_intensity: bool invert the intensity of an image rot_cc: int, float Rotate image counter-clockwise by degrees, can be positive or negative (cw rot) flip: CoordinateFlip, default: None flip coordinates, "v" = vertical flip, "h" = horizontal flip crop_to_mask_bbox: bool Convert a binary mask to a bounding box and crop to this area mask_bbox: tuple or list of 4 ints supply a pre-computed list of bbox info of form x,y,width,height downsampling: int Downsampling by integer factor, i.e., downsampling = 3, downsamples image 3x use_mask: bool Whether to use mask in elastix registration. At times it is better to use the mask to find a cropping area then use the mask during the registration process as errors are frequent custom_processing: callable Custom intensity preprocessing functions in a dict like {"my_custom_process: custom_func} that will be applied to the image. Must take in an sitk.Image and return an sitk.Image """ # intensity preprocessing image_type: ImageType = ImageType.DARK max_int_proj: bool = True ch_indices: Optional[List[int]] = None as_uint8: bool = True contrast_enhance: bool = False invert_intensity: bool = False custom_processing: Optional[Dict[str, Callable]] = None # spatial preprocessing rot_cc: Union[int, float] = 0 flip: Optional[CoordinateFlip] = None crop_to_mask_bbox: bool = False mask_bbox: Optional[BoundingBox] = None downsampling: int = 1 use_mask: bool = True @validator('mask_bbox', pre=True) def _make_bbox(cls, v): return _transform_to_bbox(v) @validator('ch_indices', pre=True) def _make_ch_list(cls, v): return _index_to_list(v) @validator('custom_processing', pre=True) def _check_custom_prepro(cls, v): if isinstance(v, (list, tuple)): return _transform_custom_proc(v) else: return v # make sure serialization to dict is json like # for saving YAML file
[docs] def dict(self, **kwargs): output = super().dict(**kwargs) for k, v in output.items(): if isinstance(v, Enum): output[k] = v.value return output
[docs] class Config: use_enum_names = True