leo.blog();

Transformative downscaling

Downscaling an image reduces its dimensions, causing each pixel in the smaller image to represent multiple pixels from the original. This process is irreversible: once the extra detail is lost, it cannot be recovered. This is why shrinking an image and then enlarging it back to its original size results in a blurry or pixelated version of the original.

It might seem like a downscaled image is just a smaller, simplified version of the original. However, this is not always true. By carefully manipulating the original image, it is possible to control what the downscaled version looks like, sometimes with surprising results.

To demonstrate this, an image of PewDiePie was created that, when downscaled, turns into an image of Elon Musk. This was achieved using Dual Annealing, a numerical optimization algorithm that searched for a high-resolution image that:

  1. Closely resembles the original PewDiePie image
  2. Downscales into an image closely resembling the target Elon Musk image

Note that Dual Annealing is not the only algorithm that could achieve this; many other optimization methods could work as well.

Potential applications

Future work

Code

Below is the code used to produce such images.

from PIL import Image
import scipy.optimize
import numpy as np

# Transformative downscaling

large = Image.open("./images/pewds.png").convert('L').resize((256,256))
small = Image.open("./images/elon.png").convert('L').resize((128,128))

init = np.array(large).flatten()
small = np.array(small).flatten()

it = 0

def fitness(img):
    lg = np.linalg.norm(img - np.array(large).flatten())
    img = img.reshape((256,256))
    img = Image.fromarray(img).convert("L")
    global it
    it += 1
    if it == 50:
        img.save('/tmp/test.png')
        img.resize((128,128)).save('/tmp/test1.png')
        it = 0
    img = img.resize((128,128))
    img = np.array(img).flatten()
    sm = np.linalg.norm(img - small)
    return sm + lg

opt = scipy.optimize.dual_annealing(fitness, [(0,255)] * init.shape[0])
print(opt)
img = Image.fromarray(opt.x.reshape((256,256))).convert("L")
img.save("/tmp/test.png")

Tags: Image processing

Leave a Comment