osgeonepal / geotile

GeoTile is the python library for tiling the geographic raster data (eg. Tiff etc)
https://geotile.readthedocs.io
MIT License
74 stars 9 forks source link

Need to implement data augmentation technique #15

Closed iamtekson closed 7 months ago

iamtekson commented 1 year ago

Doing data augmentation inside the library needs more effort and it add more dependencies to the library. As of this day, I am thinking to use imgaug as a data augmentation. If I add this library, the following dependencies will be added to the code,

So, for now, I am thinking not to include data augmentation. But if anyone wants to use the data augmentation, you can do as below using imgaug library.

import imgaug.augmenters as iaa
from imgaug.augmentables.segmaps import SegmentationMapsOnImage
import numpy as np

# Define augmentation pipeline
seq = iaa.Sequential([
    iaa.Fliplr(0.5),  # Horizontal flip
    iaa.Flipud(0.5),  # Vertical flip
    iaa.Affine(rotate=(-45, 45)),  # Random rotation between -45 and 45 degrees
    iaa.Affine(scale=(0.5, 1.5)),  # Random scaling between 0.5x and 1.5x
    iaa.Affine(translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}),  # Random translation
    # iaa.AdditiveGaussianNoise(scale=(0, 0.05*255)),  # Gaussian noise
    # iaa.ElasticTransformation(alpha=50, sigma=5)  # Elastic deformation
])

# Apply augmentation to images and masks
augmented_images, augmented_masks = seq(images=TRAIN_XX, segmentation_maps=TRAIN_YY)

In above code, the TRAIN_XX shape(num_tiles, x, y, bands) and TRAIN_YY shape(num_tiles, x, y, 1). The above code will only generate the 1 set of augmentation, i.e. if your total number of tiles is 10, then it will only generate 10 additional tiles.

But in order to generate more number of tiles, you can do as below,

augmented_images = []
augmented_masks = []

num_augmentations = 15 # total number of tiles will be: num_augmentations * number of features
# Apply augmentation to each original image and mask
for i in range(TRAIN_XX.shape[0]):
    image = TRAIN_XX[i]
    mask = TRAIN_YY[i]

    # Create a segmentation map object from the mask
    segmentation_map = SegmentationMapsOnImage(mask, shape=image.shape)

    # Apply augmentation num_augmentations times
    for _ in range(num_augmentations):
        # Apply the same augmentation to both image and mask
        augmented_image, augmented_segmentation_mask = seq.augment(image=image, segmentation_maps=segmentation_map)

        # Append the augmented image and mask to the lists
        augmented_images.append(augmented_image)
        augmented_masks.append(augmented_segmentation_mask.get_arr())

# Convert lists to numpy arrays
augmented_images = np.array(augmented_images)
augmented_masks = np.array(augmented_masks)

# append augmented images/masks with original images/masks
all_images = np.concatenate((TRAIN_XX, augmented_images), axis=0)
all_masks = np.concatenate((TRAIN_YY, augmented_masks), axis=0)