Upsampling images with Lanczos kernel

Resampling images is a very common operation in IDL, and it can happen both implicitly as well explicitly. Implicit resampling happens with IDLgrImage rendering. When the destination rendering area contains fewer pixels than the original image, then downsampling occurs. When the destination area is larger than the original image, then upsampling occurs. There are many options for upsampling algorithms. The simplest is a pure pixel replication to fill in the gaps. This is useful when there is a need to look closely at the original data. However, if the goal is to look for details in the scene that may be approaching the limits of the image resolution, then a more sophisticated resampling algorithm should be chosen instead. There are a few options that are commonly used. Bilinear interpolation and cubic spline interpolation are both options that are available with the CONGRID function in IDL. Lanczos and Lagrange resampling are two other options that are more computationally intensive. In the code below, I am showing an example comparing the Lanczos resampling kernel with bilinear and pixel replication. Lanczos resampling is often preferred because of its ability to preserve and even enhance local contrast, whereas bilinear tends have a blurring effect.

functionlanczos, data

xval = [-3:3:.25]

lanc3 = 3*sin(!pi*xval)*(sin(!pi*xval/3d)/!pi/!pi/xval/xval)

lanc3[where(xval eq0)] = 1

l2d = lanc3 # lanc3

; high resolution version

msk = fltarr(data.dim*4)

msk[0:*:4,0:*:4] = data

hi = convol(msk, l2d, /edge_trunc)

hi = byte(round(hi>0<255))

return, hi

end

proupsample_example

compile_opt idl2,logical_predicate

; Read the original image data

f = filepath('moon_landing.png', subdir=['examples','data'])

data = read_png(f)

dim = data.dim

window, xsize=dim[0], ysize=dim[1], 0, title='Original full size'

tv, data

; Define a zoomed in are on the flag.

xs = 200

ys = 165

dx = 40

dy = 40

; display upsampled 4x with pixel replication

window, xsize=160, ysize=160, 1, title='CONGRID pixel-replication'

tv, congrid(data[xs:xs+dx-1,ys:ys+dy-1],160,160)

; display upsampled 4x with bilinear interpretation

window, xsize=160, ysize=160, 2, title='CONGRID linear'

tv, congrid(data[xs:xs+dx-1,ys:ys+dy-1],160,160,/interp)

; display upsampled 4x with Lanczos convolution

window, xsize=160, ysize=160, 3, title='Lanczos'

tv, (lanczos(data))[xs*4:xs*4+dx*4-1,ys*4:ys*4+dy*4-1]

end

The results are shown here, starting with the original image, then the 4x zoomed area with pixel replication, then the 4x zoomed with bilinear interpolation, and finally the 4x zoomed with Lanczos convolution. The Lanczos convolution has the advantage of retaining good contrast while avoiding looking too pixelated.