C语言实现box blur滤镜输出图像偏黑问题排查
CS50盒式模糊滤镜输出偏黑问题
问题描述
我正在完成CS50课程第4周的模糊滤镜图像处理任务,需要实现box blur(盒式模糊)算法:该算法核心逻辑为遍历每个像素,将像素的各颜色通道值替换为其邻域像素对应颜色通道值的平均值。但编写的代码运行后始终输出偏黑的图像,无法定位错误原因。
问题代码如下:
void blur(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE copy[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { copy[i][j] = image[i][j]; } } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { BYTE red_sum = 0; BYTE green_sum = 0; BYTE blue_sum = 0; float pixel_count = 0.0; // 遍历上一行邻域像素 if (i > 0) { red_sum += copy[i-1][j].rgbtRed; green_sum += copy[i-1][j].rgbtGreen; blue_sum += copy[i-1][j].rgbtBlue; pixel_count++; if (j > 0) { red_sum += copy[i-1][j-1].rgbtRed; green_sum += copy[i-1][j-1].rgbtGreen; blue_sum += copy[i-1][j-1].rgbtBlue; pixel_count++; } if (j < (width - 1)) { red_sum += copy[i-1][j+1].rgbtRed; green_sum += copy[i-1][j+1].rgbtGreen; blue_sum += copy[i-1][j+1].rgbtBlue; pixel_count++; } } // 遍历下一行邻域像素 if (i < (height - 1)) { red_sum += copy[i+1][j].rgbtRed; green_sum += copy[i+1][j].rgbtGreen; blue_sum += copy[i+1][j].rgbtBlue; pixel_count++; if (j > 0) { red_sum += copy[i+1][j-1].rgbtRed; green_sum += copy[i+1][j-1].rgbtGreen; blue_sum += copy[i+1][j-1].rgbtBlue; pixel_count++; } if (j < (width - 1)) { red_sum += copy[i+1][j+1].rgbtRed; green_sum += copy[i+1][j+1].rgbtGreen; blue_sum += copy[i+1][j+1].rgbtBlue; pixel_count++; } } // 遍历当前行邻域像素 red_sum += copy[i][j].rgbtRed; green_sum += copy[i][j].rgbtGreen; blue_sum += copy[i][j].rgbtBlue; pixel_count++; if (j > 0) { red_sum += copy[i][j-1].rgbtRed; green_sum += copy[i][j-1].rgbtGreen; blue_sum += copy[i][j-1].rgbtBlue; pixel_count++; } if (j < (width - 1)) { red_sum += copy[i][j+1].rgbtRed; green_sum += copy[i][j+1].rgbtGreen; blue_sum += copy[i][j+1].rgbtBlue; pixel_count++; } // 计算通道平均值 BYTE average_red = round(red_sum / pixel_count); BYTE average_green = round(green_sum / pixel_count); BYTE average_blue = round(blue_sum / pixel_count); image[i][j].rgbtRed = average_red; image[i][j].rgbtGreen = average_green; image[i][j].rgbtBlue = average_blue; } } return; }
问题原因
- 代码中定义的三个通道求和变量
red_sum、green_sum、blue_sum类型为BYTE,这是8位无符号整数类型,取值范围仅为0~255。盒式模糊的3x3邻域最多包含9个像素,单个通道累加的最大值可达9*255=2295,远超出BYTE的存储上限,累加过程中会发生整数溢出,高位数据被直接截断,最终得到的求和结果远小于真实值,计算出的通道平均值偏小,直接导致输出图像整体偏黑。 - 其余邻域遍历、原图备份、边界判断的逻辑均无问题。
修复方法
将三个通道求和变量的类型从BYTE修改为取值范围足够大的整数类型即可,例如使用int类型:
// 替换原代码中BYTE类型的求和变量定义 int red_sum = 0; int green_sum = 0; int blue_sum = 0; float pixel_count = 0.0;
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

