0

我正在做一个关于中值滤波器的程序。我想要完成的只是获取一个像素值,找到它的相邻像素,并将它们存储在一个数组中,对该数组进行排序,然后取中间值(对于大小为 9 的数组,中间值是索引位置 4)。并将该值替换为与所考虑的像素完全相同的坐标。

如果我删除其内容并仅打印i,j,x,y. 在我添加我做的语句的那一刻,我neighborhoodVal.add(imageRaster.getSample(x, y, 0));得到了一个java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!错误。

根据我的观察,我发现当值j变为1i变为值264,这很奇怪,因为我只循环图像内的所有像素,外部两个循环(i 和 j)循环除边缘之外的所有像素的图像。内部循环 ( x& ) 循环遍历第 th 个像素y的所有 8 个邻居。[i][j]

我使用的图像有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;
    }
}

我正在使用这张图片:

在此处输入图像描述

怎么j变成1了?我在哪里错了?

4

1 回答 1

1

在外部循环中,您将“i”与 .getHeight() 一起使用,但在内部循环中,“x”与 .getWidth() 一起使用。所以看起来 i 和 j 的边界需要交换。这可能是因为疲倦而打错了;我可能会在下面的示例代码中自己做。

此外,由于外部循环已经忽略了边界像素,因此内部循环可能只是 "for(x = i - 1; i <= i + 1; i++" 和 "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
   }
}

也就是说,一旦你使用了约定,就坚持下去。意外交换 getWidth() 和 getHeight() 边界很容易,但如果你总是以 y,x,j,i 的相同顺序嵌套循环,你将更有可能在不考虑的情况下键入正确的边界.

于 2012-10-12T04:23:01.473 回答