The Art and Science of Interpolation

3i5g...ueVp
17 Feb 2024
37



Image interpolation is a computational process used in digital image processing to estimate unknown pixel values. It comes into play when images are resized, or transformed, or when missing parts need to be filled in.

The essence of interpolation lies in creating a smooth transition between known pixel values, thereby generating new pixels in a way that maintains the overall integrity and quality of the image.


If you are not familiar with pixels and images take a look at the following article:


But how are images created?

A quick introduction to pixels and color channels.
medium.com

. . .

How interpolation works


At a fundamental level, image interpolation methods rely on surrounding known pixel values to calculate the unknown or new pixel values.

This can be visualized as filling in the blanks in a grid of pixels, where the “blanks” are the new pixels that need to be created.

The goal is to make these new pixels blend seamlessly with the existing ones, preserving edgestextures, and gradients as accurately as possible.

Resizing



Another common example of interpolation is rotating an image. Here we are also applying this technique to rotate the picture into different angles.

The more you know about the surrounding pixels, the better the interpolation will become.

Results quickly deteriorate the more you stretch an image, and interpolation can never add detail which is not already present to your picture.

. . .

Types of interpolation


  1. Nearest neighbor interpolation
  2. Bilinear interpolation
  3. Bicubic interpolation


# Nearest neighbor interpolation


The simplest form of interpolation. It assigns the value of the nearest pixel to the new pixel.

This method is fast but can result in a blocky, less smooth image.


# Bilinear interpolation


Bilinear interpolation considers the closest 2 × 2 neighborhood of known pixel values surrounding the unknown pixel.

It then takes a weighted average of these 4 pixels to arrive at its final interpolated value. This results in much smoother-looking images than the nearest neighbor.


# Bicubic interpolation


Bicubic goes one step beyond bilinear by considering the closest 4 × 4 neighborhood of known pixels — for a total of 16 pixels.

Since these are at various distances from the unknown pixel, closer pixels are given a higher weighting in the calculation.

Bicubic produces noticeably sharper images than the previous two methods and is perhaps the ideal combination of processing time and output quality.

Bicubic interpolation is a standard in many image editing programs (including Adobe Photoshop), printer drivers, and in-camera interpolation.

. . .

Example of interpolation


I´ll pick an image from Unsplash and downsample it to see the whole process.


Before resampling the image, I´ll analyze its dimensions to see the resolution.

You can download the image and keep track of the code of this tutorial.

from PIL import Image
image path = '/mnt/data/horse_medium_interpolation.jpg'

image_info = Image.open(image_path)
image_resolution = image_info.size 
print(image_resolution)


The image resolution is 800 pixels in width by 533 pixels in height.

I will reduce it by a factor of 8 yielding a downsampled size of 100 pixels in width by approximately 66 pixels in height.

Image size (800 × 533) → (100 × 66)

1.- Nearest neighbor method


1.1.- Code


from PIL immport Image
import matplotlib.pyplot as plt

# Define the downscale factor
downscale_factor = 8  
# Downscale the image using the nearest neighbor method
downscaled_image = original_image.resize(
    (original_image.width // downscale_factor, 
     original_image.height // downscale_factor), Image.NEAREST)
# Display the result
plt.figure(figsize=(8, 6))
plt.imshow(downsacale_image)
plt.title('Nearest Neighbor Interpolation')
plt.axis('off')
plt.show()


1.2.- Image Representation



In the displayed image, you can observe the distinctive visual characteristics nearest neighbor produces:

  • Pixelation: The most notable feature is the pixelated appearance, where the individual pixels are enlarged and become visible as distinct squares.


  • Jagged Edges: When the image is downscaled and then upscaled, the straight and diagonal lines become jagged, also known as “staircase” due to the abrupt changes in pixel color and intensity.


Use case


This method is computationally less intensive compared to others, making it fast and suitable for real-time applications where processing power is limited.

2.- Bilinear interpolation method


2.1.- Code


from PIL import Image
import matplotlib.pyplot as plt

# Define the downscale factor
downscale_factor = 8
# Downscale the image using the bilinear method 
downscaled_bilinear = original_image.resize(
    (original_image.width // downscale_factor, 
     original_image.height // downscale_factor), Image.BILINEAR)
# Display the downscaled image
plt.figure(figsize=(8, 6))
plt.imshow(downscaled_bilinear)
plt.title('Bilinear Interpolation')
plt.axis('off')
plt.show()


2.2.- Image Representation



The bilinear interpolation method represents a significant step up from nearest neighbor interpolation in terms of image quality:

  1. Smooth Transitions: Bilinear interpolation calculates the pixel value using a weighted average of the four nearest pixels in the original image, resulting in smoother transitions between pixels. This mitigates the blocky appearance seen in nearest neighbor interpolation.


  1. Reduced Jaggedness: The staircasing effect on the edges is less pronounced with bilinear interpolation. It offers a moderate improvement in rendering diagonals and curves, which appear smoother and less jagged.


Use case


Bilinear interpolation is a commonly used method that offers a reasonable trade-off between image quality and computational efficiency,

3.- Bicubic interpolation method


3.1.- Code


# Downscale the image using the bicubic method
downscaled_bicubic = original_image.resize(
(original_image.width // downscale_factor,
original_image.height // downscale_factor), Image.BICUBIC)

# Display the downscaled image
plt.figure(figsize=(8, 6))
plt.imshow(downscaled_bicubic)
plt.title('Bicubic Interpolation')
plt.axis('off')
plt.show()

3.2.- Image Representation



The bicubic interpolation method is typically used when a high-quality image scaling is required:

  1. High-Quality Results: Bicubic interpolation considers the closest 16 pixels (a 4x4 environment) to estimate the new pixel values using cubic polynomials. This results in a higher quality image with smoother edges and finer detail compared to bilinear and nearest neighbor methods.
  2. Preservation of Details: It generally does a better job of preserving the details in the image, especially when scaling up. The transitions between different intensities and colors are smoother, which often makes the result look more natural and less digital.


Use case


Bicubic interpolation is the most used technique for resampling images. It is more computationally expensive but usually more effective.

Comparing the different methods


Code


from PIL import Image
import matplotlib.pytplot as plt

methods = {
    "Nearest Neighbor": Image.NEAREST,
    "Bilinear": Image.BILINEAR,
    "Bicubic": Image.BICUBIC
}
# Define a larger downscale factor for more pronounced differences
downscale_factor = 8
# Downscale and then upscale the image using different interpolation methods
interpolated_images_large_diff = {}
for method_name, method in methods.items():
    # Downscale
    small_image = original_image.resize(
        (original_image.width // downscale_factor, 
         original_image.height // downscale_factor), method)
    # Upscale back to original size
    interpolated_images_large_diff[method_name] = small_image.resize(original_image.size, method)
# Display the results
plt.figure(figsize=(15, 10))
plt.subplot(2, 2, 1)
plt.imshow(original_image)
plt.title('Original Image')
plt.axis('off')
for i, (method_name, interpolated_image) in enumerate(interpolated_images_large_diff.items(), 2):
    plt.subplot(2, 2, i)
    plt.imshow(interpolated_image)
    plt.title(f'{method_name} Interpolation')
    plt.axis('off')
plt.tight_layout()
plt.show()


Image Representation



Overall, each interpolation method has trade-offs between quality and computational complexity.

  • The nearest neighbor is the fastest but offers the lowest quality, suitable for real-time applications where speed is critical.


  • Bilinear interpolation is a mid-ground, offering a balance between quality and performance.


  • Bicubic interpolation provides the highest quality of the three, making it ideal for applications where a high level of detail is necessary.


Bibliography




Thanks for reading! If you like the article make sure to clap (up to 50!) and follow me on Medium to stay updated with my new articles.

Also, make sure to follow my new publication!

The Deep Hub


Your data science hub. A Medium publication dedicated to exchanging ideas and empowering your knowledge.
medium.com



















Get fast shipping, movies & more with Amazon Prime

Start free trial

Enjoy this blog? Subscribe to souravgg

1 Comment