This is a program was created for a Network Security and Automation bootcamp. It is intended for educational purposes only.
This script creates a mosiac of an image using smaller images (tiles). It can accept 1 or 2 additional command line arguments.
- If no arguments are given, the script will ask for user input for a painter. It will attempt to find a self-portrait of the painter to be made into a mosaic,
and also find the art from that painter to compose the mosaic.
- The first optional argument should be a path to an image that will be used as the blueprint for the mosaic.
- The second optional argument should be the path to a directory containing images that will be used to compose the mosaic.
- If only the first argument is given, the script will then prompt the user for a painter whos art will compose the mosaic.
The difficulty is to try and find a source that images can be reliably and consistantly downloaded. For this project I chose "classical art",
as they would be in the public domain, and therefore have less restrictions on copyright.
Even though finding databases of classical art is easier than other types, it was still a challenge to acqure the necessary files for this
program to work.
Website used: https://www.wga.hu
: The Web Gallery of Art is a virtual museum and searchable database of European fine arts, decorative arts and architecture (3rd-19th centuries),
currently containing over 52.800 reproductions. Artist biographies, commentaries, guided tours, period music, catalogue,
free postcard and mobile services are provided.
This source allows files to be searched easily and images thumbnails can be downloaded instead of the full images, saving bandwidth.
Even though the thumbnails being downloading were relatively small, it was taking about a second per download. So to download a few hundred
images would be minutes.
The solution was to use the Pool() function on the downloads, this drastically decreased to download window to a handful of seconds.
In developing this project, I learned about a technical problem called rectangle packing, or the packing problem. Which is the difficulty is
trying to fit rectangles of various sizes into a larger rectangle, conserving the least amout of empty space. Needless to say this is a difficult
problem, even without adding on the other problem of finding the best colored image for a particular space on
the mosaic.
After researching this particular problem, my solution was just to avoid it. As that would be a worthy enough problem for a project on its own.
Therefore, after downloading the required thumbnails, the program turns them into squares which I call tiles of equal size.
The next challenge was how to cut up the image that was going to be used for the mosaic template into individual pieces,
that can be compared to the tiles. The challenge was for the program to be able to take images of various dimensions,
and split them up, relatively, into a certain amount of tiles. This, like the packing problem, was harder than I anticipated.
The math involved here was a bit more than I would have hoped, and in the end I had to used a magic number approach. After running the program
a few times and finding the "best" looking square density. I was able to find the best number of tiles per length/width, relatively speaking.
Therefore I can use a "magic number", with some math, to give me and workable result.
This leaves something to be desired for the usablility of the program, and is a core component that needs to be reworked.
The next challenge was how I was going to compare a square on the template image to the database of tiles. For this the program with will find the
average red/green/blue numerical value for each tile and store it in a json file. In order to do this the program will iterate through each pixel
on the tile, extracting the RGB value and then derive the average. It does the same for the square on the template image to will be replaced.
When the program is replaces template image squares, it adds up the RGB as one number for both the square and tile, then finds the tile that is closest
in value, and uses that tile as a replacement.
This seems to work relatively well, compared to its simplicity, although a better solution is no doubt probable.
There was an issue when trying to have the same amount of tile no matter the relative size of the image that was to be made into a mosaic. Solving it was just a matter of just factoring in percentages.
- Completed Add code to delete downloaded files.
- Progress meter on downloads/mosiac composition. tqdm does not work with easily work with Pool.
- Refine how tile color comparisons are calculated.