图像处理之图像快速插值放缩算法

简介: 图像处理之图像快速插值放缩算法

算法思想:

基于双线性算法的分解,分别进行水平与垂直两个方向的放缩,完成对整张图像的放大或

者缩小。基于的数学思想为矩阵的乘法,对一个scale矩阵可以拆分为水平与垂直方向的两

个关联矩阵,具体如下:

1348487435_3142.png

关于什么是双线性插值参加这里:http://blog.csdn.net/jia20003/article/details/6915185

程序解释:

类ScaleFilter完成对图像的快速放大与缩小,接受输入参数为XY方向的放缩比例值。

hscal, vscale的默认值为1.5f即将输入图像在XY放大1.5倍。XY方向的Scale方法参考与运用

了移动窗口的算法。感兴趣可以自己研究,我也是改写一段c语言代码得到。感觉非常的精妙。

程序效果如下:

errno-404.png

Scale Filter的源代码如下:

package com.gloomyfish.filter.study;
/**
 * @author gloomyfish
 * @date 2012-09-23
 * @BLOGPAGE:http://blog.csdn.net/jia20003
 */
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
 
public class ScaleFilter extends AbstractBufferedImageOp {
  
  /**
   * default will zoom in 2.0 * input size of original image.
   */
  private float hscale = 1.5f;
  private float vscale = 1.5f;
  public ScaleFilter() {
    
  }
  
  public void setHscale(float hscale) {
    this.hscale = hscale;
  }
 
  public void setVscale(float vscale) {
    this.vscale = vscale;
  }
 
  @Override
  public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    int width = src.getWidth();
        int height = src.getHeight();
 
        if ( dest == null )
          dest = createCompatibleDestImage( src, null );
 
        // initialization pixel data
        int[] inPixels = new int[width*height];
        int outwidth = (int)(hscale * (float)width);
        int outheight = (int)(vscale * (float)height);
        int[] outhPixels = new int[outwidth*height];
        int[] outPixels = new int[outwidth*outheight];
 
        // start to zoom in/out here
        getRGB( src, 0, 0, width, height, inPixels );
        hscale(inPixels, outhPixels, width, height);
        vscale(outhPixels, outPixels, outwidth, height);
 
        // create buffered image and return it with result image data 
        setRGB( dest, 0, 0, outwidth, outheight, outPixels);
        return dest;
  }
  
    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
        if ( dstCM == null )
            dstCM = src.getColorModel();
        int outwidth = (int)(hscale * (float)src.getWidth());
        int outheight = (int)(vscale * (float)src.getHeight());
        return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(outwidth, outheight), dstCM.isAlphaPremultiplied(), null);
    }
  
  private void hscale(int[] input, int[] output, int width, int height) {
    int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;
    int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
    int sumred = 0, sumgreen = 0, sumblue = 0;
    double accred = 0, accgreen = 0, accblue = 0;
    int p, q;
    int outwidth = (int)(this.hscale * width);
    double area = (outwidth * width);
    int inCol = 0, outCol = 0;
    int inIndex1 = 0, inIndex2 = 0, outIndex = 0;
    for (int row = 0; row < height; row++) {
      q = width;
      p = outwidth;
      accred = accgreen = accblue = 0;
      inCol = outCol = 0;
      while (outCol < outwidth) {
        if(outCol == 299) {
          System.out.println("what are you doing...");
        }
        if ((inCol + 1) < 2) {
          inIndex1 = row * width + inCol;
          inIndex2 = row * width + (inCol + 1);
              ta1 = (input[inIndex1] >> 24) & 0xff;
                  tr1 = (input[inIndex1] >> 16) & 0xff;
                  tg1 = (input[inIndex1] >> 8) & 0xff;
                  tb1 = input[inIndex1] & 0xff;
                  
              ta2 = (input[inIndex2] >> 24) & 0xff;
                  tr2 = (input[inIndex2] >> 16) & 0xff;
                  tg2 = (input[inIndex2] >> 8) & 0xff;
                  tb2 = input[inIndex2] & 0xff;
                  sumred = p * tr1 + (outwidth - p) * tr2;
                  sumgreen = p * tg1 + (outwidth - p) * tg2;
                  sumblue = p * tb1 + (outwidth - p) * tb2;
        }
        else 
        {
          inIndex1 = row * width + inCol;
              ta1 = (input[inIndex1] >> 24) & 0xff;
                  tr1 = (input[inIndex1] >> 16) & 0xff;
                  tg1 = (input[inIndex1] >> 8) & 0xff;
                  tb1 = input[inIndex1] & 0xff;
                  sumred = outwidth * tr1;
                  sumgreen = outwidth * tg1;
                  sumblue = outwidth * tb1;
        }
        if (p < q) {
          accred += sumred * p;
          accgreen += sumgreen * p;
          accblue += sumblue * p;
          q -= p;
          p = outwidth;
          inCol++;
        } else {
          accred += sumred * q;
          accgreen += sumgreen * q;
          accblue += sumblue * q;
          outIndex = row * outwidth + outCol;
          output[outIndex] = ta1 << 24 | ((int)(accred / area) << 16) | ((int)(accgreen / area) << 8) | (int)(accblue / area);
          accred = accgreen = accblue = 0;
          p -= q;
          q = width;
          outCol++;
        }
      }
    }
  }
 
  private void vscale(int[] input, int[] output, int width, int height) {
    int ta1 = 0, tr1 = 0, tg1 = 0, tb1 = 0;
    int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
    int sumred = 0, sumgreen = 0, sumblue = 0;
    double accred = 0, accgreen = 0, accblue = 0;
    int inRow = 0, outRow = 0;
    int inIndex1 = 0, inIndex2 = 0, outIndex = 0;
    int p, q;
    int ih = height;
    int oh = (int)(height * vscale);
    int area = (ih * oh);
    for (int col = 0; col < width; col++) {
      q = ih;
      p = oh;
      accred = accgreen = accblue = 0;
      inRow = outRow = 0;
      while (outRow < oh) {
        if (inRow+1 < ih) {
          inIndex1 = inRow * width + col;
          inIndex2 = (inRow+1) * width + col;
              ta1 = (input[inIndex1] >> 24) & 0xff;
                  tr1 = (input[inIndex1] >> 16) & 0xff;
                  tg1 = (input[inIndex1] >> 8) & 0xff;
                  tb1 = input[inIndex1] & 0xff;
                  
              ta2 = (input[inIndex2] >> 24) & 0xff;
                  tr2 = (input[inIndex2] >> 16) & 0xff;
                  tg2 = (input[inIndex2] >> 8) & 0xff;
                  tb2 = input[inIndex2] & 0xff;
                  sumred = p * tr1 + (oh - p) * tr2;
                  sumgreen = p * tg1 + (oh - p) * tg2;
                  sumblue = p * tb1 + (oh - p) * tb2;
        }
        else
        {
          inIndex1 = inRow * width + col;
              ta1 = (input[inIndex1] >> 24) & 0xff;
                  tr1 = (input[inIndex1] >> 16) & 0xff;
                  tg1 = (input[inIndex1] >> 8) & 0xff;
                  tb1 = input[inIndex1] & 0xff;
                  sumred = oh * tr1;
                  sumgreen = oh * tg1;
                  sumblue = oh * tb1;
        }
        if (p < q) {
          accred += sumred * p;
          accgreen += sumgreen * p;
          accblue += sumblue * p;
          q -= p;
          p = oh;
          inRow++;
        } else {
          accred += sumred * q;
          accgreen += sumgreen * q;
          accblue += sumblue * q;
          outIndex = outRow * width + col;
          
          output[outIndex] = ta1 << 24 | ((int)(accred / area) << 16) | ((int)(accgreen / area) << 8) | (int)(accblue / area);
          accred = accgreen = accblue = 0;
          p -= q;
          q = ih;
          outRow++;
        }
      }
    }   
  }
}

后注:其效果近似与双线性内插值算法,但是运行速度却是它的几十倍之多,感兴趣者

可以自己测试。证明我没有信口开河。


相关文章
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
1月前
|
机器学习/深度学习 人工智能 算法
【MM2024】面向 StableDiffusion 的多目标图像编辑算法 VICTORIA
阿里云人工智能平台 PAI 团队与华南理工大学合作在国际多媒体顶级会议 ACM MM2024 上发表 VICTORIA 算法,这是一种面向 StableDiffusion 的多目标图像编辑算法。VICTORIA 通过文本依存关系来修正图像编辑过程中的交叉注意力图,从而确保关系对象的一致性,支持用户通过修改描述性提示一次性编辑多个目标。
|
1月前
|
算法 数据安全/隐私保护
织物图像的配准和拼接算法的MATLAB仿真,对比SIFT,SURF以及KAZE
本项目展示了织物瑕疵检测中的图像拼接技术,使用SIFT、SURF和KAZE三种算法。通过MATLAB2022a实现图像匹配、配准和拼接,最终检测并分类织物瑕疵。SIFT算法在不同尺度和旋转下保持不变性;SURF算法提高速度并保持鲁棒性;KAZE算法使用非线性扩散滤波器构建尺度空间,提供更先进的特征描述。展示视频无水印,代码含注释及操作步骤。
|
2月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
3月前
|
算法 前端开发 计算机视觉
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
42 0
|
24天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
9天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
10天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
11天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。
|
10天前
|
机器学习/深度学习 算法 芯片
基于GSP工具箱的NILM算法matlab仿真
基于GSP工具箱的NILM算法Matlab仿真,利用图信号处理技术解析家庭或建筑内各电器的独立功耗。GSPBox通过图的节点、边和权重矩阵表示电气系统,实现对未知数据的有效分类。系统使用MATLAB2022a版本,通过滤波或分解技术从全局能耗信号中提取子设备的功耗信息。