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

CS50作业:C语言实现图像模糊滤镜遇问题求协助

CS50图像模糊滤镜代码修复

正在完成CS50的图像模糊滤镜作业,要求遍历图像二维数组的每个像素,找到其3x3范围内的相邻像素,取RGB平均值替换原像素值,但编写的C代码无法正常运行,对教程提到的"像素相对位置计算"存在困惑,附上原始代码并求助:

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    int red = 0;
    int green = 0;
    int blue = 0;
    int counter_pixel = 0;
    //I would assume that we would need to tell the computer to free up space for the new imafe with malloc()
    RGBTRIPLE temporary[height][width];
    for (int i = 0; i < height; i++)
    {
        // go through every column
        for (int j = 0; j < width; j++)
        {
            temporary[i][j] = image[i][j];
        }
    }
    // go through every row
    for (int i = 0; i < height; i++)
    {
        // go through every column
        for (int j = 0; j < width; j++)
        {
            //checking if the pixel is inside the image
            red = green = blue = 0;
            if (i < 0 || j < 0 || i > height +1 || j > width + 1)
            {
                image[i + 1][j].rgbtRed = temporary[i + 1][j].rgbtRed;
                image[i - 1][j].rgbtRed = temporary[i - 1][j].rgbtRed;
                image[i][j + 1].rgbtRed = temporary[i][j + 1].rgbtRed;
                image[i][j - 1].rgbtRed = temporary[i][j - 1].rgbtRed;

                image[i + 1][j].rgbtGreen = temporary[i + 1][j].rgbtGreen;
                image[i - 1][j].rgbtGreen = temporary[i - 1][j].rgbtGreen;
                image[i][j + 1].rgbtGreen = temporary[i][j + 1].rgbtGreen;
                image[i][j - 1].rgbtGreen = temporary[i][j - 1].rgbtGreen;

                image[i + 1][j].rgbtBlue = temporary[i + 1][j].rgbtBlue;
                image[i - 1][j].rgbtBlue = temporary[i - 1][j].rgbtBlue;
                image[i][j + 1].rgbtBlue = temporary[i][j + 1].rgbtBlue;
                image[i][j - 1].rgbtBlue = temporary[i][j - 1].rgbtBlue;

                counter_pixel++;

                red = round(((temporary[i + 1][j].rgbtRed + temporary[i - 1][j].rgbtRed + temporary[i][j + 1].rgbtRed + temporary[i][j -1].rgbtRed) / counter_pixel));
                green = round(((temporary[i + 1][j].rgbtGreen + temporary[i - 1][j].rgbtGreen + temporary[i][j + 1].rgbtGreen + temporary[i][j -1].rgbtGreen) / counter_pixel));
                blue = round(((temporary[i + 1][j].rgbtBlue + temporary[i - 1][j].rgbtBlue + temporary[i][j + 1].rgbtBlue + temporary[i][j -1].rgbtBlue) / counter_pixel));
            }
        }
    }
    return;
}

原始代码的核心问题

  • 边界判断逻辑完全错误:外层循环i从0到height-1,j从0到width-1,if (i < 0 || j < 0 || i > height +1 || j > width + 1)的条件永远不会触发,且判断范围的阈值错误(正确应为x >= height或y >= width)。
  • 模糊逻辑偏离要求:代码中没有计算相邻像素的RGB平均值,反而错误地将临时数组的像素直接赋值给原图像,完全不符合模糊滤镜的逻辑。
  • 相邻像素范围不全:只考虑了上下左右4个方向,忽略了对角线的相邻像素,正确的模糊应覆盖当前像素周围3x3的所有有效像素(包括自身)。
  • 变量初始化与累加错误:counter_pixel未在每次计算单个像素时重置,RGB值的累加逻辑混乱,没有正确统计有效像素的数量。

修复后的代码及解释

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // 复制原始图像到临时数组,避免修改时覆盖原始数据
    RGBTRIPLE temporary[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            temporary[i][j] = image[i][j];
        }
    }

    // 遍历每个目标像素
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int red_sum = 0, green_sum = 0, blue_sum = 0;
            int valid_count = 0;

            // 遍历当前像素周围3x3的相对位置(偏移量从-1到1)
            for (int di = -1; di <= 1; di++)
            {
                for (int dj = -1; dj <= 1; dj++)
                {
                    // 计算偏移后的绝对坐标
                    int x = i + di;
                    int y = j + dj;

                    // 检查坐标是否在图像有效范围内
                    if (x >= 0 && x < height && y >= 0 && y < width)
                    {
                        // 累加有效像素的RGB值
                        red_sum += temporary[x][y].rgbtRed;
                        green_sum += temporary[x][y].rgbtGreen;
                        blue_sum += temporary[x][y].rgbtBlue;
                        valid_count++;
                    }
                }
            }

            // 计算平均值并赋值给原图像(转换为浮点型后取整,避免整数除法截断误差)
            image[i][j].rgbtRed = round((float)red_sum / valid_count);
            image[i][j].rgbtGreen = round((float)green_sum / valid_count);
            image[i][j].rgbtBlue = round((float)blue_sum / valid_count);
        }
    }

    return;
}

关键逻辑说明

  • 像素相对位置计算:用di(行偏移)和dj(列偏移)表示当前像素与相邻像素的位置关系,范围是-1到1,这样就能遍历当前像素周围3x3的所有区域。
  • 边界有效性检查:对每个偏移后的坐标x和y,判断是否在0 <= x < height、0 <= y < width范围内,确保不会访问数组越界的内存。
  • 临时数组的必要性:模糊计算依赖原始像素值,如果直接修改原图像,后续像素的计算会使用已修改的值,导致结果错误,因此必须先保存原始数据到临时数组,所有计算基于临时数组完成后,再将结果赋值给原图像。

内容的提问来源于stack exchange,提问作者Leon de Keller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:41:35