I need to do data augmentation but not with any fill modes, constant
, reflect
, nearest
, wrap
. Instead everytime the image is rotated or translated, I would like to have it center-cropped (shown below) so as not have any black, white, reflected, or constant edges/borders as explained here.
How do I extend the ImageDataGenerator
class (if that's the only way to do it and no center crop is available out of the box) with these points taken into account?
Keep existing parts of the ImageDataGenerator other than the augmentation part, and write a custom augmentation function
It would be efficient to retain the images of original size without resizing before augmentation happens because center crop would result in huge loss of data after resize. Translate/Rotate -> Center crop -> Resize
should be more efficient than Resize -> Translate/Rotate -> Center crop
Keras ImageDataGenerator is a gem! It lets you augment your images in real-time while your model is still training! You can apply any random transformations on each training image as it is passed to the model. This will not only make your model robust but will also save up on the overhead memory!
For example, if you have 1000 images in your dataset and the batch size is defined as 10. Then the "ImageDataGenerator" will produce 10 images in each iteration of the training. An iteration is defined as steps per epoch i.e. the total number of samples / batch_size.
Class modes: "categorical" : 2D output (aka. list of numbers of length N), [0, 0, 1, 0], which is a one-hot encoding (only one number is 1/ "hot") representing the donkey. This is for mutually exclusive labels.
Referencing from image Keras ImageDatagenerator source code, the parameter rescale is to multiply every pixel in the preprocessing image. rescale: rescaling factor. If None or 0, no rescaling is applied, otherwise we multiply the data by the value provided (before applying any other transformation).
In case someone is looking for a solution, here's how I managed to solve the problem. The main idea is to wrap the ImageDataGenerator
in a custom generator, like this:
def crop_generator(batches, new_size):
while True:
batch_x, batch_y = next(batches)
x= batch_x.shape[1] // 2
y= batch_x.shape[2] // 2
size = new_size // 2
yield (batch_x[:, x-size:x+size, y-size:y+size], batch_y)
x_train = HDF5Matrix(...)
y_train = HDF5Matrix(...)
datagen = ImageDataGenerator(rotation_range=180, ...)
model = create_model()
training_gen = crop_generator(datagen.flow(x_train, y_train, batch_size=128), new_size=64)
model.fit_generator(training_gen, ...)
Using numpy indexing batch_x[:, x-size:x+size, y-size:y+size, :]
we only alter x
and y
dimensions of the images, leaving batch size and channel dimensions the same. This allows us to avoid the for-loop.
This may be helpful,
Extending Keras' ImageDataGenerator to Support Random Cropping
https://jkjung-avt.github.io/keras-image-cropping/
github code:
https://github.com/jkjung-avt/keras-cats-dogs-tutorial/blob/master/train_cropped.py
train_datagen = ImageDataGenerator(......)
train_batches = train_datagen.flow_from_directory(DATASET_PATH + '/train',
target_size=(256,256),
......)
train_crops = crop_generator(train_batches, 224)
net_final.fit_generator(train_crops, ......)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With