question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom data augmentation clarification

See original GitHub issue

I would like to use a custom augmentation from the Albumentation library. I took a look at your documentation, in particular at the custom augmentation section where you do the following example:

class MyColorAugmentation(T.Augmentation):
    def get_transform(self, image):
        r = np.random.rand(2)
        return T.ColorTransform(lambda x: x * r[0] + r[1] * 10)

class MyCustomResize(T.Augmentation):
    def get_transform(self, image):
        old_h, old_w = image.shape[:2]
        new_h, new_w = int(old_h * np.random.rand()), int(old_w * 1.5)
        return T.ResizeTransform(old_h, old_w, new_h, new_w)

augs = MyCustomResize()
transform = augs(input)

So I decided to implement my custom augmentation as follows:

import albumentations as A
class ElasticDistortion(T.Augmentation):
    
    def get_transform(self, image):
        
        transform = A.ElasticTransform(alpha=1,
                             sigma=50,
                             alpha_affine=50,
                             interpolation=1,
                             border_mode=4,
                             value=None,
                             mask_value=None,
                             always_apply=True,
                             approximate=False)
        
        h, w = image.shape[:2]
        image = transform(image=image)['image']
        return T.ResizeTransform(h, w, h, w)

in particular I applied a identity resizing in order to return a Transform object rather than a numpy array, (how can I do it better??). My question is if this solution apply the same type of transformation on the image annotations If I create a custom loader as:

def custom_mapper(dataset_dict):
    dataset_dict = copy.deepcopy(dataset_dict)  # it will be modified by code below
    image = utils.read_image(dataset_dict["file_name"], format="BGR")
    # Apply augmentations in sequence
    transform_list = [
        # intensity < 1 reduce brightness, intensity > 1 increase brightness
        T.RandomBrightness(0.2, 1.8),
        # intensity < 1 reduce contrast, intensity > 1 increase contrast
        T.RandomContrast(0.6, 1.4),
        T.RandomSaturation(0.8, 1.4),
        T.RandomRotation(angle=[90, 90]),
        T.RandomLighting(0.7),
        # Apply random flip of the image
        T.RandomFlip(prob=0.5, horizontal=True, vertical=False),
        T.RandomFlip(prob=0.5, horizontal=False, vertical=True),
        # Custom Elastic Distortion
        ElasticDistortion()
    ]
    image, transforms = T.apply_transform_gens(transform_list, image)
    dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32"))

    annos = [
        utils.transform_instance_annotations(obj, transforms, image.shape[:2])
        for obj in dataset_dict.pop("annotations")
        if obj.get("iscrowd", 0) == 0
    ]
    instances = utils.annotations_to_instances(annos, image.shape[:2])
    dataset_dict["instances"] = utils.filter_empty_instances(instances)
    return dataset_dict

from detectron2.data import build_detection_test_loader, build_detection_train_loader

class CustomTrainer(DefaultTrainer):
    @classmethod
    def build_train_loader(cls, cfg):
        return build_detection_train_loader(cfg, mapper=custom_mapper)

moreover, after these modifications, training has bacame very slow. It will be useful to enrich properly the documentation with some more examples. Thank you for your support!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

2reactions
FrancescoMandrucommented, Feb 7, 2022

I found another way which seems to work, please correct me if I am wrong. I implemented an easier augmentation with respect to elastic distortion

class Clahe(T.Augmentation):

    def __init__(self, clip_lim, win_size):
        self.clip_lim = clip_lim
        self.win_size = win_size
        self._init(locals())

    def get_transform(self, image):
        return ClaheTransform(self.clip_lim, self.win_size)
    
class ClaheTransform(T.Transform):

    def __init__(self, clip_lim, win_size):
        super().__init__()
        self.clip_limit = clip_lim
        self.win_size = win_size
        self._set_attributes(locals())

    def apply_image(self, img):
        transform = A.CLAHE(clip_limit=self.clip_lim, 
                            tile_grid_size=(self.win_size, self.win_size))
        augmented_image = transform(image=img)['image']
        return augmented_image

    def apply_coords(self, coords):
        #coords[:, 0] = coords[:, 0] * (self.new_w * 1.0 / self.w)
        #coords[:, 1] = coords[:, 1] * (self.new_h * 1.0 / self.h)
        return coords

    def apply_segmentation(self, segmentation):
        segmentation = self.apply_image(segmentation)
        return segmentation

    def inverse(self):
        return ClaheTransform(self.clip_lim, self.win_size)
0reactions
deshwalmaheshcommented, Oct 14, 2022

@FrancescoMandru Oh! that’s sad. Anyways thank for a quick reply. Just want to know that if I have a function:

def foo(image, coors):
  return image1, coors1

How can I apply that to my pipeline?

If you happen to get the function in the near future, please do let me know. Thank you

Read more comments on GitHub >

github_iconTop Results From Across the Web

Writing a custom data augmentation layer in Keras
Data augmentation can help an image ML model learn to handle variations of the image that are not in the training dataset.
Read more >
Guide To Customized Data Augmentation Using Tensorflow
This article demonstrates the data augmentation techniques, firstly using Keras preprocessing layer and tensorflow.image class. Code ...
Read more >
Custom Image Augmentations with ... - Keras
KerasCV offers a helpful base class for writing data augmentation layers: BaseImageAugmentationLayer . Any augmentation layer built with ...
Read more >
Data augmentation | TensorFlow Core
This tutorial demonstrates data augmentation: a technique to increase the diversity of your training set by applying random (but realistic) transformations, ...
Read more >
Custom Data Augmentation Technique (A Deeper Insight)
This paper presents a deeper insight into prior research for the classification of NFRs based on deep learning techniques.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found