Punks for Printers

My 15 year old son bears a striking resemblance to Crypto Punk #2101. For his birthday, I’d like to get him a high quality, framed print of #2101 that he can showcase proudly in his room. Unfortunately, the original punk images are only available at a very low resolution and aren’t printshop ready. In this post, I’ll show how to upscale a low-rez image using Python, Tensorflow and Keras so the images will be ready for printing at 300 Dots per Inch (DPI).

First, load punk #2101 into memory and take a look.

import cryptopunks.utils as cp
img = cp.get_punk(2101)
plt.imshow(img) 
Punk #2101
Punk #2101

Upsampling images with Keras and UpSampling2d

The Keras library for building deep neural networks provides a layer that is useful for increasing the resolution of images. Upsampling2d takes a multidimensional array as input and doubles each pixel value in the input resulting in an output image that is twice the size.

We can use this layer to repeatedly upsample the 24 x 24 cryptopunks until we have an image of the size we want. For print quality, we’ll need 300 Dots per Inch (DPI), so, if we want a 10 X 10 inch image, we’ll need to upscale the punks to be size 3000 x 3000. We can do this with a simple Keras network like the following …

model = keras.Sequential()
model.add(layers.UpSampling2D(input_shape=(24, 24, 4)))
model.add(layers.UpSampling2D(input_shape=(48, 48 , 4)))
model.add(layers.UpSampling2D(input_shape=(192, 192, 4)))
model.add(layers.UpSampling2D(input_shape=(384, 384, 4)))
model.add(layers.UpSampling2D(input_shape=(768, 768, 4)))
model.add(layers.UpSampling2D(input_shape=(1536, 1536, 4)))
model.summary()

Take a look at the network shape using the summary method of model.

Model: "sequential_8"
_______________________________________________________________
Layer (type)                 Output Shape              Param #   
===============================================================
up_sampling2d_31 (UpSampling (None, 48, 48, 4)         0         
_______________________________________________________________
up_sampling2d_32 (UpSampling (None, 96, 96, 4)         0         
_______________________________________________________________
up_sampling2d_33 (UpSampling (None, 192, 192, 4)       0         
_______________________________________________________________
up_sampling2d_34 (UpSampling (None, 384, 384, 4)       0         
_______________________________________________________________
up_sampling2d_35 (UpSampling (None, 768, 768, 4)       0         
===============================================================
up_sampling2d_35 (UpSampling (None, 1536, 1536, 4)       0        
===============================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0

Note that this model doesn’t have any parameters; it’s not a typical Keras model that must be trained on data before it can predict. The model is ready to make predictions, that is, it will predict a new images of size 3072 x 3072.

X_ = img.reshape((1,24,24,4))
Y = model.predict(X_)
plt.imshow(y[0])
Upscaled Punk
Upscaled Punk

That’s it. The upscaled punk image is print ready and will make a nice 10in X 10in print at 300DPI. While this is a round about way of getting images print-ready, it avoids the need to introduce another image processing library and is completely programmable, that is, going from 1 to 10,000 upscale punks is as simple as a for loop.

FWIW, I’d also like to be able to buy my son the actual #2101 NFT, but at a 500K valuation, I’m completely comfortable with the simulacra.

Subscribe to 0x9C65…e51c
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.