2012-10-11 54 views
0

我正在執行中值濾波器的程序。所有我試圖完成的是取一個像素值,找到它的相鄰像素,並將它們存儲在一個數組中,對該數組進行排序,並取中間值(對於大小爲9的中間值數組爲索引位置4)。並在與考慮中的像素完全相同的座標處代替該值。在WritableRaster中設置值時座標不在邊界

如果我刪除它的內容並只輸出i,j,x,y的值,則循環正常工作。當我添加聲明,其中我做neighborhoodVal.add(imageRaster.getSample(x, y, 0));我得到一個java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!錯誤。

從我觀察到的,我發現的j值變爲1時的i值變爲264,其奇怪,因爲我循環僅在圖像內的所有像素中,外兩個環路(i和j)循環通過除了那些在圖像邊緣的像素之外的所有像素。和內環(x & y)循環遍歷[i][j]個像素的所有8個鄰居。

我使用的圖像有width = 265height=269。 的代碼如下:

public class MedianFilter { 


    public static void main(String[] args) throws IOException { 

     int i, j, x, y; 
     ArrayList<Integer> neighborhoodVal = new ArrayList<Integer>(); 
     ; 
     String imagePath = "images/assignment10/noisyShapes.jpg"; 
     BufferedImage inputImage = convertToGrayScale(ImageIO.read(new File(
       imagePath))); 
     WritableRaster imageRaster = inputImage.getRaster(); 
     BufferedImage filteredImage = new BufferedImage(inputImage.getWidth(), 
       inputImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY); 
     WritableRaster newWRaster = filteredImage.getRaster(); 



     for (i = 1; i < imageRaster.getHeight()-1; i++) { 
      for (j = 1; j < imageRaster.getWidth()-1; j++) { 
       for (x = Math.max(0, i - 1); x <= Math.min(i + 1,imageRaster.getWidth()); x++) { 
        for (y = Math.max(0, j - 1); y <= Math.min(j + 1,imageRaster.getHeight()); y++) { 

         System.out.println(i+","+j+"------->"+x+","+y); 

         neighborhoodVal.add(imageRaster.getSample(x, y, 0)); 
         Collections.sort(neighborhoodVal); 
        } 
       } 
       newWRaster.setSample(i, j, 0, (neighborhoodVal 
           .get((neighborhoodVal.size()/2) + 1))); 
       neighborhoodVal.clear(); 
      } 

     } 

     File f = new File("images/assignment10/medianFilterOutput.jpg"); 
     ImageIO.write(filteredImage, "JPG", f); 

    } 
    public static BufferedImage convertToGrayScale(BufferedImage givenImage) 
      throws IOException { 
     // TODO Auto-generated method stub 
     BufferedImage image = new BufferedImage(givenImage.getWidth(), 
       givenImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY); 
     Graphics grp = image.getGraphics(); 
     grp.drawImage(givenImage, 0, 0, null); 
     return image; 
    } 
} 

,我用這個形象:

enter image description here

如何j變成1?我在哪裏錯了?

+0

在內部循環中,您可能會使用「x <= Math.min(i + 1,imageRaster.getWidth())」而不是「... x <=」來搜索圖像的邊緣。 imageRaster.getWidth() - 1「。 – Rethunk

+0

@Rethunk我試圖這樣做,問題仍然存在 – md1hunox

+0

糟糕,那根本就不是。不過,我認爲我發現了這個問題。 – Rethunk

回答

1

在外部循環中,您將使用「i」與.getHeight(),但在內部循環中,「x」與.getWidth()一起使用。所以它看起來像我和j的界限需要交換。這可能是一個疲倦的錯字;我可以在下面的示例代碼中自己做。由於外部循環已經忽略了邊界像素,所以內部循環可以是「for(x = i-1; i < = i + 1; i ++」and「for(y = j - 1; y < = j + 1; j ++)「並且保證在範圍內

如果我可以提出一個建議:在圖像處理中,通常是逐行掃描(也就是」y「)最外層循環,然後通過X,並且還要用(X,Y)的像素座標和(i,j),其中偏移。例如:

int r = 1; //radius, in case you want to use median over a larger kernel 

for(int y = r; y < height - r; y++) 
{ 
    for (int x = r; x < width - r; x++) 
    { 
     for(int j = y - r; j <= y + r; j++) 
     { 
     for(i = x - r; i <= x + r; i++) 
     { 
      //get all neighborhood values 
     } 
     }  

     //find median 
    } 
} 

這就是說,一旦你使用了一個公約,堅持下去意外sw應用getWidth()和getHeight()邊界很容易,但是如果你總是以y,x,j,i的順序嵌套循環,那麼你會更有可能在不考慮它的情況下輸入正確的邊界。