def apply_augmentations( self, augmentations: List[Union[Augmentation, Transform]]) -> TransformList: """ Apply a list of Transform/Augmentation in-place and returned the applied transform. Attributes of this class will be modified. Returns: TransformList: returns transformed inputs and the list of transforms applied. The TransformList can then be applied to other data associated with the inputs. """ tfms = [] for aug in augmentations: if isinstance(aug, Augmentation): args = [] for f in aug.input_args: try: args.append(getattr(self, f)) except AttributeError: raise AttributeError( f"Augmentation {aug} needs '{f}', which is not an attribute of {self}!" ) tfm = aug.get_transform(*args) assert isinstance(tfm, Transform), ( f"{type(aug)}.get_transform must return an instance of Transform! " "Got {type(tfm)} instead.") else: tfm = aug self.transform(tfm) tfms.append(tfm) return TransformList(tfms)
def apply_transform_gens(transform_gens, img): """ Apply a list of :class:`TransformGen` on the input image, and returns the transformed image and a list of transforms. We cannot simply create and return all transforms without applying it to the image, because a subsequent transform may need the output of the previous one. Args: transform_gens (list): list of :class:`TransformGen` instance to be applied. img (ndarray): uint8 or floating point images with 1 or 3 channels. Returns: ndarray: the transformed image TransformList: contain the transforms that's used. """ for g in transform_gens: assert isinstance(g, TransformGen), g check_dtype(img) tfms = [] for g in transform_gens: tfm = g.get_transform(img) assert isinstance( tfm, Transform ), "TransformGen {} must return an instance of Transform! Got {} instead".format( g, tfm) img = tfm.apply_image(img) tfms.append(tfm) return img, TransformList(tfms)
def apply_augmentations(augmentations, img): """ Apply a list of :class:`Augmentation` or :class:`Transform` on the input image, and returns the transformed image and a list of transforms. We cannot simply create and return all transforms without applying it to the image, because a subsequent transform may need the output of the previous one. Args: augmentations (list): list of :class:`Augmentation` or :class:`Transform` instance to be applied. img (ndarray): uint8 or floating point images with 1 or 3 channels. Returns: ndarray: the transformed image TransformList: contain the transforms that's used. """ for aug in augmentations: assert isinstance(aug, (Transform, Augmentation)), aug check_dtype(img) tfms = [] for aug in augmentations: tfm = aug.get_transform(img) if isinstance(aug, Augmentation) else aug assert isinstance( tfm, Transform ), f"Augmentation {aug} must return an instance of Transform! Got {tfm} instead." img = tfm.apply_image(img) tfms.append(tfm) return img, TransformList(tfms)
def inverse(self): if not self.expand: raise NotImplementedError() rotation = RotationTransform(self.bound_h, self.bound_w, -self.angle, True, None, self.interp) crop = CropTransform((rotation.bound_w - self.w) // 2, (rotation.bound_h - self.h) // 2, self.w, self.h) return TransformList([rotation, crop])
def __call__(self, aug_input) -> Transform: tfms = [] for x in self.augs: # 序列执行 tfm = x(aug_input) # tfm is a instance of Transform tfms.append(tfm) # 返回Transorm 是可以用于处理User 需要处理的别的东西 return TransformList(tfms)
def inverse(self): """ The inverse is to rotate it back with expand, and crop to get the original shape. """ if not self.expand: # Not possible to inverse if a part of the image is lost raise NotImplementedError() rotation = RotationTransform(self.bound_h, self.bound_w, -self.angle, True, None, self.interp) crop = CropTransform((rotation.bound_w - self.w) // 2, (rotation.bound_h - self.h) // 2, self.w, self.h) return TransformList([rotation, crop])
def apply_transform_gens(transform_gens, img): for g in transform_gens: assert isinstance(g, (Transform, TransformGen)), g check_dtype(img) tfms = [] for g in transform_gens: tfm = g.get_transform(img) if isinstance(g, TransformGen) else g assert isinstance(tfm, Transform), \ f"TransformGen {g} must return an instance of Transform! Got {tfm} instead" img = tfm.apply_image(img) tfms.append(tfm) return img, TransformList(tfms)
def get_transform(self, image: np.ndarray) -> TransformList: # Compute the image scale and scaled size. input_size = image.shape[:2] output_size = self.crop_size # Add random crop if the image is scaled up. max_offset = np.subtract(input_size, output_size) max_offset = np.maximum(max_offset, 0) offset = np.multiply(max_offset, np.random.uniform(0.0, 1.0)) offset = np.round(offset).astype(int) crop_transform = CropTransform(offset[1], offset[0], output_size[1], output_size[0], input_size[1], input_size[0]) # Add padding if the image is scaled down. pad_size = np.subtract(output_size, input_size) pad_size = np.maximum(pad_size, 0) original_size = np.minimum(input_size, output_size) pad_transform = PadTransform(0, 0, pad_size[1], pad_size[0], original_size[1], original_size[0], self.pad_value) return TransformList([crop_transform, pad_transform])
def __call__(self, aug_input) -> Transform: tfms = [] for x in self.augs: tfm = x(aug_input) tfms.append(tfm) return TransformList(tfms)
def get_transform(self, image: np.ndarray) -> TransformList: transforms = [self._get_crop(image)] if self.pad: transforms.append(self._get_pad(image)) return TransformList(transforms)