Java使用高斯滤波去除图像高斯噪声时图像变暗问题求助
高斯滤波代码错误解答
问题表现
你实现的高斯滤波代码运行后没有去噪效果,且图像整体变暗,对比如下:
- 原图效果:

- 处理后效果:

核心错误原因
- 未执行高斯滤波的核心卷积计算:你虽然生成了3x3的高斯权重模板,但仅对当前中心像素乘以模板中心权重
w[1][1],完全没有累加邻域内8个相邻像素的加权值,完全没有实现平滑去噪的效果。 - 亮度降低的直接原因:归一化后的高斯模板所有权重总和为1,单独的中心权重
w[1][1]数值必然小于1,像素值直接乘以这个小于1的系数后,整体亮度自然会成比例下降。 - 边界未做兼容处理:当前代码直接跳过了图像最外侧1圈像素,输出图像的边缘会存在默认的黑色空值区域。
修正后的代码
import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class Main { public static void main(String[] args) { File file = new File("src/main/resources/123.jpg"); BufferedImage source; try { source = ImageIO.read(file); int width = source.getWidth(); int height = source.getHeight(); BufferedImage result = new BufferedImage(width, height, source.getType()); int n = 3; double[][] w = new double[n][n]; genGaussTemplate(w, n, 0.5); int halfSize = n / 2; // 遍历每个像素 for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { double redSum = 0, greenSum = 0, blueSum = 0; // 3x3邻域卷积计算 for (int k = -halfSize; k <= halfSize; k++) { for (int l = -halfSize; l <= halfSize; l++) { // 边界处理:超出范围的像素用当前中心像素代替 int x = Math.max(0, Math.min(width - 1, i + k)); int y = Math.max(0, Math.min(height - 1, j + l)); Color color = new Color(source.getRGB(x, y)); // 加权累加各通道值 redSum += color.getRed() * w[k + halfSize][l + halfSize]; greenSum += color.getGreen() * w[k + halfSize][l + halfSize]; blueSum += color.getBlue() * w[k + halfSize][l + halfSize]; } } // 数值限制在0-255区间,避免溢出 int red = Math.max(0, Math.min(255, (int) Math.round(redSum))); int green = Math.max(0, Math.min(255, (int) Math.round(greenSum))); int blue = Math.max(0, Math.min(255, (int) Math.round(blueSum))); Color newColor = new Color(red, green, blue); result.setRGB(i, j, newColor.getRGB()); } } // 保存结果 File output = new File("src/main/resources/output/321.jpg"); ImageIO.write(result, "jpg", output); } catch (IOException e) { System.out.println("发生错误 - " + e.getMessage()); } } static void genGaussTemplate(double[][] window, int ksize, double sigma) { final double pi = 3.1415926; int center = ksize / 2; double x2, y2; double sum = 0; for (int i = 0; i < ksize; i++) { x2 = Math.pow(i - center, 2); for (int j = 0; j < ksize; j++) { y2 = Math.pow(j - center, 2); double g = Math.exp(-(x2 + y2) / (2 * sigma * sigma)); g /= 2 * pi * sigma * sigma; sum += g; window[i][j] =g; } } // 归一化保证权重和为1,避免亮度变化 for (int i = 0; i < ksize; i++) { for (int j = 0; j < ksize; j++) { window[i][j] /=sum; } } } }
补充说明
高斯滤波的核心逻辑是用邻域内所有像素的加权平均值替代原像素值,权重符合高斯分布,距离中心越近的像素权重越高,以此实现平滑噪声的同时尽可能保留图像边缘信息。
内容的提问来源于stack exchange,提问作者rulila52
相关产品推荐
相关产品推荐

