Random center cropping with TensorFlow
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.
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)