Generating a gallery of clothes while using interactive IPython notebook tools
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
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:
clothe_type = lambda s: s.split('_')[0]
clothe_type("tshirt_1.jpg")
'tshirt'
And now we create a dictionary from the filenames:
from collections import defaultdict
clothes_dict = defaultdict(list)
for item in clothes:
clothes_dict[clothe_type(item)].append(os.path.join(parent_dir, item))
clothes_dict.keys()
['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.
%matplotlib inline
from pylab import *
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)
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)
axis('off')
This function can be immediately tested:
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.
from IPython.html.widgets import interact
from IPython.html import widgets
from IPython.display import display, clear_output
button = widgets.ButtonWidget(description="Change clothes!")
display(button)
def on_button_clicked(b):
clear_output()
top = randint(0, len(clothes_dict['tshirt']))
bottom = randint(0, len(clothes_dict['pants']))
plot_outfit(top, bottom)
button.on_click(on_button_clicked)
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:
from IPython.display import Image
Image(filename='files/clothes_interactive.PNG')
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!
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)