📜 ⬆️ ⬇️

Creating a photomosaic using the Wolfram Language (Mathematica)


Download the translation in the form of a Mathematica document that contains all the code used in the article here (archive, ~ 3 MB).

Introduction


Until New Year 2015, there are already less than a day:

In [1]: =
')
ImageMosaic_2.png

Out [1] =

ImageMosaic_3.png

I would like to congratulate everyone on the Coming New Year 2015 and tell you how you can give your loved ones an unusual gift in the form of photo mosaic created using the Mathematica 10 system and the Wolfram Language.

The idea of ​​photo mosaic as a whole is quite simple: create an image based on a collection of other small-sized images .

In order to create a photo mosaic you can act in two main ways:



To simplify the problem under consideration, we will create a mosaic of square thumbnails.

Creating a collection of images


Of course, you can use any collection of images that you have, be it family photos or travel photos.

I do not think that my collections of this kind will be very interesting to most readers, so I will use a collection of images of a famous person as a collection. As such a person, I will take someone who is known to absolutely everyone, namely, Arnold Schwarzenegger.

To create a collection of images, use the parser from the Zimbio website:

In [2]: =

ImageMosaic_4.png

In [3]: =

ImageMosaic_5.png

We import all available photos from Arnold's profile:

In [4]: ​​=

ImageMosaic_6.png

In total, 5436 photos were imported:

In [5]: =

ImageMosaic_7.png

Out [5] =

ImageMosaic_8.png

The total “weight” of which is almost 5 GB.

In [6]: =

ImageMosaic_9.png

Out [6] =

ImageMosaic_10.png

We can look at the collection briefly, making a collage of 150 randomly selected images:

In [7]: =

ImageMosaic_11.png

Out [7] =

ImageMosaic_12.png

Simple photo mosaic


Let's start creating a simple photo mosaic.

To begin with, we indicate the directory in which the collection of our images is stored:

In [8]: =

ImageMosaic_13.png

Now we will load the paths to each of the images:

In [9]: =

ImageMosaic_14.png

Out [9] // Short =

ImageMosaic_15.png

Save the number of images in a separate variable:

In [10]: =

ImageMosaic_16.png

Out [10] =

ImageMosaic_17.png

Now we will create a collection of thumbnail images, since, obviously, we will not need images in their original size. The size of each thumbnail does not exceed 150x150 pixels (by default).

In [11]: =

ImageMosaic_18.gif

In [13]: =

ImageMosaic_19.png

In [14]: =

ImageMosaic_20.png

Load the paths to each of the thumbnails:

In [15]: =

ImageMosaic_21.png

Now upload all the thumbnails to the system:

In [16]: =

ImageMosaic_22.png

Calculate for each of the thumbnails its average RGB color:

In [17]: =

ImageMosaic_23.png

Let's create a function that will select the miniature closest to it for some image. At the same time, we will provide for the possibility of randomly selecting from the n nearest miniatures (this will be necessary in order for the photo mosaic to lack areas filled with one miniature, which occurs, say, if a large section of the image has one color).

In [18]: =

ImageMosaic_24.gif

Out [18] =

ImageMosaic_25.png

Create a function that makes photomosaic:

In [20]: =

ImageMosaic_26.png

Let's set the image, the mosaic of which we want to get:

In [21]: =

ImageMosaic_27.png

Let's see what the mosaic will look like if the nearest miniature is taken when the thumbnails are gradually reduced:

In [22]: =

ImageMosaic_28.png

Out [22] =

ImageMosaic_29.png

On the last photo mosaic, the effect that was mentioned earlier is most noticeable - areas filled with one miniature in areas of an image with one (or very close) color.

In order to get rid of this, let's set a random selection of the 10 nearest thumbnails:

In [23]: =

ImageMosaic_30.png

Out [23] =

ImageMosaic_31.png

Of course, using this algorithm, you can create any mosaic of this kind:

In [24]: =

ImageMosaic_32.png

Out [24] =

ImageMosaic_33.png

Adaptive photo mosaic


Create a function that will split the image into smaller images in an adaptive way.

The adaptiveImagePartition function works as follows:


In [25]: =

ImageMosaic_34.png

In [26]: =

ImageMosaic_35.png

In [27]: =

ImageMosaic_36.png

Set the base image:

In [28]: =

ImageMosaic_37.png

Let's look at the steps of the created function:

In [29]: =

ImageMosaic_38.png

Out [29] =

ImageMosaic_39.png

By changing the handler, we can get adaptive pixelation:

In [30]: =

ImageMosaic_40.png

Out [30] =

ImageMosaic_41.png

Finally, if, as a handler, specify the replacement of a fragment of the image with the nearest thumbnail, we get:

In [31]: =

ImageMosaic_42.png

Out [31] =

ImageMosaic_43.png

Conclusion


I hope that my post could please you and interest. Of course, you can create even more complex algorithms for photo mosaics that take into account: not only the average color, but also the dominant colors of fragments and miniatures ( DominantColors ); image morphology; more complex adaptive partitioning, etc. But, I think, the created algorithms may already be quite enough to make an original gift yours close to the Coming New Year 2015.

Resources for learning Wolfram Language ( Mathematica ) in Russian: http://habrahabr.ru/post/244451

Source: https://habr.com/ru/post/247149/


All Articles