使用拉格朗日多项式方法对图像进行上采样
15483 文章评分:
3.0
使用拉格朗日多项式方法对图像进行上采样
匿名 星期日, 2016年8月28日
几周前,我发布了一篇关于使用兰克索斯(Lanczos)核对图像进行重采样以获得更高分辨率的文章。这周我继续使用同一个示例,但加入了拉格朗日(Lagrange)重采样方法。拉格朗日方法和兰克索斯方法有一些相似的特性,它们都比纯粹的线性插值显示出更好的细节。这两种方法也可以适用于不规则网格化的数据集,而不仅仅是我这里示例中使用的栅格图像。代码使用不同的方法生成了4张上采样后的图像,结果如下所示。
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
![]()
像素复制

双线性插值

兰克索斯重采样

拉格朗日重采样