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

CS50滤镜进阶任务:Edges滤镜仅保留边角像素其余全黑问题

CS50 Edges滤镜问题修复

问题根源

你代码里的核心错误是计算卷积时引用了错误的像素:在遍历周围3x3像素的循环中,你始终使用image[i][j](当前目标像素)的颜色值来计算Gx和Gy,而不是使用偏移后的image[i+a][j+b]的颜色值。

对于图像中间的像素,3x3卷积核的权重会相互抵消(比如Gx的列权重-1、0、1,行相加后对于相同像素值来说总和为0),所以计算出来的gxred、gyred等都是0,最终sqrt后结果为0,导致像素全黑;而边缘/角落像素因为部分偏移超出图像范围,对应的权重没有被完全抵消,所以还能显示出像素值。

修正后的代码

把卷积计算部分的image[i][j]替换成image[i+a][j+b]即可:

void edges(int height, int width, RGBTRIPLE image[height][width])
{
    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}};

    RGBTRIPLE temp[height][width];

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

            double gxred = 0, gxgreen = 0, gxblue = 0;
            double gyred = 0, gygreen = 0, gyblue = 0;
            double red = 0, green = 0, blue = 0;

            for(int a = -1; a <= 1; a++) {
                for(int b = -1; b <=1; b++) {

                    if(a+i >= 0 && a+i < height && b+j >= 0 && b+j < width) {
                        // 修正:使用偏移后的像素而非当前像素
                        gxred += Gx[a+1][b+1] * image[i+a][j+b].rgbtRed;
                        gxgreen += Gx[a+1][b+1] * image[i+a][j+b].rgbtGreen;
                        gxblue += Gx[a+1][b+1] * image[i+a][j+b].rgbtBlue;

                        gyred += Gy[a+1][b+1] * image[i+a][j+b].rgbtRed;
                        gygreen += Gy[a+1][b+1] * image[i+a][j+b].rgbtGreen;
                        gyblue += Gy[a+1][b+1] * image[i+a][j+b].rgbtBlue;
                    }

                }
            }

            red = sqrt(((gxred*gxred) + (gyred*gyred)));
            if(red > 255)
                red = 255;
            green = sqrt(((gxgreen*gxgreen) + (gygreen*gygreen)));
            if(green > 255)
                green = 255;
            blue = sqrt(((gxblue*gxblue) + (gyblue*gyblue)));
            if(blue > 255)
                blue = 255;

            temp[i][j].rgbtRed = red;
            temp[i][j].rgbtGreen = green;
            temp[i][j].rgbtBlue = blue;

        }
    }

    // 复制临时图像到原图像
    for(int i = 0; i < height; i++) {
        for(int j = 0; j < width; j++) {
            image[i][j].rgbtRed = temp[i][j].rgbtRed;
            image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
            image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
        }
    }

    return;
}

额外调试技巧

可以用一张小尺寸的测试图(比如3x3或5x5)来debug,这样能清晰看到每个像素的计算过程,避免大图无法查看中间值的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:35:28