Previously, I recreated an image by rearranging squares of another image. Typical photomosaics allow for repeated use of tiles, so I’ll try that for comparison. I’ll still allow rotation, as it helps the edges so much. The image on the left is the result:

It works, but isn’t great. The repeated use of certain tiles is very noticeable, and the edges are not sharp. In the previous post, the requirement of using every tile without repetition spread out the error, and avoided regions of duplicated tiles.

Since we’re allowing for re-use, how about bending the rules farther? Let’s no longer be restricted by the positions of the tiles on the source image. That is, pick the section of the source image that best matches the target. What’s the best way to do that? Convolutions, of course! I’ll put the equations down at the bottom. The result is on the right of the image above.

This convolved method is not very quick (not yet, since I didn’t parallelize this very parallelizable problem), but it gives much better results! The edges are cleaner, and there’re fewer obvious repeats of the same tiles. I still like the no-repeats version better, but I’m glad this worked out.

Since we’re relaxing constraints here, let’s go even further. I’ll instead use source region that is most highly correlated with the target tile, and then linearly rescale the colors so that they match. The result is pretty nice:

It’s like the poor man’s version of neural style transfer. The image at the top of this post shows the three variants as well, using Starry Night to make a skull.

## Convoluted math

The tile of the target image is t, and the source picture is s. I want to find the total squared difference between the tile and each identically-sized portion of the image, call that \epsilon. Some more nomenclature: applying a filter a to image b is called F_a(b). Say that A is the area (in pixels) of t. And make another filter called t_1, which is identical in shape to t, but all values are 1.

The resulting error at each (x,y) location is:

\epsilon(x,y) = \left(\sum_{A} t^2\right) - 2 F_t \left(s \right) + F_{t_1}\left(s^2 \right)

The best match is where \epsilon(x,y) is minimized.