首先,在循环的每个循环中,您都需要(错误地)将结果从浮点转换为int。您的 red
, green
和 blue
应为浮动类型,只有在卷积后才施放回整数(转换回RGB):
float red=0.0f, green = 0.0f, blue = 0.0f
for(int i = x;i<x+3;i++){
for(int j = y;j<y+3;j++){
int color = a.getRGB(i,j);
red += ((color >> 16) & 0xff)*matrix[(i-x)*3+j-y];
green += ((color >> 8) & 0xff)*matrix[(i-x)*3+j-y];
blue += ((color >> 0) & 0xff)*matrix[(i-x)*3+j-y];
}
}
return (a.getRGB(x, y)&0xFF000000) | (((int)red) << 16) | (((int)green) << 8) | ((int)blue);
结果中颜色的出血是引起的,因为您的系数在 matrix
错了:
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f = 1.8452741
模糊卷积矩阵中系数的总和应为1.0。当您将此矩阵应用于图像时,您可能会得到超过255的颜色。当这种情况发生时,通道“流血”到下一个通道(蓝色到绿色等)。使用此矩阵完全绿色的图像将导致:
green = 255 * 1.8452741 ~= 471 = 0x01D7; rgb = 0xFF01D700;
这是一个不太强烈的绿色,带有红色的味道。
您可以通过将系数除以 1.8452741
, ,但是您要确保:
(int)(255.0f * (sum of coefficients)) = 255
如果不是,您需要添加一个将通道大小限制为255的检查,并且不要让它们缠绕。例如:
if (red > 255.0f)
red = 255.0f;
关于效率/优化:
速度的差异可能是通过这种不必要的铸造和调用数学来解释的。我对BufferedImage和Raster不太熟悉,无法为您提供访问基础图像缓冲区的最有效方法。