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

CS50 filter-more edges函数check50检测不通过,求错误排查

CS50 Problem Set 4 Filter-More:Edges函数无法通过check50检测的问题

我正在完成CS50的Problem Set 4中filter-more项目,除edges函数外其余功能均正常,但该函数无法通过check50检测。ChatGPT判定我的代码正确,想请教代码中存在什么问题?

我的Edges函数代码

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    // Copying
    RGBTRIPLE copy[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            copy[i][j] = image[i][j];
        }
    }

    int Gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int Gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int GxsumRed = 0;
            int GxsumGreen = 0;
            int GxsumBlue = 0;

            int GysumRed = 0;
            int GysumGreen = 0;
            int GysumBlue = 0;

            // Forming 3x3 grid
            int m = 0;  // For Gx and Gy
            for (int k = i - 1; k < i + 2; k++)
            {
                if (k < 0)
                {
                    continue;
                }

                // if k > height then break
                if (k >= height)
                {
                    break;
                }
                int n = 0;  // For Gx and Gy
                for (int l = j - 1; l < j + 2; l++)
                {
                    if (l < 0)
                    {
                        continue;
                    }
                    if (l >= width)
                    {
                        break;
                    }

                    GxsumRed += Gx[m][n] * copy[k][l].rgbtRed;
                    GxsumGreen += Gx[m][n] * copy[k][l].rgbtGreen;
                    GxsumBlue += Gx[m][n] * copy[k][l].rgbtBlue;

                    GysumRed += Gy[m][n] * copy[k][l].rgbtRed;
                    GysumGreen += Gy[m][n] * copy[k][l].rgbtGreen;
                    GysumBlue += Gy[m][n] * copy[k][l].rgbtBlue;
                    n++;
                }
                m++;
            }

            int newRed = round(sqrt((GxsumRed * GxsumRed) + (GysumRed * GysumRed)));
            int newGreen = round(sqrt((GxsumGreen * GxsumGreen) + (GysumGreen * GysumGreen)));
            int newBlue = round(sqrt((GxsumBlue * GxsumBlue) + (GysumBlue * GysumBlue)));

            // Caping to 255
            if (newRed > 255)
            {
                newRed = 255;
            }

            if (newGreen > 255)
            {
                newGreen = 255;
            }

            if (newBlue > 255)
            {
                newBlue = 255;
            }

            image[i][j].rgbtRed = newRed;
            image[i][j].rgbtGreen = newGreen;
            image[i][j].rgbtBlue = newBlue;
        }
    }
    return;
}

check50检测结果

check50检测结果截图

问题分析

你的代码核心错误在于边界处理时的权重矩阵索引错位:

  • 当遍历到超出图像范围的k(行)或l(列)时,你用continue跳过了该位置的计算,但没有同步递增m或n(Gx/Gy矩阵的索引)。
  • 例如,处理图像第一行(i=0)时,k=-1触发continue,此时m不会递增,导致后续k=0(原图像第一行)对应的Gx/Gy索引是m=0,而正确索引应为m=1(对应3x3窗口的中间行)。
  • 同理,列方向的l<0会导致n不递增,后续列的权重对应全部错位,最终计算出的Gx、Gy求和值完全错误。

正确逻辑:遍历3x3窗口的所有9个相对位置(行偏移和列偏移从-1到1),不管位置是否在图像范围内,都对应Gx/Gy矩阵的正确索引。若位置超出范围,用0作为该位置的像素值参与计算,而非跳过整个权重位置。

修正后的代码示例

// Detect edges
void edges(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];
        }
    }

    int Gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int Gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int GxsumRed = 0, GxsumGreen = 0, GxsumBlue = 0;
            int GysumRed = 0, GysumGreen = 0, GysumBlue = 0;

            // 遍历3x3窗口的相对偏移量
            for (int dx = -1; dx <= 1; dx++)
            {
                for (int dy = -1; dy <= 1; dy++)
                {
                    int k = i + dx;
                    int l = j + dy;
                    // 计算Gx/Gy的索引
                    int m = dx + 1;
                    int n = dy + 1;

                    int red = 0, green = 0, blue = 0;
                    if (k >= 0 && k < height && l >= 0 && l < width)
                    {
                        red = copy[k][l].rgbtRed;
                        green = copy[k][l].rgbtGreen;
                        blue = copy[k][l].rgbtBlue;
                    }

                    GxsumRed += Gx[m][n] * red;
                    GxsumGreen += Gx[m][n] * green;
                    GxsumBlue += Gx[m][n] * blue;

                    GysumRed += Gy[m][n] * red;
                    GysumGreen += Gy[m][n] * green;
                    GysumBlue += Gy[m][n] * blue;
                }
            }

            // 转换为double避免整数溢出
            int newRed = round(sqrt((double)GxsumRed * GxsumRed + (double)GysumRed * GysumRed));
            int newGreen = round(sqrt((double)GxsumGreen * GxsumGreen + (double)GysumGreen * GysumGreen));
            int newBlue = round(sqrt((double)GxsumBlue * GxsumBlue + (double)GysumBlue * GysumBlue));

            // 限制值在0-255之间
            image[i][j].rgbtRed = (newRed > 255) ? 255 : newRed;
            image[i][j].rgbtGreen = (newGreen > 255) ? 255 : newGreen;
            image[i][j].rgbtBlue = (newBlue > 255) ? 255 : newBlue;
        }
    }
    return;
}

额外注意:计算平方根时将整数转换为double类型,可避免整数溢出导致的计算错误,这也是check50可能检测到的问题点之一。

内容的提问来源于stack exchange,提问作者GreenIsLearningProgramming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:12:04