Mosaic algorithm

Mosaic algorithm

Today I noticed a new blogpost by William, he wrote a small Python script to create mosaics from thumbnails.

As input he is using thumbnails from the Ludum Dare game programming contest.

To make such a program you basically need four things:

  1. A collection of thumbnails/photos/images to place
  2. Divide the target mosaic image into a grid of tiles
  3. Have a scoring/measuring method for each tile
  4. Have a placement algorithm


Will is using all the thumbnails from the contest and a given target image. He then divides the target image into a grid. Next comes the important part, how do you measure how well a thumbnail matches a target tile? He is using a clever per-pixel RGB matching technique. The closer the color matches, the higher the score.

The final (important) step is placement. For each tile he takes the highest scoring thumbnail and assigns it to the tile. If you keep doing this (greedy) you’ll get a good recognisable result:

mosaic generation with greedy placement

Random swapping

When he explained his algorithm (in gtalk) it reminded of the problem I encounter in almost all the Al Zimmermann programming competitions. Eventually all these algorithms boil down to search algorithms. You are looking for the best combination of images with the highest overall matching score (correctness/likeness). Instead of using just the greedy algorithm I suggested he’d try randomly swapping a couple of images and checking the score for improvements. This turned out to be a difference of night and day, check it out:

mosaic placement improvement with random swaps

Of course there are still problems with this method, for example: you’ll quickly run into a local optima. Maybe you’ll have a much better image if A -> B and B -> C and C -> A. This will never be reached by swapping two tiles if the individual steps don’t have an improved score. This can be countered by swapping multiple pairs at once and hoping you’ll hit this correct pair.

There are a lot of other ‘smarter’ things you could do, for example always try to put a ‘best match’ on a particular tile and trying to fill the hole it created…. But for now adding this simple random swap is perfect!

Be sure to check out Williams other tech related blogposts, he’s also involved in the development of the amazing Mill CPU.