为什么在CS50中为PSET4的图像上实现框模糊时,我的RGB值会稍微偏离?

问题描述 投票:0回答:1

我已经为此工作了两周,但无济于事。我认为逻辑和实现是合理的,但是除了使角落像素模糊之外,它没有通过所有测试。

我的逻辑:将原始像素文件图像中的每个像素复制到相同的像素,计算每个相邻像素中RGB值的平均值(如果存在),然后将其应用于原始图像。我的实现通过嵌套循环扫描每个像素的上一行,下一行和下一行。我知道这不是最简洁的实现方式-我对此并不陌生。

这里是一个此类错误的示例:

:(模糊错误地过滤3x3图像

预期输出

70 85 95

80 95 105

90 105 115

117 130 140

127140149

137 150 159

163178188

170185194

178193201

我的结果:

实际输出

70 85 95

90 106 116

103 119 129

135150160

145 160169

155169178

175 188 197

178191200

180193201

这是我的代码(用C语言编写:):

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE imageCopy[height][width];
                                            //assign new image
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            imageCopy[i][j] = image[i][j];
        }
    }

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int red = 0;
            int green = 0;
            int blue = 0;
            float pixelCount = 0.00;
                                                        //scan top row
            for (int k = -1; k < 2; k++)
            {
                if ((i - 1) >= 0 && (j + k) >= 0 && (j + k) < width)
                {
                    red += imageCopy[i - 1][j + k].rgbtRed;
                    green += imageCopy[i - 1][j + k].rgbtGreen;
                    blue += imageCopy[i - 1][j + k].rgbtBlue;
                    pixelCount++;
                }
            }
                                                        //scan same row
            for (int m = -1; m < 2; m++)
            {
                if ((j + m) >= 0 && (j + m) < width)
                {
                    red += imageCopy[i][j + m].rgbtRed;
                    green += imageCopy[i][j + m].rgbtGreen;
                    blue += imageCopy[i][j + m].rgbtBlue;
                    pixelCount++;
                }
            }
                                                        //scan below row
            for (int n = -1; n < 2; n++)
            {
                if ((i + 1) < height && (j + n) >= 0 && (j + n) < width)
                {
                    red += imageCopy[i + 1][j + n].rgbtRed;
                    green += imageCopy[i + 1][j + n].rgbtGreen;
                    blue += imageCopy[i + 1][j + n].rgbtBlue;
                    pixelCount++;
                }
            }
                                                        // find averages
            imageCopy[i][j].rgbtRed = round(red / pixelCount);
            imageCopy[i][j].rgbtGreen = round(green / pixelCount);
            imageCopy[i][j].rgbtBlue = round(blue / pixelCount);
        }
    }
                                                        // assign back to original image
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j] = imageCopy[i][j];
        }
    }
    return;
}

提前感谢。

c blur cs50
1个回答
0
投票

确定,我找到了[[问题。

您为每个像素计算一个新的“模糊”值,那里的逻辑似乎很好。最后,您要做的就是用这段代码为像素分配“新的模糊值”。

imageCopy[i][j].rgbtRed = round(red / pixelCount); imageCopy[i][j].rgbtGreen = round(green / pixelCount); imageCopy[i][j].rgbtBlue = round(blue / pixelCount);

这不行,因为您对已更改的图像应用了“模糊”过滤。因此,您要做的实际上是将一个像素更改为一个模糊像素,然后对于邻域像素,使用其旁边的“模糊”像素进行计算,这是错误的。

解决方案;

imageCopy不应在计算期间更改,因为所有模糊计算均应在“原始图像”上进行。在每个像素的末尾,您应将值直接传递给image。如下所示,将imageCopy替换为image

image[i][j].rgbtRed = round(red / pixelCount); image[i][j].rgbtGreen = round(green / pixelCount); image[i][j].rgbtBlue = round(blue / pixelCount);

并从代码中删除此for循环。 

for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j] = imageCopy[i][j]; } }

© www.soinside.com 2019 - 2024. All rights reserved.