Gopi
Gopi

Reputation: 369

How to obtain same augmented images using ImageDataGenerator in keras or tensorflow?

I am working with grayscale images of size 75 by 75 and want to perform some augmentation techniques using ImageDataGenerator.

But wondering if we can repeat the output consistently if we run multiple times. I am not talking about epochs but like running the whole code to mimic the exact same augmented images to get same results.

I am attaching sample grayscale image:

enter image description here

import matplotlib.pyplot as plt
import numpy as np
from scipy import misc, ndimage
from keras.preprocessing.image import ImageDataGenerator

gen = ImageDataGenerator(rotation_range=10, width_shift_range=0.1, 
       height_shift_range=0.1, zoom_range=0.1, # shear_range=0.15, 
       channel_shift_range=10., horizontal_flip=True, vertical_flip = True,
       rescale = 0.2, fill_mode = 'wrap')

image_path = '/trial_img.png' # grayscale image

# Obtain image
# data_format = [#num_images,height,width,#num_of_channels]
# where, #num_images = 1 and #num_of_channels = 1, height = width = 75
image = np.expand_dims(ndimage.imread(image_path),0) # add num_images dimension
image = np.expand_dims(image, axis=3) # add num_of_channels dimension
plt.imshow(image.reshape(75,75), cmap = 'gray')

# Trial #1
# Generate batches of augmented images from this image
aug_iter = gen.flow(image)
# Get 10 samples of augmented images
aug_images1 = [next(aug_iter)[0].reshape(75,75).astype(np.uint8) for i in range(10)]

# Trial #2
aug_iter = gen.flow(image)
aug_images2 = [next(aug_iter)[0].reshape(75,75).astype(np.uint8) for i in range(10)]

# check if equal
truth = []
for val in range(10):
    truth.append((aug_images1[val] == aug_images2[val]).all()) # check images
np.asarray(truth).all() # check if all images are same

How to repeat the augmented outputs consistently in above code?

I know this code is written very badly, any suggestions on code optimization are also greatly appreciated.

Thanks,

Gopi

Upvotes: 1

Views: 2505

Answers (2)

ebeneditos
ebeneditos

Reputation: 2612

You can set a seed to the flow method:

aug_iter = gen.flow(image, seed = 0)

By setting this parameter to a specific integer, you will always get the same sequence of random shuffling/transformations.

Upvotes: 3

Daniel Möller
Daniel Möller

Reputation: 86650

You could run the generator and save the images, then simply load the images:

# Trial #1
# Generate batches of augmented images from this image
aug_iter = gen.flow(image)
# Get 10 samples of augmented images
aug_images1 = [next(aug_iter)[0].reshape(75,75).astype(np.uint8) for i in range(10)]

If memory is not a problem, you can save this with numpy:

aug_images1 = np.array(aug_images1)
np.save(filename, aug_images1)

Then load it:

aug_images1 = np.load(filename)

If you prefer, you can save each image as proper image files (less memory occupied) using an image library such as Pillow:

from PIL import Image

for (im,filename in zip(aug_images1,list_of_names)):
    im = Image.fromarray(im) #make sure you have a uint8 from 0 to 255 array.
    im.save(filename)

Later, load the files:

aug_images1 = [np.array(image.open(filename)) for filename in list_of_names]
aug_images1 = np.array(aug_images1)

Using ImageDataGenerator for loading files

In case you don't want to load all images at once in memory, with saved images, you can create a new ImageDataGenerator, but without any kind of augmentation, just a pure image loader.

Then use gen.flow_from_directory() to get images from a directory.

Read more in the documentation: https://keras.io/preprocessing/image/

Upvotes: 1

Related Questions