Source code for anomalib.pre_processing.pre_process
"""Pre Process.This module contains `PreProcessor` class that applies preprocessingto an input image before the forward-pass stage."""# Copyright (C) 2022 Intel Corporation# SPDX-License-Identifier: Apache-2.0fromtypingimportOptional,Tuple,UnionimportalbumentationsasAfromalbumentations.pytorchimportToTensorV2
[docs]classPreProcessor:"""Applies pre-processing and data augmentations to the input and returns the transformed output. Output could be either numpy ndarray or torch tensor. When `PreProcessor` class is used for training, the output would be `torch.Tensor`. For the inference it returns a numpy array. Args: config (Optional[Union[str, A.Compose]], optional): Transformation configurations. When it is ``None``, ``PreProcessor`` only applies resizing. When it is ``str`` it loads the config via ``albumentations`` deserialisation methos . Defaults to None. image_size (Optional[Union[int, Tuple[int, int]]], optional): When there is no config, ``image_size`` resizes the image. Defaults to None. to_tensor (bool, optional): Boolean to check whether the augmented image is transformed into a tensor or not. Defaults to True. Examples: >>> import skimage >>> image = skimage.data.astronaut() >>> pre_processor = PreProcessor(image_size=256, to_tensor=False) >>> output = pre_processor(image=image) >>> output["image"].shape (256, 256, 3) >>> pre_processor = PreProcessor(image_size=256, to_tensor=True) >>> output = pre_processor(image=image) >>> output["image"].shape torch.Size([3, 256, 256]) Transforms could be read from albumentations Compose object. >>> import albumentations as A >>> from albumentations.pytorch import ToTensorV2 >>> config = A.Compose([A.Resize(512, 512), ToTensorV2()]) >>> pre_processor = PreProcessor(config=config, to_tensor=False) >>> output = pre_processor(image=image) >>> output["image"].shape (512, 512, 3) >>> type(output["image"]) numpy.ndarray Transforms could be deserialized from a yaml file. >>> transforms = A.Compose([A.Resize(1024, 1024), ToTensorV2()]) >>> A.save(transforms, "/tmp/transforms.yaml", data_format="yaml") >>> pre_processor = PreProcessor(config="/tmp/transforms.yaml") >>> output = pre_processor(image=image) >>> output["image"].shape torch.Size([3, 1024, 1024]) """def__init__(self,config:Optional[Union[str,A.Compose]]=None,image_size:Optional[Union[int,Tuple]]=None,to_tensor:bool=True,)->None:self.config=configself.image_size=image_sizeself.to_tensor=to_tensorself.transforms=self.get_transforms()
[docs]defget_transforms(self)->A.Compose:"""Get transforms from config or image size. Returns: A.Compose: List of albumentation transformations to apply to the input image. """ifself.configisNoneandself.image_sizeisNone:raiseValueError("Both config and image_size cannot be `None`. ""Provide either config file to de-serialize transforms ""or image_size to get the default transformations")transforms:A.Composeifself.configisNoneandself.image_sizeisnotNone:height,width=self._get_height_and_width()transforms=A.Compose([A.Resize(height=height,width=width,always_apply=True),A.Normalize(mean=(0.485,0.456,0.406),std=(0.229,0.224,0.225)),ToTensorV2(),])ifself.configisnotNone:ifisinstance(self.config,str):transforms=A.load(filepath=self.config,data_format="yaml")elifisinstance(self.config,A.Compose):transforms=self.configelse:raiseValueError("config could be either ``str`` or ``A.Compose``")ifnotself.to_tensor:ifisinstance(transforms[-1],ToTensorV2):transforms=A.Compose(transforms[:-1])# always resize to specified image sizeifnotany(isinstance(transform,A.Resize)fortransformintransforms)andself.image_sizeisnotNone:height,width=self._get_height_and_width()transforms=A.Compose([A.Resize(height=height,width=width,always_apply=True),transforms])returntransforms
[docs]def_get_height_and_width(self)->Tuple[Optional[int],Optional[int]]:"""Extract height and width from image size attribute."""ifisinstance(self.image_size,int):returnself.image_size,self.image_sizeifisinstance(self.image_size,tuple):returnint(self.image_size[0]),int(self.image_size[1])ifself.image_sizeisNone:returnNone,NoneraiseValueError("``image_size`` could be either int or Tuple[int, int]")