均值滤波java_均值滤波,中值滤波,最大最小值滤波
http://blog.csdn.net/fastbox/article/details/7984721
討論如何使用卷積作為數學工具來處理圖像,實現圖像的濾波,其方法包含以下幾種,均值
濾波,中值濾波,最大最小值濾波,關于什么是卷積以及理解卷積在圖像處理中作用參見這
均值濾波:
均值濾波,是圖像處理中最常用的手段,從頻率域觀點來看均值濾波是一種低通濾波器,高
頻信號將會去掉,因此可以幫助消除圖像尖銳噪聲,實現圖像平滑,模糊等功能。理想的均
值濾波是用每個像素和它周圍像素計算出來的平均值替換圖像中每個像素。采樣Kernel數
據通常是3X3的矩陣,如下表示:
從左到右從上到下計算圖像中的每個像素,最終得到處理后的圖像。均值濾波可以加上兩個
參數,即迭代次數,Kernel數據大小。一個相同的Kernel,但是多次迭代就會效果越來越好。
同樣,迭代次數相同,Kernel矩陣越大,均值濾波的效果就越明顯。
中值濾波
中值濾波也是消除圖像噪聲最常見的手段之一,特別是消除椒鹽噪聲,中值濾波的效果要比
均值濾波更好。中值濾波是跟均值濾波唯一不同是,不是用均值來替換中心每個像素,而是
將周圍像素和中心像素排序以后,取中值,一個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;?//?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
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;
}
/**
*??
?perform?convolution?filter?
*
*?@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?
for?(int?x?=?0;?x?
float?r?=?0,?g?=?0,?b?=?0,?a?=?0;
for?(int?row?=?-rows2;?row?<=?rows2;?row++)?{
int?rowoffset?=?y?+?row;
if(rowoffset?=height)?{
rowoffset?=?y;
}
//System.out.println("rowoffset?==?"?+?rowoffset);
for(int?col?=?-cols2;?col?<=?cols2;?col++)?{
int?coloffset?=?col?+?x;
if(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?<
}
}
}
/**
*??
?perform?median?filter?
*
*?@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?
for?(int?x?=?0;?x?
int?count?=?0;
for?(int?row?=?-rows2;?row?<=?rows2;?row++)?{
int?rowoffset?=?y?+?row;
if(rowoffset?=height)?{
rowoffset?=?y;
}
for(int?col?=?-cols2;?col?<=?cols2;?col++)?{
int?coloffset?=?col?+?x;
if(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?<
}
}
}
/**
*?
?perform?min/max?pixel?filter?
*
*?@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?
for?(int?x?=?0;?x?
int?count?=?0;
for?(int?row?=?-rows2;?row?<=?rows2;?row++)?{
int?rowoffset?=?y?+?row;
if(rowoffset?=height)?{
rowoffset?=?y;
}
for(int?col?=?-cols2;?col?<=?cols2;?col++)?{
int?coloffset?=?col?+?x;
if(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?<
}
}
}
private?int?findNewPixel(int[]?matrix,?int?oldPixel)?{
ArrayList?list?=?new?ArrayList();
for(int?i=0;?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?
}
public?static?int?clamp(int?c)?{
if?(c?
return?0;
if?(c?>?255)
return?255;
return?c;
}
}
總結
以上是生活随笔為你收集整理的均值滤波java_均值滤波,中值滤波,最大最小值滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql适配器_MySQL适配器PyM
- 下一篇: java mvc 断点续传_用Sprin