Comparison of OpenCV Interpolation Algorithms

The following are comparisons of the different image interpolation algorithms available in OpenCV. The exampes are shown for both upsizing and downsizing images. Also shown is a comparison of the speed of the different algorithms.

The algorithms are: (descriptions are from the OpenCV documentation)

  • INTER_NEAREST - a nearest-neighbor interpolation
  • INTER_LINEAR - a bilinear interpolation (used by default)
  • INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
  • INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
  • INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
In [1]:
%pylab inline
import cv2
import imageio
import itertools
import matplotlib.gridspec as gridspec
import pandas as pd
import time

# standard images in imageio
ref_images = ["coffee.png", "page.png", "immunohistochemistry.png", "horse.png"] 
# Limit starting size
images_orig = [cv2.resize(imageio.imread(im), (400,400)) for im in ref_images] 
# interpolation methods to compare
methods=[("area", cv2.INTER_AREA), 
         ("nearest", cv2.INTER_NEAREST), 
         ("linear", cv2.INTER_LINEAR), 
         ("cubic", cv2.INTER_CUBIC), 
         ("lanczos4", cv2.INTER_LANCZOS4)]
# opencv version
print "opencv version", cv2.__version__
Populating the interactive namespace from numpy and matplotlib
opencv version 2.4.12
In [2]:
# function to display images
def display(images, titles=['']):
    if isinstance(images[0], list):
        c = len(images[0])
        r = len(images)
        images = list(itertools.chain(*images))
    else:
        c = len(images)
        r = 1
    plt.figure(figsize=(4*c, 4*r))
    gs1 = gridspec.GridSpec(r, c, wspace=0, hspace=0)
    #gs1.update(wspace=0.01, hspace=0.01) # set the spacing between axes. 
    titles = itertools.cycle(titles)
    for i in range(r*c):
        im = images[i]
        title = titles.next()
        plt.subplot(gs1[i])
        # Don't let imshow doe any interpolation
        plt.imshow(im, cmap='gray', interpolation='none')
        plt.axis('off')
        if i < c:
            plt.title(title)
    plt.tight_layout()

Upsampling comparison

Take a 50x50 image and rescale it to 400x400 pixels. For ease of comparison, the original and the rescaled are shown at the same size so the algorithm image quality can be compared. For updampling, area & nearest algorithms create jagged edges while the linear makes smoother edges. The cubic and Lanczos make the sharpest edges.

In [3]:
images_small = [cv2.resize(im, (50,50),interpolation=cv2.INTER_AREA) for im in images_orig]
image_set = [[cv2.resize(im, (400,400), interpolation=m[1]) for m in methods] for im in images_small]
image_set = [[ima,]+imb for ima, imb in zip(images_small, image_set)]
names = ["original 50x50",] + [m[0]+" 400x400" for m in methods]
display(image_set, names)
# plt.savefig("opencv_interpolation_upsample.jpg", dpi=75)