Java中的均值和中值图像过滤

时间:2015-03-16 10:38:14

标签: java image-processing

作为一个简短的序言,我想就这样一个非常愚蠢的问题道歉。

现在,正确的问题 - 我们的任务是为我们的学习计划编写一个简单的均值/中值(两者)过滤器,该过滤器稍后将作为更高级过滤器类型的介绍和基础。

我研究了内核2D矩阵如何工作并流过图像数据矩阵(至少,我希望我理解它应该如何工作),但我遇到了代码问题。我使用以下代码过滤的每个图像显示为平面颜色,通常是左上角的第一种颜色。我确定错误可能很小,但我似乎无法找到它。

如果你们可以看看,我将不胜感激。

public void medianFilter(){
        System.out.println("Initializing 2nd image.");
        initializeAltImage(); // <-- Preps a blank image the same size as the original.
        System.out.println("2nd image initialized.");

        int kernelwidth = 3;
        int kernelheight = 3;

        int[] rMedian = new int [kernelwidth*kernelheight];
        int[] gMedian = new int [kernelwidth*kernelheight];
        int[] bMedian = new int [kernelwidth*kernelheight];

        int kerneliter = 0;

        // Walk the entire image but stop before you go out of bounds at the kernel boundraries.
        for (int i = 0; i<this.x-kernelwidth; i++){
            for (int j=0; j<this.y-kernelheight; j++){
                // Walk the kernel itself.
                for (int ki = i; ki<kernelwidth; ki++){
                    for(int kj = j; kj<kernelheight; kj++){
                        Color col = new Color(this.img.getRGB(ki, kj));
                        rMedian[kerneliter] = col.getRed();
                        gMedian[kerneliter] = col.getGreen();
                        bMedian[kerneliter] = col.getBlue();
                        kerneliter++;
                    }
                }
                kerneliter = 0;
                Arrays.sort(rMedian);
                Arrays.sort(gMedian);
                Arrays.sort(bMedian);
                Color colfinal = new Color(rMedian[4], gMedian[4], bMedian[4]);
                this.altimg.setRGB(i+1, j+1, colfinal.getRGB());
            }
        }
    }

编辑#1:添加了完整的最小可编译代码以供帮助之用。

编辑#2:删除了所说的代码。答案结果证明是简单的愚蠢循环限制。

1 个答案:

答案 0 :(得分:1)

当您从源图像img.getRGB(ki, kj)获取值时,实际上您在0和kernelwidth / kernelheight之间的坐标处获取了一个像素。

为简单起见,假设为kernelwidth=kernelheight=3。当i,j >=3内部循环未执行时,中位数不会更新。

for (int i = 0; i<x-3; i++)
   for (int j=0; j<y-3; j++)
      for (int ki = i; ki<3; ki++)
         for(int kj = j; kj<3; kj++)
             //ki, kj at most between 0 and 2
             img.getRGB(ki, kj)

实际上它应该是:

 for (int i=1; i<x-1; i++)
   for (int j=1; j<y-1; j++)  {
      for (int ki = 0; ki<3; ki++)
         for(int kj = 0; kj<3; kj++)                
            img.getRGB(i+ki-1, j+kj-1) {
            ...

请注意,我不是在处理边界问题。对于边框,您可能会使用缩小的内核,或者将图像外部的像素值作为常量(例如白/黑)或与边框相同的值。