Generating a gallery of clothes while using interactive IPython notebook tools

Clothes Real life

This post is dedicated to a small clothing experiment. With the help of Google, I've downloaded images of pants and t-shirts (or shirts) from the internet. Using Python and matplotlib, I will generate and display random pairings from these images.

First, let's load the data I've saved to my hard drive:

  • we read a bunch of filenames
  • and we create a dictionary containing the paths to the different clothing elements
In [1]:
import os
parent_dir = 'files/clothes/'
clothes = os.listdir(parent_dir)

We create a helper function that separates the prefix of the file from the rest of the name:

In [2]:
clothe_type = lambda s: s.split('_')[0]
In [3]:

And now we create a dictionary from the filenames:

In [4]:
from collections import defaultdict
clothes_dict = defaultdict(list)
for item in clothes:
    clothes_dict[clothe_type(item)].append(os.path.join(parent_dir, item))
In [5]:
['tshirt', 'pants']

As we now have a dictionary listing our images, we're going to define a function able to visualize a top and a bottom element (basically a shirt and pants).

To display that, we plot the top and the bottom on the same axes, but with different extents. Let's demo this below.

In [6]:
%matplotlib inline
from pylab import *
In [7]:
imshow(imread(clothes_dict['tshirt'][3]), extent=(0.25, 0.75, 0.5, 1)) 
imshow(imread(clothes_dict['pants'][6]), extent=(0.1, 0.9, 0, 0.5)) 
xlim(0, 1)
ylim(0, 1)
(0, 1)
In [8]:
def plot_outfit(top, bottom):
    im_top = imread(clothes_dict['tshirt'][top])
    im_bottom = imread(clothes_dict['pants'][bottom])
    imshow(im_bottom, extent=(0.1, 0.9, 0, 0.5)) 
    imshow(im_top, extent=(0.25, 0.75, 0.5, 1)) 
    xlim(0, 1)
    ylim(0, 1)

This function can be immediately tested:

In [9]:
plot_outfit(1, 2)

Now, let's move on to the fun part: we can use randomness and a click button from the IPython interactive widget tools to generate arbirtary outfits.

In [10]:
from IPython.html.widgets import interact
from IPython.html import widgets
from IPython.display import display, clear_output
In [11]:
button = widgets.ButtonWidget(description="Change clothes!")

def on_button_clicked(b):
    top = randint(0, len(clothes_dict['tshirt']))
    bottom = randint(0, len(clothes_dict['pants']))
    plot_outfit(top, bottom)


Unfortunately, the interactive part is not displayed in the IPython Notebook static rendering. Therefore I made a screenshot that is shown below showing the interactive button created with the code in the above cell:

In [1]:
from IPython.display import Image

It's quite fun clicking on that button! To conclude this post, let's apply the previously defined function plot outfit to a grid to generate a lot of random outfits!

In [12]:
figure(figsize=(10, 10))
n, m = 8, 8
for i in range(n * m):
    subplot(n, m, i+1)
    top = randint(0, len(clothes_dict['tshirt']))
    bottom = randint(0, len(clothes_dict['pants']))
    plot_outfit(top, bottom)