// MedianFilter.java import java.applet.Applet; import java.awt.*; import java.io.*; import java.awt.event.*; import java.awt.image.*; import java.lang.Math.*; /*<applet code="MedianFilter.class" width="967" height="747"> <param name="img_" value="aiboakira.jpg"> </applet>*/ public class MedianFilter extends Applet { Image img_; Image img; MediaTracker mt; int w=410,h=307; int[][] color; public void init(){ mt=new MediaTracker(this); setBackground(Color.white); img_ = getImage(getDocumentBase(), getParameter("img_")); mt.addImage(img_,0); try { mt.waitForID(0); } catch(InterruptedException e) { } w = img_.getWidth(this); h = img_.getHeight(this); color= new int[w*h][3]; getColor(img_, color, w, h); img=img_; Button btn_med = new Button("メディアンフィルタ"); Button btn_noise = new Button("ノイズ付加"); Button btn_reset = new Button("リセット"); this.add(btn_med); this.add(btn_noise); this.add(btn_reset); // メディアンフィルタボタン設定 btn_med.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { img_ = median(color, w, h); repaint(); getColor(img_, color, w, h); } }); // ノイズ付加ボタン設定 btn_noise.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { img_ = noise(color, w, h); repaint(); getColor(img_, color, w, h); } }); // リセットボタン設定 btn_reset.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { img_ = reset(); repaint(); getColor(img_, color, w, h); } }); } public void paint(Graphics g) { g.drawImage(img_,0,0,this); } // メディアンフィルタ処理 // 色情報(0~255)をしまう配列 color[h*w][3] public Image median(int color[][], int w, // 画像の幅 int h // 画像の高さ ){ int[][] sort = new int[9][9]; int[] mat = new int[9]; // 3X3フィルタの座標 // mat[0] mat[1] mat[2] // mat[3] mat[4] mat[5] // mat[6] mat[7] mat[8] int[][] color2 = new int[w*h][3]; int[] gray = new int[h*w]; for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ gray[j+i*w]=0; for(int k=0;k<3;k++){ gray[j+i*w]+=color[j+i*w][k]; } } } for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ int i1,i2,i3; int j1,j2,j3; if(i-1<0) i1=i; else i1=i-1; if(j-1<0) j1=j; else j1=j-1; i2=i; j2=j; if(i+1>h-1) i3=i; else i3=i+1; if(j+1>2-1) j3=j; else j3=j+1; mat[0]=j1+i1*w; mat[1]=j2+i1*w; mat[2]=j3+i1*w; mat[3]=j1+i2*w; mat[4]=j2+i2*w; mat[5]=j3+i2*w; mat[6]=j1+i3*w; mat[7]=j2+i3*w; mat[8]=j3+i3*w; sort[0][0]=mat[0]; for(int l=1;l<9;l++){ for(int m=0;m<l;m++){ if(gray[sort[l-1][m]] < gray[mat[l]]){ sort[l][m]=sort[l-1][m]; } else{ sort[l][m]=mat[l]; for(int n=m+1;n<=l;n++){ sort[l][n]=sort[l-1][n-1]; } break; } sort[l][l]=mat[l]; } } for(int k=0;k<3;k++){ color2[j+i*w][k]= color[sort[8][4]][k]; } } } return makeImage(color2, w , h); } // リセット public Image reset() { return img; } // ノイズ付加処理 // 色情報(0~255)をしまう配列 color[h*w][3] public Image noise(int color[][], int w, // 画像の幅 int h // 画像の高さ ){ double rand; int[] pix2= new int[w*h]; for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ for(int k=0;k<3;k++){ rand = Math.random(); if(rand<0.05){ rand = Math.random(); color[j+i*w][k]= (int)(rand*255); } } } } return makeImage(color, w , h); } // 色情報から画像をつくる。 // 色情報(0~255)をしまう配列 color[h*w][3] Image makeImage(int color[][], int w, // 画像の幅 int h // 画像の高さ ){ int[] pix = new int[w*h]; for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ pix[j+i*w]=(255<<24)| (color[j+i*w][0]<<16)| (color[j+i*w][1]<<8)| (color[j+i*w][2]); } } return createImage(new MemoryImageSource(w,h,pix,0,w)); } // 画像から色情報を取り出す。 void getColor(Image img_, // 元の画像 int color[][], // 色情報(0~255)をしまう配列 color[h*w][3] int w, // 画像の幅 int h // 画像の高さ ) { int[] pix= new int[w*h]; PixelGrabber pg= new PixelGrabber(img_,0,0,w,h,pix,0,w); try{pg.grabPixels();}catch(Exception e){} for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ color[j+i*w][0]= (pix[j+i*w] & 0xff0000)>>16; // 赤色 color[j+i*w][1]= (pix[j+i*w] & 0xff00)>>8; // 緑色 color[j+i*w][2]= pix[j+i*w] & 0xff; // 青色 } } } }