图像处理之应用卷积一实现噪声消去

简介: 图像处理之应用卷积一实现噪声消去

讨论如何使用卷积作为数学工具来处理图像,实现图像的滤波,其方法包含以下几种,均值


滤波,中值滤波,最大最小值滤波,关于什么是卷积以及理解卷积在图像处理中作用参见这


里–http://blog.csdn.net/jia20003/article/details/7038938



均值滤波:


均值滤波,是图像处理中最常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高


频信号将会去掉,因此可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均


值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。采样Kernel数


据通常是3X3的矩阵,如下表示:

0_13301798916bud.png


从左到右从上到下计算图像中的每个像素,最终得到处理后的图像。均值滤波可以加上两个


参数,即迭代次数,Kernel数据大小。一个相同的Kernel,但是多次迭代就会效果越来越好。


同样,迭代次数相同,Kernel矩阵越大,均值滤波的效果就越明显。



中值滤波


中值滤波也是消除图像噪声最常见的手段之一,特别是消除椒盐噪声,中值滤波的效果要比


均值滤波更好。中值滤波是跟均值滤波唯一不同是,不是用均值来替换中心每个像素,而是


将周围像素和中心像素排序以后,取中值,一个3X3大小的中值滤波如下:

0_13301799280L9y.gif


最大最小值滤波


最大最小值滤波是一种比较保守的图像处理手段,与中值滤波类似,首先要排序周围像素和


中心像素值,然后将中心像素值与最小和最大像素值比较,如果比最小值小,则替换中心像


素为最小值,如果中心像素比最大值大,则替换中心像素为最大值。一个Kernel矩阵为3X3的最大最小值滤波如下:

0_1330179955mtNy.png


原图如下:


0_13301800687gGZ.png


分别实现中值和均值滤波以后效果如下:

0_13301806325t5T.png


代码就不解释了,原理已经解释得很清楚了,全部算法源代码都是基于Java


特别说明一点的是,均值滤波对于高斯噪声的效果比较好,中值滤波对于椒盐噪声的效果比较好


想必大家从上面效果比较中也可以看到一点端倪。因为我选择的噪声图片是椒盐噪声的,哈哈



自己读吧,不解释了,有问题的可以问,源代码如下:

package com.process.blur.study;
 
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
 
 
public class SmoothFilter extends AbstractBufferedImageOp {
  public final static int MEAN_FILTER_TYPE = 1;
  public final static int MEADIAN_FILTER_TYPE = 2;
  public final static int MIN_MAX_FILTER_TYPE = 4;
  
  private int repeats = 3; // default 1
  private int kernel_size = 3; // default 3
  private int type = 1; // default mean type
  
  public int getRepeat() {
    return repeats;
  }
  
  public void setRepeat(int repeat) {
    this.repeats = repeat;
  }
  
  public int getKernelSize() {
    return kernel_size;
  }
  
  public void setKernelSize(int kernelSize) {
    this.kernel_size = kernelSize;
  }
  
  public int getType() {
    return type;
  }
  
  public void setType(int type) {
    this.type = type;
  }
 
  @Override
  public BufferedImage filter(BufferedImage src, BufferedImage dest) {
        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 );
        
        // pick up one filter from here!!!
        if(this.type == MEAN_FILTER_TYPE) 
        {
          for(int i=0; i<repeats; i++) {
            performMeanFilter(width, height, inPixels, outPixels);
            System.arraycopy(outPixels, 0, inPixels, 0, inPixels.length);
          }
        } 
        else if(this.type == MEADIAN_FILTER_TYPE) 
        {
          performMedianFilter(width, height, inPixels, outPixels);
        } 
        else if(this.type == MIN_MAX_FILTER_TYPE) 
        {
          performMinMaxFilter(width, height, inPixels, outPixels);
        }
        
        // return result
        setRGB( dest, 0, 0, width, height, outPixels );
    return dest;
  }
  
  /**
   *  <p> perform convolution filter </p>
   * 
   * @param width
   * @param height
   * @param inPixels
   * @param outPixels
   */
  public void performMeanFilter(int width, int height, int[] inPixels, int[] outPixels) {
 
    int rows2 = kernel_size/2;
    int cols2 = kernel_size/2;
    int index = 0;
    int index2 = 0;
    float total = kernel_size * kernel_size;
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        float r = 0, g = 0, b = 0, a = 0;
        for (int row = -rows2; row <= rows2; row++) {
          int rowoffset = y + row;
          if(rowoffset < 0 || rowoffset >=height) {
            rowoffset = y;
          }
          //System.out.println("rowoffset == " + rowoffset);
          for(int col = -cols2; col <= cols2; col++) {
            int coloffset = col + x;
            if(coloffset < 0 || coloffset >= width) {
              coloffset = x;
            }
            index2 = rowoffset * width + coloffset;
            int rgb = inPixels[index2];
            a += ((rgb >> 24) & 0xff);
            r += ((rgb >> 16) & 0xff);
            g += ((rgb >> 8) & 0xff);
            b += (rgb & 0xff);
          }
        }
        int ia = 0xff;
        int ir = clamp((int)(r/total));
        int ig = clamp((int)(g/total));
        int ib = clamp((int)(b/total));
        outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
      }
    }
  }
  /**
   *  <p> perform median filter </p>
   * 
   * @param width
   * @param height
   * @param src
   * @param inPixels
   * @param outPixels
   */
  public void performMedianFilter(int width, int height, int[] inPixels, int[] outPixels) {
 
    int rows2 = kernel_size/2;
    int cols2 = kernel_size/2;
    int index = 0;
    int index2 = 0;
    float total = kernel_size * kernel_size;
    int[] matrix = new int[(int)total];
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        int count = 0;
        for (int row = -rows2; row <= rows2; row++) {
          int rowoffset = y + row;
          if(rowoffset < 0 || rowoffset >=height) {
            rowoffset = y;
          }
 
          for(int col = -cols2; col <= cols2; col++) {
            int coloffset = col + x;
            if(coloffset < 0 || coloffset >= width) {
              coloffset = x;
            }
            index2 = rowoffset * width + coloffset;
            int rgb = inPixels[index2];
            matrix[count] = rgb;
            count++; 
          }
        }
        Arrays.sort(matrix);
        
        int ia = 0xff;
        int ir = ((matrix[count/2] >> 16) & 0xff);
        int ig = ((matrix[count/2] >> 8) & 0xff);
        int ib = (matrix[count/2] & 0xff);
        outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
      }
    }
  }
  
  /**
   * <p> perform min/max pixel filter </p>
   * 
   * @param width
   * @param height
   * @param src
   * @param inPixels
   * @param outPixels
   */
  public void performMinMaxFilter(int width, int height, int[] inPixels, int[] outPixels) {
    int rows2 = kernel_size/2;
    int cols2 = kernel_size/2;
    int index = 0;
    int index2 = 0;
    float total = kernel_size * kernel_size;
    int[] matrix = new int[(int)total];
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        int count = 0;
        for (int row = -rows2; row <= rows2; row++) {
          int rowoffset = y + row;
          if(rowoffset < 0 || rowoffset >=height) {
            rowoffset = y;
          }
 
          for(int col = -cols2; col <= cols2; col++) {
            int coloffset = col + x;
            if(coloffset < 0 || coloffset >= width) {
              coloffset = x;
            }
            index2 = rowoffset * width + coloffset;
            int rgb = inPixels[index2];
            matrix[count] = rgb;
            count++; 
          }
        }
        int ia = 0xff;
        int oldPixel = matrix[count/2];
        int targetRGB = findNewPixel(matrix, oldPixel);
        int ir = ((targetRGB >> 16) & 0xff);
        int ig = ((targetRGB >> 8) & 0xff);
        int ib = (targetRGB & 0xff);
        outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
      }
    }
  }
  
  private int findNewPixel(int[] matrix, int oldPixel) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    for(int i=0; i<matrix.length; i++) {
      if(matrix[i] == oldPixel)
        continue;
      list.add(matrix[i]);
    }
    int[] filterData = new int[list.size()];
    int index = 0;
    for(Integer rgb : list) {
      filterData[index++] = rgb;
    }
    Arrays.sort(filterData);
    
    if(filterData.length == 0)
      return oldPixel;
    return (oldPixel > filterData[0]) ? filterData[0] : (oldPixel < filterData[filterData.length -1])? filterData[filterData.length -1] : oldPixel;
  }
 
  public static int clamp(int c) {
    if (c < 0)
      return 0;
    if (c > 255)
      return 255;
    return c;
  }
 
}


转载是请注明出自本博客,如果需要完全代码的留下Email

相关文章
|
25天前
|
算法 计算机视觉
图像处理之应用卷积– 轧花与边缘检测
图像处理之应用卷积– 轧花与边缘检测
18 1
|
25天前
|
Java API 计算机视觉
图像处理之添加高斯与泊松噪声
图像处理之添加高斯与泊松噪声
13 1
|
25天前
|
Java 数据处理 计算机视觉
图像处理之理解卷积
图像处理之理解卷积
17 0
|
24天前
|
机器学习/深度学习 算法 BI
图像处理之HOG特征提取
图像处理之HOG特征提取
20 0
|
24天前
|
算法 计算机视觉
图像处理之Lanczos采样放缩算法
图像处理之Lanczos采样放缩算法
13 0
|
10月前
|
机器学习/深度学习 传感器 算法
【视频去噪】基于全变异正则化最小二乘反卷积是最标准的图像处理、视频去噪研究(Matlab代码实现)
【视频去噪】基于全变异正则化最小二乘反卷积是最标准的图像处理、视频去噪研究(Matlab代码实现)
|
11月前
|
机器学习/深度学习 算法 BI
图像处理HOG特征提取
简要介绍hog特征提取的原理和python代码实现。
|
11月前
|
编解码 算法 Java
基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)
基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)
|
12月前
|
算法 计算机视觉
【信号处理】基于遗传算法的噪声图像的边缘检测(Matlab代码实现)
【信号处理】基于遗传算法的噪声图像的边缘检测(Matlab代码实现)
101 0
|
机器学习/深度学习 计算机视觉
卷积及其图像处理的运用
卷积及其图像处理的运用
108 0