图像处理之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.

相关文章
|
16天前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
23 0
|
16天前
|
监控 算法 图计算
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
18 0
|
16天前
|
算法 Java 计算机视觉
图像处理之积分图算法
图像处理之积分图算法
13 2
|
16天前
|
资源调度 算法 计算机视觉
图像处理之积分图应用二(快速边缘保留滤波算法)
图像处理之积分图应用二(快速边缘保留滤波算法)
10 0
|
16天前
|
算法 BI 计算机视觉
图像处理之积分图应用一(半径无关的快速模糊算法)
图像处理之积分图应用一(半径无关的快速模糊算法)
11 0
|
1天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。
|
4天前
|
机器学习/深度学习 算法 数据可视化
m基于PSO-LSTM粒子群优化长短记忆网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,应用PSO优化的LSTM模型提升了电力负荷预测效果。优化前预测波动大,优化后预测更稳定。PSO借鉴群体智能,寻找LSTM超参数(如学习率、隐藏层大小)的最优组合,以最小化误差。LSTM通过门控机制处理序列数据。代码显示了模型训练、预测及误差可视化过程。经过优化,模型性能得到改善。
19 6
|
1天前
|
缓存 算法
基于机会网络编码(COPE)的卫星网络路由算法matlab仿真
**摘要:** 该程序实现了一个基于机会网络编码(COPE)的卫星网络路由算法,旨在提升无线网络的传输效率和吞吐量。在MATLAB2022a中测试,结果显示了不同数据流个数下的网络吞吐量。算法通过Dijkstra函数寻找路径,计算编码机会(Nab和Nx),并根据编码机会减少传输次数。当有编码机会时,中间节点执行编码和解码操作,优化传输路径。结果以图表形式展示,显示数据流与吞吐量的关系,并保存为`R0.mat`。COPE算法预测和利用编码机会,适应卫星网络的动态特性,提高数据传输的可靠性和效率。
|
4天前
|
算法 调度
基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图
**摘要:** 实现变异混合蛙跳算法的MATLAB2022a版车间调度优化程序,支持动态调整工件和机器数,输出甘特图。核心算法结合SFLA与变异策略,解决Job-Shop Scheduling Problem,最小化总完成时间。SFLA模拟蛙群行为,分组进行局部搜索和全局信息交换。变异策略增强全局探索,避免局部最优。程序初始化随机解,按规则更新,经多次迭代和信息交换后终止。
|
9天前
|
算法 JavaScript 决策智能
基于禁忌搜索算法的TSP路径规划matlab仿真
**摘要:** 使用禁忌搜索算法解决旅行商问题(TSP),在MATLAB2022a中实现路径规划,显示优化曲线与路线图。TSP寻找最短城市访问路径,算法通过避免局部最优,利用禁忌列表不断调整顺序。关键步骤包括初始路径选择、邻域搜索、解评估、选择及禁忌列表更新。过程示意图展示搜索效果。