图像处理之积分图应用一(半径无关的快速模糊算法)

简介: 图像处理之积分图应用一(半径无关的快速模糊算法)

图像处理之积分图像应用一(半径无关的快速模糊算法)


一:基本原理概述


传统的图像空间域卷积模糊算法,当窗口大小改变时卷积模糊时间也会变化,而且随着窗口尺寸越大计算量也越大,算法运行时间约越长。在很多时候无法满足实时性要求。而基于积分图像可以实现对窗口区域和大小的快速计算,把传统卷积模糊计算受窗口大小影响消除,把卷积模糊变成一个与窗口大小半径无关的常量时间完成的操作。关于如何从图像本身得到积分图像的算法请看上一篇文章《图像处理之积分图像算法》


二:详细解释


以5x5的窗口大小为例,假设图像I、积分图像II、处理之后模糊图像BI、则传统空间域卷积实现的图像均值模糊对每个像素点公式表示如下:


基于积分图像计算每个像素点模糊公式表示如下:

上述基于传统的均值模糊计算得到模糊之后的结果要计算24次加法和一次除法共计25次计算,而基于积分图像则只需要一次加法两次减法和一次除法共计四次计算,而且基于传统卷积均值模糊计算当窗口大小越大计算次数也越多,而基于积分图像则计算次数保持常量不变,是一个半径无关的均值模糊算法。


三:代码实现


积分图像算法实现参见:http://blog.csdn.net/jia20003/article/details/52710751


传统模式的卷积模糊代码如下:

package com.gloomyfish.ii.demo;
 
import java.awt.image.BufferedImage;
 
public class Convolution2DFilter extends AbstractImageOptionFilter {
  // 窗口半径大小
  private int xr;
  private int yr;
 
  public Convolution2DFilter() {
    xr = 1;
    yr = 1;
  }
 
  public int getXr() {
    return xr;
  }
 
  public void setXr(int xr) {
    this.xr = xr;
  }
 
  public int getYr() {
    return yr;
  }
 
  public void setYr(int yr) {
    this.yr = yr;
  }
 
  @Override
  public BufferedImage process(BufferedImage image) {
    long time = System.currentTimeMillis();
    int width = image.getWidth();
    int height = image.getHeight();
 
    int[] pixels = new int[width * height];
    int[] outPixels = new int[width * height];
    getRGB(image, 0, 0, width, height, pixels);
    int size = (xr * 2 + 1) * (yr * 2 + 1);
    int r = 0, g = 0, b = 0;
 
    for (int row = yr; row < height - yr; row++) {
      for (int col = xr; col < width - xr; col++) {
        int sr = 0, sg = 0, sb = 0;
        // 鍗风Н鎿嶄綔/妯℃澘璁$畻
        for (int i = -yr; i <= yr; i++) {
          int roffset = row + i;
          for (int j = -xr; j <= xr; j++) {
            int coffset = col + j;
            sr += ((pixels[roffset * width + coffset] >> 16) & 0xff);
            sg += (pixels[roffset * width + coffset] >> 8) & 0xff;
            sb += (pixels[roffset * width + coffset] & 0xff);
          }
        }
 
        r = sr / size;
        g = sg / size;
        b = sb / size;
        outPixels[row * width + col] = (0xff << 24) | (r << 16) | (g << 8) | b;
      }
    }
    System.out.println("Convolution2DFilter ->> time duration : " + (System.currentTimeMillis() - time));
    BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    setRGB(dest, 0, 0, width, height, outPixels);
    return dest;
  }
 
}

基于积分图像的快速模糊代码如下:

package com.gloomyfish.ii.demo;
 
import java.awt.image.BufferedImage;
 
public class FastBlurFilter extends AbstractImageOptionFilter {
  // 窗口半径大小
  private int xr;
  private int yr;
 
  public FastBlurFilter() {
    xr = 1;
    yr = 1;
  }
 
  public int getXr() {
    return xr;
  }
 
  public void setXr(int xr) {
    this.xr = xr;
  }
 
  public int getYr() {
    return yr;
  }
 
  public void setYr(int yr) {
    this.yr = yr;
  }
 
  @Override
  public BufferedImage process(BufferedImage image) {
    long time = System.currentTimeMillis();
    int width = image.getWidth();
    int height = image.getHeight();
    // get image data
    int[] pixels = new int[width * height];
    int[] outPixels = new int[width * height];
    getRGB(image, 0, 0, width, height, pixels);
    int size = (xr * 2 + 1) * (yr * 2 + 1);
    int r = 0, g = 0, b = 0;
    
    // per-calculate integral image
    byte[] R = new byte[width*height];
    byte[] G = new byte[width*height];
    byte[] B = new byte[width*height];
    getRGB(width, height, pixels, R, G, B);
    IntIntegralImage rii = new IntIntegralImage();
    rii.setImage(R);
    rii.process(width, height);
    IntIntegralImage gii = new IntIntegralImage();
    gii.setImage(G);
    gii.process(width, height);
    IntIntegralImage bii = new IntIntegralImage();
    bii.setImage(B);
    bii.process(width, height);
 
    for (int row = yr; row < height - yr; row++) {
      for (int col = xr; col < width - xr; col++) {
        int sr = rii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        int sg = gii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        int sb = bii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        r = sr / size;
        g = sg / size;
        b = sb / size;
        outPixels[row * width + col] = (0xff << 24) | (r << 16) | (g << 8) | b;
      }
    }
    System.out.println("FastBlurFilter ->> time duration : " + (System.currentTimeMillis() - time));
    BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    setRGB(dest, 0, 0, width, height, outPixels);
    return dest;
  }
  
  /** Returns the red, green and blue planes as 3 byte arrays. */
  public void getRGB(int width, int height, int[] pixels, byte[] R, byte[] G, byte[] B) {
    int c, r, g, b;
    for (int i=0; i < width*height; i++) {
      c = pixels[i];
      r = (c&0xff0000)>>16;
      g = (c&0xff00)>>8;
      b = c&0xff;
      R[i] = (byte)r;
      G[i] = (byte)g;
      B[i] = (byte)b;
    }
  }
 
}

四:效率之比

分别把窗口半径调整到1、3、10、20的情况下,对同一张图像做模糊处理,CPU耗时直方图如下:


可见在其它条件不改变的情况下,窗口半径越大,两者之间执行时间差距越大。各位国庆节快乐!

相关文章
|
4天前
|
存储 自然语言处理 算法
位运算入门及简单算法题的应用
位运算入门及简单算法题的应用
11 1
|
2天前
|
算法 程序员 数据处理
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
|
2天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
2天前
|
存储 算法
【数据结构和算法】---二叉树(2)--堆的实现和应用
【数据结构和算法】---二叉树(2)--堆的实现和应用
5 0
|
6天前
|
算法 索引
DFS算法及应用(二)
回溯:回溯就是DFS的一种,在搜索探索过程中寻找问题的解,当发现不满足求解条件时,就回溯返回,尝试其他路径。
|
2天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
23 8
|
4天前
|
算法
基于GA遗传优化的混合发电系统优化配置算法matlab仿真
**摘要:** 该研究利用遗传算法(GA)对混合发电系统进行优化配置,旨在最小化风能、太阳能及电池储能的成本并提升系统性能。MATLAB 2022a用于实现这一算法。仿真结果展示了一系列图表,包括总成本随代数变化、最佳适应度随代数变化,以及不同数据的分布情况,如负荷、风速、太阳辐射、弃电、缺电和电池状态等。此外,代码示例展示了如何运用GA求解,并绘制了发电单元的功率输出和年变化。该系统原理基于GA的自然选择和遗传原理,通过染色体编码、初始种群生成、适应度函数、选择、交叉和变异操作来寻找最优容量配置,以平衡成本、效率和可靠性。
|
5天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。
|
5天前
|
机器学习/深度学习 算法 数据可视化
基于BP神经网络的64QAM解调算法matlab性能仿真
**算法预览图省略** MATLAB 2022A版中,运用BP神经网络进行64QAM解调。64QAM通过6比特映射至64复数符号,提高数据速率。BP网络作为非线性解调器,学习失真信号到比特的映射,对抗信道噪声和多径效应。网络在处理非线性失真和复杂情况时展现高适应性和鲁棒性。核心代码部分未显示。
|
3天前
|
算法 计算机视觉
基于Chan-Vese算法的图像边缘提取matlab仿真
**算法预览展示了4幅图像,从边缘检测到最终分割,体现了在matlab2022a中应用的Chan-Vese水平集迭代过程。核心代码段用于更新水平集并显示迭代效果,最后生成分割结果及误差曲线。Chan-Vese模型(2001)是图像分割的经典方法,通过最小化能量函数自动检测平滑区域和清晰边界的图像分割,适用于复杂环境,广泛应用于医学影像和机器视觉。**