均值濾波:java
均值濾波,是圖像處理中最經常使用的手段,從頻率域觀點來看均值濾波是一種低通濾波器,高算法
頻信號將會去掉,所以能夠幫助消除圖像尖銳噪聲,實現圖像平滑,模糊等功能。理想的均ide
值濾波是用每一個像素和它周圍像素計算出來的平均值替換圖像中每一個像素。採樣Kernel數this
據一般是3X3的矩陣,以下表示:url

從左到右從上到下計算圖像中的每一個像素,最終獲得處理後的圖像。均值濾波能夠加上兩個spa
參數,即迭代次數,Kernel數據大小。一個相同的Kernel,可是屢次迭代就會效果愈來愈好。.net
一樣,迭代次數相同,Kernel矩陣越大,均值濾波的效果就越明顯。orm
中值濾波blog
中值濾波也是消除圖像噪聲最多見的手段之一,特別是消除椒鹽噪聲,中值濾波的效果要比排序
均值濾波更好。中值濾波是跟均值濾波惟一不一樣是,不是用均值來替換中心每一個像素,而是
將周圍像素和中心像素排序之後,取中值,一個3X3大小的中值濾波以下:

最大最小值濾波
最大最小值濾波是一種比較保守的圖像處理手段,與中值濾波相似,首先要排序周圍像素和
中心像素值,而後將中心像素值與最小和最大像素值比較,若是比最小值小,則替換中心像
素爲最小值,若是中心像素比最大值大,則替換中心像素爲最大值。一個Kernel矩陣爲3X3的最大最小值濾波以下:

原圖以下:

分別實現中值和均值濾波之後效果以下:

代碼就不解釋了,原理已經解釋得很清楚了,所有算法源代碼都是基於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;
- private int kernel_size = 3;
- private int type = 1;
-
- 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 );
-
-
- 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);
- }
-
-
- setRGB( dest, 0, 0, width, height, outPixels );
- return dest;
- }
-
-
-
-
-
-
-
-
-
- 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;
- }
-
- 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;
- }
- }
- }
-
-
-
-
-
-
-
-
-
- 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;
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
- 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;
- }
-
- }