作为一个简短的序言,我想就这样一个非常愚蠢的问题道歉。
现在,正确的问题 - 我们的任务是为我们的学习计划编写一个简单的均值/中值(两者)过滤器,该过滤器稍后将作为更高级过滤器类型的介绍和基础。
我研究了内核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:删除了所说的代码。答案结果证明是简单的愚蠢循环限制。
答案 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) {
...
请注意,我不是在处理边界问题。对于边框,您可能会使用缩小的内核,或者将图像外部的像素值作为常量(例如白/黑)或与边框相同的值。