albumentations
albumentations copied to clipboard
how to add custom data aug operation
how to add custom data aug operation to albumentations.Compose?any example?
Hey @gentlebreeze1
We have plans to add a step-by-step tutorial for creating a new augmentation. For now, I think the best option is to check PRs that implement new augmentations as a reference, e.g., #843, #490
Has there been an update on this issue?
- aslo here for updates
Though one should ideally do something like https://github.com/albumentations-team/albumentations/pull/490/files ie modify functional.py, test_transforms.py and transforms but if you already have a long albumentation augmentations pipeline and just want to add aug in between than one can use something like:
Depending upon the use case one can inherit ImageOnlyTransform, DualTransform etc There are a lot of other methods that one can too use like apply_to_keypoints etc
class MyCustomAug(DualTransform):
def __init__(self, parameter_1, parameter_2, always_apply=True, p=1.0):
super().__init__(always_apply, p)
self.parameter_1 = parameter_1
self.parameter_2 = parameter_2
def apply(self, img, **params):
#apply augmentation to images
def apply_to_mask(self, mask, **params):
#apply augmentation to masks
to give somebody a hint based on my own experiments, for image only argumentations. Key to use custom transforms is based on it's interface https://github.com/albumentations-team/albumentations/blob/master/albumentations/core/transforms_interface.py
see following pipline examples
import cv2
from albumentations.core.transforms_interface import ImageOnlyTransform
import albumentations as A
class RandomA(ImageOnlyTransform):
"""
RamdomA transformation
"""
def __init__(self, safe_db_lists=[], prob =0.5) -> None:
super(RandomA, self).__init__()
self.safe_db_lists = safe_db_lists
self.prob = prob
def apply(self, img, copy=True, **params):
if np.random.uniform(0, 1) > self.prob:
return img
if copy:
img = img.copy()
# some of your logic here
return img
class RandomB(ImageOnlyTransform):
"""
RandomB transformation
"""
def __init__(self, safe_db_lists=[], prob =0.5) -> None:
super(RandomB, self).__init__()
self.safe_db_lists = safe_db_lists
self.prob = prob
def apply(self, img, copy=True, **params):
if np.random.uniform(0, 1) > self.prob:
return img
if copy:
img = img.copy()
# some of your logic here
return img
# test compose pipeline
image = cv2.imread('test.jpg')
transforms = A.Compose(transforms=[
RrandomA(prob=1.0),
RandomB(prob=1.0),
])
# and new_image is the target image dict
new_image_dict = transforms(image=image)
new_image = new_image_dict['image']
Any updates?
to give somebody a hint based on my own experiments, for image only argumentations. Key to use custom transforms is based on it's interface https://github.com/albumentations-team/albumentations/blob/master/albumentations/core/transforms_interface.py
see following pipline examples
import cv2 from albumentations.core.transforms_interface import ImageOnlyTransform import albumentations as A class RandomA(ImageOnlyTransform): """ RamdomA transformation """ def __init__(self, safe_db_lists=[], prob =0.5) -> None: super(RandomA, self).__init__() self.safe_db_lists = safe_db_lists self.prob = prob def apply(self, img, copy=True, **params): if np.random.uniform(0, 1) > self.prob: return img if copy: img = img.copy() # some of your logic here return img class RandomB(ImageOnlyTransform): """ RandomB transformation """ def __init__(self, safe_db_lists=[], prob =0.5) -> None: super(RandomB, self).__init__() self.safe_db_lists = safe_db_lists self.prob = prob def apply(self, img, copy=True, **params): if np.random.uniform(0, 1) > self.prob: return img if copy: img = img.copy() # some of your logic here return img # test compose pipeline image = cv2.imread('test.jpg') transforms = A.Compose(transforms=[ RrandomA(prob=1.0), RandomB(prob=1.0), ]) # and new_image is the target image dict new_image_dict = transforms(image=image) new_image = new_image_dict['image']
This works but note that ImageOnlyTransform
extends BasicTransform
which does not get applied to every image. To apply to every input you need to pass always_apply=True
to
super(...).__init__()