繁体   English   中英

cs50 pset4 过滤器“边缘”

[英]cs50 pset4 filter “edges”

当我通过edges代码运行照片时,图像返回全白色,除了底部的三行像素,看起来类似于 Rainbow tv static。 我试图调试我的代码,但我仍然无法弄清楚:

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}};
    int redx = 0;
    int greenx = 0;
    int bluex = 0;
    int redy = 0;
    int greeny = 0;
    int bluey = 0;
    int finalred = 0;
    int finalgreen = 0;
    int finalblue = 0;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            for (int k = i - 1; k <= i + 1 && k < height && k >= 0; k++)
            {
                for (int m = j - 1; m <= j + 1 && m < width && m >= 0; m++)
                {
                    if (k < i)
                    {
                        if (m < j)
                        {
                            redx += image[k][m].rgbtRed * gx[0][0];
                            greenx += image[k][m].rgbtGreen * gx[0][0];
                            bluex += image[k][m].rgbtBlue * gx[0][0];
                            redy += image[k][m].rgbtRed * gy[0][0];
                            greeny += image[k][m].rgbtGreen * gy[0][0];
                            bluey += image[k][m].rgbtBlue * gy[0][0];
                            // gx[?][0]
                        }
                        else if (m > j)
                        {
                            redx += image[k][m].rgbtRed * gx[0][2];
                            greenx += image[k][m].rgbtGreen * gx[0][2];
                            bluex += image[k][m].rgbtBlue * gx[0][2];
                            redy += image[k][m].rgbtRed * gy[0][2];
                            greeny += image[k][m].rgbtGreen * gy[0][2];
                            bluey += image[k][m].rgbtBlue * gy[0][2];
                            // gx[?][2]
                        }
                        else
                        {
                            redx += image[k][m].rgbtRed * gx[0][1];
                            greenx += image[k][m].rgbtGreen * gx[0][1];
                            bluex += image[k][m].rgbtBlue * gx[0][1];
                            redy += image[k][m].rgbtRed * gy[0][1];
                            greeny += image[k][m].rgbtGreen * gy[0][1];
                            bluey += image[k][m].rgbtBlue * gy[0][1];
                            // gx[?][1]
                        }
                        // gx[0][?]
                    }
                    else if (k > i)
                    {
                        if (m < j)
                        {
                            redx += image[k][m].rgbtRed * gx[2][0];
                            greenx += image[k][m].rgbtGreen * gx[2][0];
                            bluex += image[k][m].rgbtBlue * gx[1][0];
                            redy += image[k][m].rgbtRed * gy[2][0];
                            greeny += image[k][m].rgbtGreen * gy[2][0];
                            bluey += image[k][m].rgbtBlue * gy[2][0];
                            // gx[?][0]
                        }
                        else if (m > j)
                        {
                            redx += image[k][m].rgbtRed * gx[2][2];
                            greenx += image[k][m].rgbtGreen * gx[2][2];
                            bluex += image[k][m].rgbtBlue * gx[2][2];
                            redy += image[k][m].rgbtRed * gy[2][2];
                            greeny += image[k][m].rgbtGreen * gy[2][2];
                            bluey += image[k][m].rgbtBlue * gy[2][2];
                            // gx[?][2]
                        }
                        else
                        {
                            redx += image[k][m].rgbtRed * gx[2][1];
                            greenx += image[k][m].rgbtGreen * gx[2][1];
                            bluex += image[k][m].rgbtBlue * gx[2][1];
                            redy += image[k][m].rgbtRed * gy[2][1];
                            greeny += image[k][m].rgbtGreen * gy[2][1];
                            bluey += image[k][m].rgbtBlue * gy[2][1];
                            // gx[?][1]
                        }
                        // gx[2][?]
                    }
                    else
                    {
                        if (m < j)
                        {
                            redx += image[k][m].rgbtRed * gx[1][0];
                            greenx += image[k][m].rgbtGreen * gx[1][0];
                            bluex += image[k][m].rgbtBlue * gx[1][0];
                            redy += image[k][m].rgbtRed * gy[1][0];
                            greeny += image[k][m].rgbtGreen * gy[1][0];
                            bluey += image[k][m].rgbtBlue * gy[1][0];
                            // gx[?][0]
                        }
                        else if (m > j)
                        {
                            redx += image[k][m].rgbtRed * gx[1][2];
                            greenx += image[k][m].rgbtGreen * gx[1][2];
                            bluex += image[k][m].rgbtBlue * gx[1][2];
                            redy += image[k][m].rgbtRed * gy[1][2];
                            greeny += image[k][m].rgbtGreen * gy[1][2];
                            bluey += image[k][m].rgbtBlue * gy[1][2];
                            // gx[?][2]
                        }
                        else
                        {
                            redx += image[k][m].rgbtRed * gx[1][1];
                            greenx += image[k][m].rgbtGreen * gx[1][1];
                            bluex += image[k][m].rgbtBlue * gx[1][1];
                            redy += image[k][m].rgbtRed * gy[1][1];
                            greeny += image[k][m].rgbtGreen * gy[1][1];
                            bluey += image[k][m].rgbtBlue * gy[1][1];
                            // gx[?][1]
                        }
                        // gx[1][?]
                    }
                }
            }
            finalred = (redx)^2 + (redy)^2;
            finalgreen = (greenx)^2 + (greeny)^2;
            finalblue = (bluex)^2 + (bluey)^2;
            if (finalred > 255)
            {
                finalred = 255;
            }
            if (finalgreen > 255)
            {
                finalgreen = 255;
            }
            if (finalblue > 255)
            {
                finalblue = 255;
            }
            image[i][j].rgbtRed = finalred;
            image[i][j].rgbtGreen = finalgreen;
            image[i][j].rgbtBlue = finalblue;
        }
    }
    return;
}

初始化变量

这些初始化:

    int redx = 0;
    int greenx = 0;
    int bluex = 0;
    int redy = 0;
    int greeny = 0;
    int bluey = 0;

出现在ij上的for语句之前,但这些变量会为每个像素累积总和,因此必须为每个像素初始化它们。 那是在j上的for语句内和km上的for语句之前。

(由于在评论中指出了这一点,已编辑问题中的代码以在更新每个像素后为这些变量分配零。这可行,但这是一个糟糕的解决方案。只需将变量的定义和初始化移动到外部两个for循环。)

不正确的循环条件

此语句将失败:

for (int k = i - 1; k <= i + 1 && k < height && k >= 0; k++)

考虑当i为 0 时会发生什么。然后int k = i - 1k初始化为 -1。 那么k >= 0是假的,所以测试k <= i + 1 && k < height && k >= 0是假的,所以循环的主体永远不会执行,并且没有i = 的行中的像素0 已更新。

您需要重新考虑代码的设计方式。 这显然是一种处理边缘和角落的尝试,这在理论上涉及使用阵列外的像素进行计算,但还有其他解决方案。 这是这个问题的重点,因此考虑并实施两个或多个解决方案将是一个很好的练习。

不正确的运算符

^用于尝试在(redx)^2中求幂。 在 C 中, ^是 XOR 运算符。 在这种情况下,要对一个数字求平方,只需将其自身相乘,就像redx*redx C中有一个求幂运算符,但它是用于浮点运算的,所以不适合这个问题,你将在另一课中学习。

过早的图像更新

这些行:

image[i][j].rgbtRed = finalred;
image[i][j].rgbtGreen = finalgreen;
image[i][j].rgbtBlue = finalblue;

ij上的循环内,因此它们会在处理每个像素时更新图像。 这意味着尚未更新的像素将使用为先前更新的像素分配的新值。 这是不正确的; 在计算新像素的值时,应使用原始更新前的值。 对此的解决方案需要使用单独的缓冲区来临时保存新值。 (一个简单的解决方案是使用一个完整的单独数组来保存新值,但还有更节省空间的解决方案。)

计算未四舍五入

此代码取平方根并将其截断为 integer:

finalred = sqrt((redx)^2 + (redy)^2);

但是,问题规范说“并且由于通道值只能采用从 0 到 255 的 integer 值,因此请确保将结果值四舍五入到最接近的 integer 和

过多的代码

像这样的代码多次出现:

if (k < i)
                    {
                        if (m < j)
                        {
                            redx += image[k][m].rgbtRed * gx[0][0];
                            greenx += image[k][m].rgbtGreen * gx[0][0];
                            bluex += image[k][m].rgbtBlue * gx[0][0];
                            redy += image[k][m].rgbtRed * gy[0][0];
                            greeny += image[k][m].rgbtGreen * gy[0][0];
                            bluey += image[k][m].rgbtBlue * gy[0][0];
                            // gx[?][0]
                        }

通过这些循环的结构, k只能等于i-1ii+1 因此,没有必要对 arrays 的 select 索引012使用if语句; 我们可以简单地计算它,对于m也是类似的,然后一组代码就足以满足所有情况:

redx   += image[k][m].rgbtRed   * gx[k-(i-1)][m-(j-1)];
greenx += image[k][m].rgbtGreen * gx[k-(i-1)][m-(j-1)];
bluex  += image[k][m].rgbtBlue  * gx[k-(i-1)][m-(j-1)];
redy   += image[k][m].rgbtRed   * gy[k-(i-1)][m-(j-1)];
greeny += image[k][m].rgbtGreen * gy[k-(i-1)][m-(j-1)];
bluey  += image[k][m].rgbtBlue  * gy[k-(i-1)][m-(j-1)];

请注意,处理边缘和角落的问题仍然存在,如上所述。

不必要的初始化

这些初始化和重置是不必要的:

    int finalred = 0;
    int finalgreen = 0;
    int finalblue = 0;
            finalred = 0;
            finalgreen = 0;
            finalblue = 0;

相反,只需在需要它们的地方定义这些变量; 改变:

            finalred = sqrt((redx)^2 + (redy)^2);
            finalgreen = sqrt((greenx)^2 + (greeny)^2);
            finalblue = sqrt((bluex)^2 + (bluey)^2);

至:

            int finalred = sqrt((redx)^2 + (redy)^2);
            int finalgreen = sqrt((greenx)^2 + (greeny)^2);
            int finalblue = sqrt((bluex)^2 + (bluey)^2);

在需要的地方定义变量会限制他们的 scope,这限制了他们犯错的机会。 这适用于上面的redx和相关变量:通过在每像素代码中定义和初始化它们,它们的使用仅限于计算单个像素,因此让总和累积在多个像素上的错误是不可能犯的.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM