A photographic mosaic, or a photomosaic, is an image made up of smaller images. This Python program takes a pool of images and turns them into a photomosaic. The algorithm it uses is pretty simple, but the results are quite passable. Though I haven't tested it too much, since I lacked images for the pool.
A large image pool is required for a photomosaic to be effective. At the time, all I had available were the scattered family photos in my hard drive. It totalled to around ~2,000 images, which was just barely enough to generate a mosaic of 1,600 tiles.
Before generating a photomosaic, the program first needs to process the image pool and create a database with all the necessary data of each tile necessary for the creation of a photomosaic. This database is needed so that matching sections of the source image with each tile could be much faster, since all the data is already stored, and no longer needed to be generated in runtime.
With the image pool ready, the program subdivides the source image into tiles (called source tiles from now on). These tiles are going to be replaced by images in the pool (pool tiles). The program then traverses through the subdivided source image and tries to find the best matching tile from the pool to place.
Matching the colors isn't done simply by comparing the average colors of the whole tile. When comparing a source tile with a pool tile, the source tile is further subdivided into a 3×3 matrix. Then the comparison can begin. Computing the average colors of each subtile in the 3×3 matrix with the data in the image pool database (which also holds the average colors of the 3×3 matrix of each pool tile), the program can find the best matching pool tile to place. Of course, increasing this second subdivision could greatly improve the matching capabilities of the software. That would have to be something for me to work on next.
The first results were barely recognizable. All the best matching tiles were placed in the top right corner of the image, since that's where the program starts traversing. And since it only uses each pool tile once, it leaves the rest of the image to receive "leftovers". I resolved this by starting in the center, where the best pool tiles could be used where it was needed most, the face in a portrait.
Much better. If I had a better pool, maybe it could be better.
I'll work on those when I have the time. I haven't touched this project in over a year.
The source is on Github. It's a little messy though, sorry.