CNNs are not inherently able to handle features of different sizes, i.e. they are not scale invariant. With affine geometric transformations we can augment our dataset and introduce scale invariance. In this post we create a simple mapping function that crops an image tensor randomly and centrally.

Random center cropping with TensorFlow

First, load the image as a tensor and convert it to a dataset:

import tensorflow as tf
import PIL
import numpy as np

img = np.array(PIL.Image.open('providence-doucet-FjwtL3YSZ9U-unsplash.jpg')) #source https://unsplash.com/photos/FjwtL3YSZ9U
img_tensor = tf.convert_to_tensor(img, dtype=tf.uint8)
ds = tf.data.Dataset.from_tensors(img_tensor)

The random_central_crop function is straightforward. Note that you cannot use Python’s random.uniform as TensorFlow will build its graph.

@tf.function
def random_central_crop(tensor):
    fraction = tf.random.uniform(shape=[], minval=0.3, maxval=1)
    cropped_tensor = tf.image.central_crop(tensor, fraction)
    return cropped_tensor

ds = ds.repeat(21).map(random_central_crop)

Let’s see the result:

import matplotlib.pyplot as plt
import math

samples = list(ds)
cols = 7
rows = math.ceil(len(samples) / cols)
fig,axs = plt.subplots(rows, cols, figsize=(20, rows*3))
for i in range(rows):
    for j in range(cols):
        num = j + (cols*i)
        if num >= len(samples):
            break
        sample = samples[num]
        axs[i, j].imshow(sample)