CS50 第 4 周模糊滤镜,图像模糊但检查 50 值错误

时间:2021-02-28 21:40:05

标签: c cs50

我的 check50 有问题,我想知道我所做的是否真的得到了正确的盒子。

模糊的目标是获取所有灰色框的颜色并对其进行平均

对于每个像素,如果像素不在第一行,我知道我可以有顶盒。如果像素不在底行,我知道我可以有底框。与边缘相同的逻辑。

enter image description here

但也有像素在角落或边缘的情况

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE arrayCopy[height][width]; 
    memcpy(arrayCopy, image, sizeof arrayCopy);

    for (int i = 0; i < height; i++)
    {
        for (int w = 0; w < width; w++)
        {
            int counter = 0;
            int totalRed = 0;
            int totalBlue = 0;
            int totalGreen = 0; 
            
            if (!(w == 0))
            {
                int leftBoxRed = arrayCopy[i][w-1].rgbtRed;
                int leftBoxBlue = arrayCopy[i][w-1].rgbtBlue;
                int leftBoxGreen = arrayCopy[i][w-1].rgbtGreen;
                
                totalRed = totalRed + leftBoxRed;
                totalBlue = totalBlue + leftBoxBlue;
                totalGreen = totalGreen + leftBoxGreen;
                counter++; 

                //printf("%i\n", leftBoxRed);
            }

            if (!(w == width-1))
            {
                int rightBoxRed = arrayCopy[i][w+1].rgbtRed;
                int rightBoxBlue = arrayCopy[i][w+1].rgbtBlue;
                int rightBoxGreen = arrayCopy[i][w+1].rgbtGreen;
                
                totalRed = totalRed + rightBoxRed; 
                totalBlue = totalBlue + rightBoxBlue;
                totalGreen = totalGreen + rightBoxGreen;
                counter++;
            }

            if (!(i == 0))
            {
                if (!(w == 0))
                {
                    int leftTopBoxRed = arrayCopy[i-1][w-1].rgbtRed;
                    int leftTopBoxBlue = arrayCopy[i-1][w-1].rgbtBlue;
                    int leftTopBoxGreen = arrayCopy[i-1][w-1].rgbtGreen; 
                    
                    totalRed = totalRed + leftTopBoxRed; 
                    totalBlue = totalBlue + leftTopBoxBlue;
                    totalGreen = totalGreen + leftTopBoxGreen;
                    counter++; 
                }
                
                if (!(w == width - 1))
                {
                    int rightTopBoxRed = arrayCopy[i-1][w+1].rgbtRed;
                    int rightTopBoxBlue = arrayCopy[i-1][w+1].rgbtBlue;
                    int rightTopBoxGreen = arrayCopy[i-1][w+1].rgbtGreen; 
                    
                    totalRed = totalRed + rightTopBoxRed; 
                    totalBlue = totalBlue + rightTopBoxBlue;
                    totalGreen = totalGreen + rightTopBoxGreen; 
                    counter++;
                }
                
                int topBoxRed = arrayCopy[i-1][w].rgbtRed;
                int topBoxBlue = arrayCopy[i-1][w].rgbtBlue;
                int topBoxGreen = arrayCopy[i-1][w].rgbtGreen;
                
                totalRed = totalRed + topBoxRed; 
                totalBlue = totalBlue + topBoxBlue; 
                totalGreen = totalGreen + topBoxGreen;
                counter++; 
            }

            if (!(i == height-1))
            {
                
                if (!(w == 0))
                {
                    int leftBottomBoxRed = arrayCopy[i+1][w-1].rgbtRed;
                    int leftBottomBoxBlue = arrayCopy[i+1][w-1].rgbtBlue;
                    int leftBottomBoxGreen = arrayCopy[i+1][w-1].rgbtGreen;
                    
                    totalRed = totalRed + leftBottomBoxRed; 
                    totalBlue = totalBlue + leftBottomBoxBlue;
                    totalGreen = totalGreen + leftBottomBoxGreen; 
                    counter++;
                }
                
                if (!(w == width - 1))
                {
                    int rightBottomBoxRed = arrayCopy[i+1][w+1].rgbtRed;
                    int rightBottomBoxBlue = arrayCopy[i+1][w+1].rgbtBlue;
                    int rightBottomBoxGreen = arrayCopy[i+1][w+1].rgbtGreen;
                    
                    totalRed = totalRed + rightBottomBoxRed; 
                    totalBlue = totalBlue + rightBottomBoxBlue;
                    totalGreen = totalGreen + rightBottomBoxGreen;
                    counter++; 
                }
                
                int bottomBoxRed = arrayCopy[i+1][w].rgbtRed;
                int bottomBoxBlue = arrayCopy[i+1][w].rgbtBlue;
                int bottomBoxGreen = arrayCopy[i+1][w].rgbtGreen;
                counter++;
                
                totalRed = totalRed + bottomBoxRed; 
                totalBlue = totalBlue + bottomBoxBlue;
                totalGreen = totalGreen + bottomBoxGreen;
                
            }
            
            
            float averageRed = totalRed / (float) counter; 
            float averageBlue = totalBlue / (float) counter;
            float averageGreen = totalGreen / (float) counter;
            
        
            
            image[i][w].rgbtRed = (int) roundf(averageRed); 
            image[i][w].rgbtBlue = (int) roundf(averageBlue);
            image[i][w].rgbtGreen = (int) roundf(averageGreen);
                
            //printf("%i\n", (int) roundf(averageRed));
        }
    }

    return;
}


enter image description here enter image description here enter image description here 原图 enter image description here 我的图像输出 enter image description here

1 个答案:

答案 0 :(得分:1)

在第一个失败的休息结果中(顺便说一下,请避免在问题中放置文本图像),您应该计算中间像素的红色分量的值为 127。你计算了 128。

这张图片中九个像素的红色分量如下:

 10  40  70
110 120 130
200 220 240

如果,正如您在问题顶部所声称的,您应该计算围绕中心像素的八个像素的平均值,那么您将得到 (10+40+70+110+ 130+200+220+240)/8,等于127.5。 roundf() 函数从零开始向上舍入中途情况,因此从结果上看,您获得了正确答案 128。

但是,我怀疑您实际上应该计算所有九个像素的平均值,包括中心像素。在这种情况下,结果将是 (10+40+70+110+120+130+200+220+240)/9,其中 roundf() 将从 126.67 向上取整到 127。

所以我认为您做错的只是忘记在计算中包含 arrayCopy[i][w] 处的像素。

我还应该指出,您的代码非常WET。很容易忘记像这样的代码中发生的事情,并且调试可能很困难。也许考虑使用内循环来扫描(最多)九个像素的每个块。可能是这样的(警告:我根本没有测试过):

    for (int x=0; x<width; x++) {
        for (int y=0; y<height; y++) {
            int counter = 0;
            int totalr=0, totalg=0, totalb=0;
            for (int dx=-1; dx<=1; dx++) {
                if (x+dx < 0 || x+dx >= width) continue;
                for (int dy=-1; dy<=1; dy++) {
                    if (y+dy >=0 && y+dy < height) {
                        totalr += image[y+dy][x+dx].rgbtRed;
                        totalg += image[y+dy][x+dx].rgbtGreen;
                        totalb += image[y+dy][x+dx].rgbtBlue;
                        counter++;
                    }
                }
            }
            result[y][x].rgbtRed = roundf(totalr / (float)counter);
            result[y][x].rgbtGreen = roundf(totalg / (float)counter);
            result[y][x].rgbtBlue = roundf(totalb / (float)counter);
        }
    }