【发布时间】:2009-06-21 20:40:04
【问题描述】:
我正在尝试在 Java 中对图像执行中值过滤,但速度非常慢。首先,如果你们中有人知道我可以使用的独立实现,如果您能告诉我,那就太好了。我正在 Android 上实现,试图复制 JAI 的一小部分。
在我的方法中,我获取每个像素,使用
提取 R、G 和 B 值r = pixel >> 16 & 0xFF
或类似的,找到内核的中值并以
结束pixel = a | r <<16 | g << 8 | b
有什么方法可以更快地从 int 中获取字节?
亲切的问候,
加文
编辑:根据要求帮助诊断我的低性能的完整代码
对于实际的源文件,请转到here,在那里可以找到我的 medianFilter 实现。
width 和 height 变量用于 dest 的大小,可用作类成员变量。像素被线性化成一维数组。
private void medianFilterSquare(int[] source, int[] dest, int rWidth,
int rHeight, int radius) {
// Source has been reflected into a border of size radius
// This makes it radius * 2 pixels wider and taller than the dest
int r,g,b;
int destOffset, rOffset, kOffset;
// The first offset into the source to calculate a median for
// This corresponds to the first pixel in dest
int rFirst = radius + (rWidth*radius);
// We use a square kernel with the radius passed
int neighbours = (radius+radius+1)*(radius+radius+1);
int index;
// Arrays to accumulate the values for median calculation
int[] rs = new int[neighbours];
int[] gs = new int[neighbours];
int[] bs = new int[neighbours];
// Declaring outside the loop helps speed? I'm sure this is done for me
// by the compiler
int pixel;
// Iterate over the destination pixels
for(int x = 0; x < height; x++){
for(int y = 0; y < width; y++){
// Offset into destination
destOffset = x + (y * width);
// Offset into source with border size radius
rOffset = destOffset + rFirst + (y * (radius *2));
index = 0;
// Iterate over kernel
for(int xk = -radius; xk < radius ; xk ++){
for(int yk = -radius; yk < radius ; yk ++){
kOffset = rOffset + (xk + (rWidth*yk));
pixel = source[kOffset];
// Color.red is equivalent to (pixel>>16) & 0xFF
rs[index] = Color.red(pixel);
gs[index] = Color.green(pixel);
bs[index] = Color.blue(pixel);
index++;
}
}
r = medianFilter(rs);
g = medianFilter(gs);
b = medianFilter(bs);
dest[destOffset] = Color.rgb(r, g, b);
}
}
}
【问题讨论】:
-
位移和逻辑运算应该比较快。你确定不是这两行之间的代码是瓶颈吗?
-
你如何“找到内核的中值”。我们可以看代码吗?
-
事实上,你甚至没有向我们展示你是如何得到 g、b 或 a 的。为什么不发布所有代码?
-
当然,我试图让您免于头痛,非常感谢您的帮助,我在试图让它在合理的时间内运行时有点困难!要遵循的代码
-
感谢您的代码。您真正的问题是您一遍又一遍地对相同的像素执行相同的操作。请参阅下面的答案。
标签: java algorithm image-processing