图像处理之Lanczos采样放缩算法

简介: 图像处理之Lanczos采样放缩算法

图像处理之Lanczos采样放缩算法

一:什么是Lanczos采样

参见这里:http://en.wikipedia.org/wiki/Lanczos_resampling

二:大致算法流程

三:算法运行结果

1.向下采样, 生成缩略图, 左边为原图,右边为缩略图


向上采样,生成放大图像时效果:

算法源代码:

package com.gloomyfish.zoom.study;
 
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
 
import com.gloomyfish.filter.study.AbstractBufferedImageOp;
 
public class LanczosScaleFilter extends AbstractBufferedImageOp {
  // lanczos_size
  private float lanczosSize;
  private float destWidth;
  
  public LanczosScaleFilter()
  {
    lanczosSize = 3;
    destWidth = 100;
  }
 
  public LanczosScaleFilter(float lobes, int width) {
    this.lanczosSize = lobes;
    this.destWidth = width;
  }
 
  public void setLanczosSize(float size) {
    this.lanczosSize = size;
  }
 
  public void setDestWidth(float destWidth) {
    this.destWidth = destWidth;
  }
 
  @Override
  public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    int width = src.getWidth();
    int height = src.getHeight();
    float ratio = width / this.destWidth;
    float rcp_ratio = 2.0f / ratio;
    float range2 = (float) Math.ceil(ratio * lanczosSize / 2);
    
    // destination image
    int dh = (int)(height * (this.destWidth/width));
    int dw = (int)this.destWidth;
 
    if (dest == null) {
      ColorModel cMD = src.getColorModel();
      dest = new BufferedImage(src.getColorModel(), cMD.createCompatibleWritableRaster(dw, dh), cMD.isAlphaPremultiplied(), null);
    }
 
    int[] inPixels = new int[width * height];
    int[] outPixels = new int[dw * dh];
    
    getRGB(src, 0, 0, width, height, inPixels);
    int index = 0;
    float fcy = 0, icy = 0, fcx = 0, icx = 0;
    for (int row = 0; row < dh; row++) {
      int ta = 0, tr = 0, tg = 0, tb = 0;
      fcy = (row + 0.5f) * ratio;
      icy = (float) Math.floor(fcy);
      for (int col = 0; col < dw; col++) {
        fcx = (col + 0.5f) * ratio;
        icx = (float) Math.floor(fcx);
 
        float sumred = 0, sumgreen = 0, sumblue = 0;
        float totalWeight = 0;
        for (int subcol = (int) (icx - range2); subcol <= icx + range2; subcol++) {
          if (subcol < 0 || subcol >= width)
            continue;
          int ncol = (int) Math.floor(1000 * Math.abs(subcol - fcx));
 
          for (int subrow = (int) (icy - range2); subrow <= icy + range2; subrow++) {
            if (subrow < 0 || subrow >= height)
              continue;
            int nrow = (int) Math.floor(1000 * Math.abs(subrow - fcy));
            float weight = (float) getLanczosFactor(Math.sqrt(Math.pow(ncol * rcp_ratio, 2)
                + Math.pow(nrow * rcp_ratio, 2)) / 1000);
            if (weight > 0) {
              index = (subrow * width + subcol);
              tr = (inPixels[index] >> 16) & 0xff;
              tg = (inPixels[index] >> 8) & 0xff;
              tb = inPixels[index] & 0xff;
              totalWeight += weight;
              sumred += weight * tr;
              sumgreen += weight * tg;
              sumblue += weight * tb;
            }
          }
        }
        index = row * dw + col;
        tr = (int) (sumred / totalWeight);
        tg = (int) (sumgreen / totalWeight);
        tb = (int) (sumblue / totalWeight);
        outPixels[index] = (255 << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);
        
        // clear for next pixel
        sumred = 0;
        sumgreen = 0;
        sumblue = 0;
        totalWeight = 0;
 
      }
    }
    setRGB(dest, 0, 0, dw, dh, outPixels);
    return dest;
  }
  
  public static int clamp(int v)
  {
    return v > 255 ? 255 : (v < 0 ? 0 : v);
  }
 
  private double getLanczosFactor(double distance) {
    if (distance > lanczosSize)
      return 0;
    distance *= Math.PI;
    if (Math.abs(distance) < 1e-16)
      return 1;
    double xx = distance / lanczosSize;
    return Math.sin(distance) * Math.sin(xx) / distance / xx;
  }
 
}

五:窗口大小对结果的影响

如果是向下采样生成缩略图的话, 窗口大小设置为3就已经非常清楚了

如果向上采样要放大图像的话, 窗口大小设置要大于6才能获得较好结果,推荐使用窗口

大小为8.

相关文章
|
canal 算法 vr&ar
【图像处理】基于电磁学优化算法的多阈值分割算法研究(Matlab代码实现)
【图像处理】基于电磁学优化算法的多阈值分割算法研究(Matlab代码实现)
324 1
|
机器学习/深度学习 算法 PyTorch
【Pytorch框架搭建神经网络】基于DQN算法、优先级采样的DQN算法、DQN + 人工势场的避障控制研究(Python代码实现)
【Pytorch框架搭建神经网络】基于DQN算法、优先级采样的DQN算法、DQN + 人工势场的避障控制研究(Python代码实现)
344 1
|
机器学习/深度学习 算法 PyTorch
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
501 0
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
963 0
|
监控 算法 图计算
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
652 0
|
资源调度 算法 计算机视觉
图像处理之积分图应用二(快速边缘保留滤波算法)
图像处理之积分图应用二(快速边缘保留滤波算法)
260 0
|
12月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
932 0
|
12月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
561 2
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
482 3
|
12月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
523 8

热门文章

最新文章