跳转至

使用拉格朗日多项式方法对图像进行上采样

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

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

像素复制

双线性插值

兰克索斯重采样

拉格朗日重采样

最小面积外接矩形 应用程序更新检查 - 即将在 IDL 8.6 和 ENVI 5.4 中发布