12 June 2020

Transformative downscaling

The process of reducing the dimensions of an image, also known as downscaling, inevitably leads to the loss of certain details. In the downscaled image, each pixel represents multiple pixels from the original image.

This process is irreversible, implying that once the information is lost, it cannot be fully recovered. This effect can be observed by reducing an image’s size and then enlarging it back to its original dimensions. The outcome is typically an image that appears blurry or pixelated, indicative of the loss of information.

Given this common occurrence, it is easy to infer that the downscaled version of an image is simply a smaller representation of the original image. However, this is not necessarily the case. In fact, the resulting image can be manipulated to a certain extent by modifying the original image, leading to potentially unexpected outcomes.

As a result of this study, a unique image of the internet personality, PewDiePie, was produced. However, when this image is downscaled, the resulting image surprisingly transforms into one of Elon Musk.

This outcome was accomplished through the application of a numerical optimization algorithm, designed to identify a high-resolution image that bears the maximum possible similarity to the original image, while ensuring that its downscaled version closely resembles the target image. The optimization algorithm employed in this process was Dual Annealing. However, it is important to note that the choice of algorithm is not restrictive, and a wide range of other algorithms could also be utilized effectively.

Potential applications

  • Producing misleading thumbnails

Future work

  • Images that transform into other images when upscaled
  • Images that transform into other images when downscaled, and a different image when upscaled


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:
        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])
img = Image.fromarray(opt.x.reshape((256,256))).convert("L")