图像处理之基于一维高斯快速模糊

简介: 图像处理之基于一维高斯快速模糊

数学基础:

二维高斯模糊的数学表达如下:

简单表达为G(x, y) = G(x)G(y)由此,对一个二维的像素矩阵可以分别在水平与垂直方向

进行一维高斯模糊其效果等同与二维高斯模糊效果。由于计算量的减少,速度却比二维

高斯模糊更快。

运行结果:


关键代码解析:

生成一维高斯核的代码如下,其中对高斯核实现归一化预处理

private float[] generateGaussianKeneral(int n, float sigma) {
  float sigma22 = 2*sigma*sigma;
  float Pi2 = 2*(float)Math.PI;
  float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ;
  int size = 2*n + 1;
  int index = 0;
  gaussianKeneral = new float[size];
  float sum = 0.0f;
  for(int i=-n; i<=n; i++) {
    float distance = i*i;
    gaussianKeneral[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2;
    //System.out.println("\t" + gaussianKeneral[index]);
    sum += gaussianKeneral[index];
    index++;
  }
  
  // nomalization to 1
  for(int i=0; i<gaussianKeneral.length; i++) {
    gaussianKeneral[i] = gaussianKeneral[i]/sum;
    //System.out.println("final gaussian data " + i + " = " + gaussianKeneral[i]);
  } 
  return gaussianKeneral;
}


实现对越界像素值的处理:

public static int clamp(float a) {
  return (int)(a < 0 ?  0 : ((a > 255) ? 255 : a));
}

全部算法源代码如下:

package com.gloomyfish.filter.study;
 
import java.awt.image.BufferedImage;
 
public class HVGaussianFilter extends AbstractBufferedImageOp {
  private float[] gaussianKeneral = null;
  private int radius = 2; // default value
  private float sigma = 10;
  public HVGaussianFilter() {
    
  }
  
  public void setSigma(float a) {
    this.sigma = a;
  }
  
  public void setRadius(int size) {
    this.radius = size;
  }
  
  public float[][] getHVGaussianKeneral() {
    float[][] hvKeneralData = new float[5][5];
    for(int i=0; i<5; i++)
    {
      for(int j=0; j<5; j++) 
      {
        hvKeneralData[i][j] = gaussianKeneral[i] * gaussianKeneral[j];
      }
    }
    return hvKeneralData;
  }
  
  @Override
  public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    generateGaussianKeneral(radius, sigma);
        int width = src.getWidth();
        int height = src.getHeight();
 
        if ( dest == null )
          dest = createCompatibleDestImage( src, null );
 
        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 0, 0, width, height, inPixels);
        blur( inPixels, outPixels, width, height); // H Gaussian
        blur( outPixels, inPixels, height, width); // V Gaussain
        setRGB(dest, 0, 0, width, height, inPixels );
        return dest;
  }
 
  /**
   * <p> here is 1D Gaussian        , </p>
   * 
   * @param inPixels
   * @param outPixels
   * @param width
   * @param height
   */
  private void blur(int[] inPixels, int[] outPixels, int width, int height)
  {
    int subCol = 0;
    int index = 0, index2 = 0;
    float redSum=0, greenSum=0, blueSum=0;
        for(int row=0; row<height; row++) {
          int ta = 0, tr = 0, tg = 0, tb = 0;
          index = row;
          for(int col=0; col<width; col++) {
            // index = row * width + col;
            redSum=0;
            greenSum=0;
            blueSum=0;
            for(int m=-2; m<=2; m++) {
              subCol = col + m;
              if(subCol < 0 || subCol >= width) {
                subCol = 0;
              }
              index2 = row * width + subCol;
                ta = (inPixels[index2] >> 24) & 0xff;
                    tr = (inPixels[index2] >> 16) & 0xff;
                    tg = (inPixels[index2] >> 8) & 0xff;
                    tb = inPixels[index2] & 0xff;
                    redSum += (tr * gaussianKeneral[m + 2]);
                    greenSum += (tg * gaussianKeneral[m + 2]);
                    blueSum += (tb * gaussianKeneral[m + 2]);
            }
            outPixels[index] = (ta << 24) | (clamp(redSum) << 16) | (clamp(greenSum) << 8) | clamp(blueSum);
            index += height;// correct index at here!!!, out put pixels matrix,
          }
        }
  }
  
  public static int clamp(float a) {
    return (int)(a < 0 ?  0 : ((a > 255) ? 255 : a));
  }
  
  private float[] generateGaussianKeneral(int n, float sigma) {
    float sigma22 = 2*sigma*sigma;
    float Pi2 = 2*(float)Math.PI;
    float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ;
    int size = 2*n + 1;
    int index = 0;
    gaussianKeneral = new float[size];
    float sum = 0.0f;
    for(int i=-n; i<=n; i++) {
      float distance = i*i;
      gaussianKeneral[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2;
      //System.out.println("\t" + gaussianKeneral[index]);
      sum += gaussianKeneral[index];
      index++;
    }
    
    // nomalization to 1
    for(int i=0; i<gaussianKeneral.length; i++) {
      gaussianKeneral[i] = gaussianKeneral[i]/sum;
      //System.out.println("final gaussian data " + i + " = " + gaussianKeneral[i]);
    } 
    return gaussianKeneral;
  }
 
}

转载文章请务必注明!

相关文章
|
22天前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
91 0
|
23天前
|
机器学习/深度学习 资源调度 算法
图像处理之高斯模糊
图像处理之高斯模糊
22 0
|
23天前
|
算法 C语言 计算机视觉
图像处理之图像快速插值放缩算法
图像处理之图像快速插值放缩算法
19 0
|
1月前
|
算法 计算机视觉
OpenCV高斯差分技术实现图像边缘检测
OpenCV高斯差分技术实现图像边缘检测
|
1月前
|
10月前
|
编解码 算法 Java
基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)
基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)
|
资源调度 算法 API
OpenCV_06 图像平滑:图像噪声+图像平滑+滤波
由于图像采集、处理、传输等过程不可避免的会受到噪声的污染,妨碍人们对图像理解及分析处理。常见的图像噪声有高斯噪声、椒盐噪声等。
110 0
|
资源调度 算法 机器人
图像特征提取与描述_角点特征02:SIFT算法+SURF算法
前面两节我们介绍了Harris和Shi-Tomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗口,就检测不到角点了。
143 0
|
资源调度 计算机视觉
CV10 图像模糊(均值、高斯、中值、双边滤波)
当我们只想得到感兴趣的物体时,通过图像模糊,可以将那些尺寸和亮度较小的物体过滤掉,较大的物体则易于检测。除了降低噪声,这就是图像平滑(模糊)的另一个重要应用:减少噪点,突出ROI,以便目标提取。
265 0
|
机器学习/深度学习 传感器 算法
【边缘检测】基于模糊算法的图像边缘检测附matlab代码
【边缘检测】基于模糊算法的图像边缘检测附matlab代码