均值滤波和中值滤波的内容非常基础,均值滤波相当于低通滤波,有将图像模糊化的趋势,对椒盐噪声基本无能为力。中值滤波的优点是可以很好的过滤掉椒盐噪声,缺点是易造成图像的不连续性。在下面的代码中,中值滤波主要通过冒泡算法来实现。 中值滤波的效果如下,可以看到,几乎完全去除了椒盐噪声。
代码如下: /** * 2013-1-24 */ package Filter; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.*; /** * 彩色图像的中值滤波和均值滤波 * @ClassName: MediaANDAveragefilter * @Description: 目的在于比较均值滤波和中值滤波的性能。 * <p> 说明: * <br> 1)均值滤波是求图像内部每个像素点的所有相邻(如八邻域)像素点的平均值,并将该平均值作为该像素点的值;而中值滤波 * <br> 是对图像内部每个像素点采用滑动窗口(3*3或5*5)进行邻域搜索,并按照从小到大的顺序排序,然后去中间的值(即中值) * <br> 作为该像素点的像素值。 * <br> 2)均值滤波对噪声具有拟制作用,但同时也会使图像变得模糊;而中值滤波用于消除椒盐噪声,但同时不会使边界变模糊。 * <br> 3)均值滤波对于拟制高斯噪声的效果比较好,中值滤波对于椒盐噪声的拟制效果比较好; * @author: TYLR2012 * @Version: V1.0 * @Date: 2013-1-24 下午4:24:25 */ public class MediaANDAveragefilter extends Frame{ /** * */ private static final long serialVersionUID = 1L; private BufferedImage inputImage =null; private BufferedImage dstImage =null; private int Image_Width, Image_Height; private int[] pixels; private boolean flag_load = false; private Button loadButtton; private Button meanButtton; private Button medianButtton; private Button saveButtton; private Button quitButtton; private Panel pdown; /** * 构造函数 */ public MediaANDAveragefilter(){ setTitle("彩色图像均值中值滤波"); setSize(600,600); setVisible(true); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); // 释放主界面时,中断JVM } }); // 界面布局 pdown = new Panel(); pdown.setBackground(Color.lightGray); this.add(pdown, BorderLayout.SOUTH); //定义按钮 loadButtton = new Button("装载图像"); pdown.add(loadButtton); loadButtton.addActionListener(new buttonActionListener()); meanButtton = new Button("均值滤波3*3"); pdown.add(meanButtton); meanButtton.addActionListener(new buttonActionListener()); medianButtton = new Button("中值滤波3*3"); pdown.add(medianButtton); medianButtton.addActionListener(new buttonActionListener()); saveButtton = new Button("保存"); pdown.add(saveButtton); saveButtton.addActionListener(new buttonActionListener()); quitButtton = new Button("退出"); pdown.add(quitButtton); quitButtton.addActionListener(new buttonActionListener()); } public class buttonActionListener implements ActionListener{ public void actionPerformed(ActionEvent et) { if (et.getSource() == loadButtton) { File inputFile = new File("./ImageProcessingAlogrithm/Filter/源图像.jpg"); try { inputImage = ImageIO.read(inputFile); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } dstImage = inputImage; Image_Width = inputImage.getWidth(); Image_Height = inputImage.getHeight(); pixels = new int[Image_Width*Image_Height]; flag_load = true; repaint(); } //均值滤波 响应事件 if (et.getSource() == meanButtton ) { if(flag_load){ try{ PixelGrabber pg = new PixelGrabber(inputImage,0,0,Image_Width,Image_Height,pixels,0,Image_Width); pg.grabPixels(); }catch(InterruptedException e3){ e3.printStackTrace(); } BufferedImage grayImage = new BufferedImage(Image_Width, Image_Height, BufferedImage.TYPE_INT_RGB); ColorModel cm = ColorModel.getRGBdefault(); for(int i=1;i<Image_Height-1;i++){ for(int j=1;j<Image_Width-1;j++){ int sum_Red = 0, sum_Green = 0,sum_Blue = 0; int mean_Red = 0,mean_Green = 0,mean_Blue = 0; for(int k=-1;k<2;k++){ for(int l=-1;l<2;l++){ sum_Red += cm.getRed(pixels[(i+k)*Image_Width+j+l]); sum_Green += cm.getGreen(pixels[(i+k)*Image_Width+j+l]); sum_Blue += cm.getBlue(pixels[(i+k)*Image_Width+j+l]); } } mean_Red = sum_Red/9; mean_Green = sum_Green/8; mean_Blue = sum_Blue/9; int rgbValue = 255<<24|mean_Red<<16|mean_Green<<8|mean_Blue; grayImage.setRGB(j, i, rgbValue); } } dstImage = grayImage; repaint(); }else{ JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", JOptionPane.WARNING_MESSAGE); } } // 中值滤波响应事件 if (et.getSource() == medianButtton ) { if(flag_load){ try{ PixelGrabber pg = new PixelGrabber(inputImage,0,0,Image_Width,Image_Height,pixels,0,Image_Width); pg.grabPixels(); }catch(InterruptedException e3){ e3.printStackTrace(); } BufferedImage grayImage = new BufferedImage(Image_Width, Image_Height, BufferedImage.TYPE_INT_RGB); ColorModel cm = ColorModel.getRGBdefault(); int[] tpRed = new int[9]; int[] tpGreen = new int[9]; int[] tpBlue = new int[9]; int media_Red,media_Green,media_Blue; for(int i=1;i<Image_Height-1;i++){ for(int j=1;j<Image_Width-1;j++){ int m = 0; for(int k=-1;k<2;k++){ for(int l=-1;l<2;l++){ tpRed[m] = cm.getRed(pixels[(i+k)*Image_Width+j+l]); tpGreen[m] = cm.getGreen(pixels[(i+k)*Image_Width+j+l]); tpBlue[m] = cm.getBlue(pixels[(i+k)*Image_Width+j+l]); m++; } } // 对像素点(i*Image_Width+j)八邻域中的所有像素点的redValue排序并求出中值; for(int rj=0; rj<8; rj++){ for(int ri=0; ri<8-rj; ri++){ if(tpRed[ri]>tpRed[ri+1]){ int Red_Temp = tpRed[ri]; tpRed[ri] = tpRed[ri+1]; tpRed[ri+1] = Red_Temp; } } } media_Red = tpRed[4]; // 对像素点(i*Image_Width+j)八邻域中的所有像素点的GreenValue 排序并求出中值; for(int rj=0; rj<8; rj++){ for(int ri=0; ri<8-rj; ri++){ if(tpGreen[ri]>tpGreen[ri+1]){ int Green_Temp = tpGreen[ri]; tpGreen[ri] = tpGreen[ri+1]; tpGreen[ri+1] = Green_Temp; } } } media_Green= tpGreen[4]; // 对像素点(i*Image_Width+j)八邻域中的所有像素点的BlueValue排序并求出中值; for(int rj=0; rj<8; rj++){ for(int ri=0; ri<8-rj; ri++){ if(tpBlue[ri]>tpBlue[ri+1]){ int Blue_Temp = tpBlue[ri]; tpBlue[ri] = tpBlue[ri+1]; tpBlue[ri+1] = Blue_Temp; } } } media_Blue = tpBlue[4]; int rgb = 255<<24|media_Red<<16|media_Green<<8|media_Blue; grayImage.setRGB(j, i, rgb); } } dstImage = grayImage; repaint(); }else{ JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", JOptionPane.WARNING_MESSAGE); } } //保存文件响应事件 if (et.getSource() == saveButtton) { if(flag_load){ JFileChooser fileChooser = new JFileChooser(); //实例化文件选择器 int saveValue=fileChooser.showSaveDialog(null); if(saveValue==JFileChooser.APPROVE_OPTION){ File file=fileChooser.getSelectedFile(); //获取保存路径; String format = "jpg"; try{ ImageIO.write(dstImage, format,file ); }catch(IOException ex){ ex.printStackTrace(); } } }else{ JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", JOptionPane.WARNING_MESSAGE); } } //退出响应事件 if (et.getSource() == quitButtton) { System.exit(0); } } } //绘图函数 public void paint(Graphics g){ if(flag_load){ g.drawImage(dstImage,50,50,this); }else{} } public static void main(String[] args) { MediaANDAveragefilter ti = new MediaANDAveragefilter(); } } 原文来自:http://hello-wangfeng./blog/1719909 |
|