跳转至

Upsampling images using a Lagrange polynomial method

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/upsampling-images-using-a-lagrange-polynomial-method

15483 Rate this article:

3.0

Upsampling images using a Lagrange polynomial method

Anonym Sunday, August 28, 2016

A few weeks ago I posted about using the Lanczos kernel for resampling images to a higher resolution. This week I am continuing with the same example, but adding in the Lagrange resampling method. Both Lagrange and Lanczos have some similar characteristics in that they show better detail than a purely linear interpolation. Both methods can also be adapted to an irregularly gridded dataset instead of the raster images used in my examples here. The code produces 4 upsampled images using different methods, and the results are shown below.

function lanczos, data

xval = [-3:3:.25]

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

lanc3[where(xval eq 0)] = 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

function lagrange, a, x, y

compile_opt idl2, logical_predicate

xf = floor(x)

yf = floor(y)

x1 = x - xf

y1 = y - yf

off = [-1,0,1,2]

retval = replicate(0., size(x, /DIM))

weightx = replicate(1., [size(x1, /DIM),4])

weighty = replicate(1., [size(x1, /DIM),4])

for i=0,3 do begin

for j=0,3 do begin

if i ne j then begin

weightx[*,*,i] *= (x1 - off[j]) / (off[i] - off[j])

weighty[*,*,i] *= (y1 - off[j]) / (off[i] - off[j])

endif

endfor

endfor

for i=0,3 do begin

for j=0,3 do begin

retval += weightx[*,*,j] * weighty[*,*,i] * a[xf+off[j], yf+off[i]]

endfor

endfor

return, retval

end

pro upsample_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 = 120

ys = 105

dx = 60

dy = 100

; display upsampled 4x with pixel replication

window, xsize=4*dx, ysize=4*dy, 1, title='CONGRID pixel-replication'

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

write_png,'moon-pixel-replication.png',tvrd()

; display upsampled 4x with bilinear interpretation

window, xsize=4*dx, ysize=4*dy, 2, title='CONGRID linear'

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

write_png,'moon-bilinear.png',tvrd()

; display upsampled 4x with Lanczos convolution

window, xsize=4*dx, ysize=4*dy, 3, title='Lanczos'

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

write_png,'moon-lanczos.png',tvrd()

; Lagrange

window, xsize=4*dx, ysize=4*dy, 4, title='Lagrange'

xcoord = [float(xs):xs+dx:0.25]

ycoord = [float(ys):ys+dy:0.25]

tv, byte(lagrange(float(data), $

xcoord # replicate(1,1,ycoord.length), $

replicate(1,xcoord.length) # ycoord)>0<255)

write_png,'moon-lagrange.png',tvrd()

end

Pixel replication

Bi-linear interpolation

Lanczos resampling

Lagrange resampling

Minimum Area Bounding Box App Update Check - Coming soon in IDL 8.6 and ENVI 5.4