Example¶
There are three main classes:
Master
: which represents the master image.Pool
: which is the pool of tile images to use to reconstruct theMaster
image.Mosaic
: which is to construct the photo mosaic for aMaster
image andPool
tiles.
We'll be using the UTKFace
dataset which can be downloaded here. Extract it to the faces/
folder.
It contains 9780 200x200 images of faces.
Let's import the 3 main classes.
from phomo import Master, Pool, Mosaic
/home/lcoyle/.cache/pypoetry/virtualenvs/phomo-pX3Qwu7w-py3.12/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html from .autonotebook import tqdm as notebook_tqdm
Pool¶
We initialize the pool from the faces/
folder. We'll be using 20x20 square tiles.
pool = Pool.from_dir("faces/", crop_ratio=1, tile_size=(20, 20))
pool
Loading tiles: 100%|█████████████████████████████████████████████████████████████████| 9780/9780 [00:04<00:00, 2102.21it/s]
phomo.pool.Pool at 0x7fbf6e0436e0: len: 9780
Master¶
Let's take a random image from the faces/
folder and use that as the master image. We also resize the master image from 200x200 to 400x400.
from pathlib import Path
master_file = list(Path("faces").glob('*'))[1534]
master = Master.from_file(master_file, img_size=(400, 400))
master
phomo.master.Master at 0x7fbf6c91a6f0: shape: (400, 400, 3)
master.img
Mosaic¶
We can create the Mosaic
from the master image and the tile pool.
mosaic = Mosaic(master, pool)
mosaic
phomo.mosaic.Mosaic at 0x7fbf6e075af0: n_appearances: 1 mosaic size: (400, 400) tile shape: (20, 20) leftover tiles: 9380 phomo.grid.Grid at 0x7fbf55529700: origin: (0, 0) len slices: 400 thresholds: [] phomo.master.Master at 0x7fbf6c91a6f0: shape: (400, 400, 3) phomo.pool.Pool at 0x7fbf6e0436e0: len: 9780
Let's show the tile grid to see how things line up.
mosaic.grid.plot()
If we want to get fancy we can subdivide tiles with more contrast. We'll get more detail in thoss tiles but have inconsistent tile size.
mosaic.grid.subdivide(0.1)
mosaic.grid.plot()
Next we compute the distance matrix, which will be used to decide which tile goes where. This is the process which takes the longest.
d_matrix = mosaic.d_matrix()
Building distance matrix: 100%|██████████████████████████████████████████████████████████| 493/493 [00:25<00:00, 18.96it/s]
If you have a GPU and installed phomo
with the cuda
extra (pip install 'phomo[cuda]'
), you can use GPU acceleration to compute the distance metric.
# d_matrix = mosaic.d_matrix_cuda()
Now we give the distance matrix to the mosaic to build the mosaic.
mosiac_img = mosaic.build(d_matrix)
mosiac_img
Building mosaic: 100%|████████████████████████████████████████████████████████████████| 493/493 [00:00<00:00, 95864.25it/s]
If we want, we can use PIL
to blend the master with the mosaic to smooth out some of the jaggedness.
from PIL import Image
Image.blend(mosiac_img, master.img, 0.3)