CS50 pset4模糊[已关闭]

wi3ka0sx  于 2022-12-22  发布在  其他
关注(0)|答案(1)|浏览(159)

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
20小时前关门了。
Improve this question
我不明白为什么我的代码不起作用。它返回了一个非常奇怪的图像,颜色非常深。我读了别人的类似问题的代码(https://stackoverflow.com/a/70203062/19299155),对我来说,这看起来是一个非常相似的概念和方法。如果有人能向我解释为什么我的不起作用,我会非常感激。有一件事我不明白另一个家伙的代码就是他更新像素值的原因(//分配新的像素值),因为这意味着其他像素的平均值将使用原始像素的现在更新的像素的新值。(我希望我是正确的解释自己).我也读了这篇文章(cs50 - pset4 - blur)这个家伙似乎有同样的问题,我,和非常相似的代码,但人们给他的答案似乎不适用于我.以下是我的代码:

void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE blurred[height][width];

    for (int i = 0; i<height; i++){
        for (int j = 0; j<width; j++){
            float colorCount = 0.0;
            blurred[i][j].rgbtBlue = 0;
            blurred[i][j].rgbtGreen = 0;
            blurred[i][j].rgbtRed = 0;

            for (int count = -1; count<2; count++){
                if (((count+i) >= 0) && ((count+i) < height)){
                    for (int count2 = -1; count2<2; count2++){
                        if (((count2+j) >= 0) && ((count2+j) < width)){
                            blurred[i][j].rgbtBlue += image[i+count][j+count2].rgbtBlue;
                            blurred[i][j].rgbtGreen += image[i+count][j+count2].rgbtGreen;
                            blurred[i][j].rgbtRed += image[i+count][j+count2].rgbtRed;
                            colorCount += 1.0;
                        }
                    }
                }
            }
            blurred[i][j].rgbtBlue = round(blurred[i][j].rgbtBlue/colorCount);
            blurred[i][j].rgbtGreen = round(blurred[i][j].rgbtGreen/colorCount);
            blurred[i][j].rgbtRed = round(blurred[i][j].rgbtRed/colorCount);

        }
    }

for (int i = 0; i<height; i++){
        for (int j = 0; j<width; j++){
            image[i][j].rgbtBlue = blurred[i][j].rgbtBlue;
            image[i][j].rgbtGreen = blurred[i][j].rgbtGreen;
            image[i][j].rgbtRed = blurred[i][j].rgbtRed;
        }
    }
    return;
}

我尝试了2个嵌套的for循环,从-1开始,这样它会像-10 +1一样遍历3x3个相邻的像素。对于count = -1,它会先count2 = -1,然后count2 = 0,然后count2 = 1。然后count = 0,count2 = -1,然后count2 = 0,然后count2 = 1。依此类推。

euoag5mw

euoag5mw1#

在线搜索RGBTRIPLE的定义(因为您没有提供它)将生成this post,其中定义为:

typedef uint8_t  BYTE;

typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

这给当前的模糊内核计算带来了问题,因为您使用的是RGBTRIPLE值来累加3x 3内核中所有像素的总和。像素中的每个颜色通道都使用整个范围,因此当您将另一个像素的数据添加到该范围时,可能会超出可存储的最大值。这将丢弃此类操作的进位位,并将结果换行以保留在0- 255范围。
输出为“暗”的原因正是因为对于图像的大部分,通道的最大可能值为round(255.0 / 9),即28。在图像的边缘,该值会更亮,但仍不会比round(255.0 / 4)更好,即64。在此狭窄范围内,您还可能会看到锯齿状的伪像或条带,其中颜色通道在丢弃溢出位后进行了 Package 。
即使你链接的答案也指出了同样的事情,你错误地Assert “似乎不适用于我”。这是不正确的。这绝对不可能对你没有问题。请允许我修改你的代码,也许只是重命名一些变量以提高可读性:

for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int count = 0;
        float sumRed = 0.0f, sumGreen= 0.0f, sumBlue = 0.0f;
        
        for (int dy = -1; dy <= 1; dy++) {
            int ky = y + dy;
            if (ky >= 0 && ky < height) {
                for (int dx = -1; dx <= 1; dx++) {
                    int kx = x + dx;
                    if (kx >= 0 && kx < width) {
                        sumBlue  += (float)image[ky][kx].rgbtBlue;
                        sumGreen += (float)image[ky][kx].rgbtGreen;
                        sumRed   += (float)image[ky][kx].rgbtRed;
                        count++;
                    }
                }
            }
        }
        
        blurred[y][x].rgbtBlue  = round(sumBlue / count);
        blurred[y][x].rgbtGreen = round(sumGreen / count);
        blurred[y][x].rgbtRed   = round(sumRed / count);
    }
}

for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        image[y][x] = blurred[y][x];
    }
}

相关问题