You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:48:18