Pyground 🐍
INFO

Image tiler

May 25, 2020 • JBen

Open In Colab

Definitions¶

In [1]:
import requests
import skimage
import skimage.io
import numpy as np
from PIL import Image
from io import BytesIO
from google import colab
In [2]:
MAX_SHAPE = (512, 512)


def tile(*, image, dim, pos):
  h, w = image.shape[:2]

  new_shape = list(image.shape)
  new_shape[0] = h*dim[0]
  new_shape[1] = w*dim[1]

  tiled = np.zeros_like(image, shape=new_shape)

  # prepare flips
  image_yx = np.flip(image, (0, 1))
  image_y = np.flipud(image)
  image_x = np.fliplr(image)

  for y in range(dim[0]):
    for x in range(dim[1]):
      rel_y = y - pos[0]
      rel_x = x - pos[1]

      flip_x, flip_y = False, False

      if rel_y % 2 != 0:
        flip_y = True
      if rel_x % 2 != 0:
        flip_x = True

      # no flip
      if True not in (flip_y, flip_x):
        tiled[h*y:h*(y+1), w*x:w*(x+1)] = image
      # flip y & x
      elif flip_y and flip_x:
        tiled[h*y:h*(y+1), w*x:w*(x+1)] = image_yx
      # flip y
      elif flip_y:
        tiled[h*y:h*(y+1), w*x:w*(x+1)] = image_y
      # flip x
      else:
        tiled[h*y:h*(y+1), w*x:w*(x+1)] = image_x

  return tiled


# Same result using np.pad
def tile_np(*, image, dim, pos):
  h, w = image.shape[:2]
  y, x = pos

  return np.pad(a, (
      (h*y, h*(dim[0]-1-y)),
      (w*x, w*(dim[1]-1-x)),
      (0, 0)
      ), "symmetric")

Demo¶

Choose an option to provide a source image

In [ ]:
# either upload a local image...
uploaded = colab.files.upload()
assert uploaded, "Please supply a file"
raw = next(iter(uploaded.values()))
In [3]:
# ...or use an URL
url = "http://wedding.beleon.com/media/8866-beleontoursgreeceweddingzakynthosislandkameo03.JPG"  #@param {type: "string"}
raw = requests.get(url).content

Process the image

In [4]:
im = Image.open(BytesIO(raw))
im.thumbnail(MAX_SHAPE)
a = np.array(im)
im = tile(image=a, dim=(2, 2), pos=(1, 1))
Image.fromarray(im)
Out[4]:

Speed comparison¶

In [5]:
a = np.empty((1000, 1000, 3))

def test(f):
  f(image=a, dim=(11, 11), pos=(5, 5))

loop method

In [6]:
%%timeit

test(tile)
1 loop, best of 3: 1.07 s per loop

versus

np.pad method

In [7]:
%%timeit

test(tile_np)
1 loop, best of 3: 1.5 s per loop
  • JBen