CS50(2019)问题集“过滤器”:“模糊”以某种方式无法正常工作

时间:2019-12-12 13:02:14

标签: c cs50

因此,我花了大约5个小时以上的时间来弄清楚我的代码出了什么问题。我用在Paint中手动创建的3x3文件尝试了debug50,一切似乎都按预期进行了。每个像素围绕其自身进行3x3扫描,而忽略不存在的像素,例如角落或边缘周围的像素。每种颜色的最终平均值也是正确的。但是,以某种方式,当我使用check50进行检查时,它发出了以下消息:

通过无数次调整和抓挠,我认为现在应该该向社区寻求帮助了。这是我的代码:

{
    for (int h = 0; h < height; h++)
    {
        for (int w = 0; w < width; w++)
        {
            int avgfordiv = 0;
            int neighvalgreen = 0;
            int neighvalblue = 0;
            int neighvalred = 0;

            for (int hh = -1; hh < 2; hh++)
            {
                for (int ww = -1; ww < 2; ww++)
                {
                    if ((h+hh) != height && (w+ww) != width && (h+hh) != -1 && (w+ww) != -1)
                    {
                        //sweep
                        avgfordiv++;//count up for division
                        neighvalgreen += image[h + hh][w + ww].rgbtGreen;
                        neighvalred += image[h + hh][w + ww].rgbtRed;
                        neighvalblue += image[h + hh][w + ww].rgbtBlue;
                    }
                }
            }
            //add values to pixels
             image[h][w].rgbtGreen = (int)(round((float)neighvalgreen / avgfordiv));
             image[h][w].rgbtBlue = (int)(round((float)neighvalblue / avgfordiv));
             image[h][w].rgbtRed = (int)(round((float)neighvalred / avgfordiv));

            //check cap
             if (image[h][w].rgbtGreen <= 255)
                {}
            else
                image[h][w].rgbtGreen %= 255;

            if (image[h][w].rgbtRed <= 255)
                {}
            else
                image[h][w].rgbtRed %= 255;

            if (image[h][w].rgbtBlue <= 255)
                {}
            else
                image[h][w].rgbtBlue %= 255;
        }
    }
    return;
}

5 个答案:

答案 0 :(得分:2)

制作图像的副本并使用该副本计算红色,绿色和蓝色的总量似乎可以解决问题。

RGBTRIPLE copy[height][width];
for (int h = 0; h < height; i++)
{
    for (int w = 0; w < width; j++)
    {
        copy[h][w] = image[h][w];
    }
}

并在下面进行更改:

neighvalgreen += copy[h + hh][w + ww].rgbtGreen;
neighvalred += copy[h + hh][w + ww].rgbtRed;
neighvalblue += copy[h + hh][w + ww].rgbtBlue;

此外,您无需检查值是否超过255,因为您正在计算平均值,因此它永远不会超过255。

答案 1 :(得分:0)

我写了一个完全不同的代码,并得到了相同的错误和相同的数字。 但是有人写了这段代码,效果很好:

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE ogImage[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            ogImage[i][j] = image[i][j];
        }
    }

    for (int i = 0, red, green, blue, counter; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            red = green = blue = counter = 0;

            if (i >= 0 && j >= 0)
            {
                red += ogImage[i][j].rgbtRed;
                green += ogImage[i][j].rgbtGreen;
                blue += ogImage[i][j].rgbtBlue;
                counter++;
            }
            if (i >= 0 && j - 1 >= 0)
            {
                red += ogImage[i][j-1].rgbtRed;
                green += ogImage[i][j-1].rgbtGreen;
                blue += ogImage[i][j-1].rgbtBlue;
                counter++;
            }
            if ((i >= 0 && j + 1 >= 0) && (i >= 0 && j + 1 < width))
            {
                red += ogImage[i][j+1].rgbtRed;
                green += ogImage[i][j+1].rgbtGreen;
                blue += ogImage[i][j+1].rgbtBlue;
                counter++;
            }
            if (i - 1 >= 0 && j >= 0)
            {
                red += ogImage[i-1][j].rgbtRed;
                green += ogImage[i-1][j].rgbtGreen;
                blue += ogImage[i-1][j].rgbtBlue;
                counter++;
            }
            if (i - 1 >= 0 && j - 1 >= 0)
            {
                red += ogImage[i-1][j-1].rgbtRed;
                green += ogImage[i-1][j-1].rgbtGreen;
                blue += ogImage[i-1][j-1].rgbtBlue;
                counter++;
            }
            if ((i - 1 >= 0 && j + 1 >= 0) && (i - 1 >= 0 && j + 1 < width))
            {
                red += ogImage[i-1][j+1].rgbtRed;
                green += ogImage[i-1][j+1].rgbtGreen;
                blue += ogImage[i-1][j+1].rgbtBlue;
                counter++;
            }
            if ((i + 1 >= 0 && j >= 0) && (i + 1 < height && j >= 0))
            {
                red += ogImage[i+1][j].rgbtRed;
                green += ogImage[i+1][j].rgbtGreen;
                blue += ogImage[i+1][j].rgbtBlue;
                counter++;
            }
            if ((i + 1 >= 0 && j - 1 >= 0) && (i + 1 < height && j - 1 >= 0))
            {
                red += ogImage[i+1][j-1].rgbtRed;
                green += ogImage[i+1][j-1].rgbtGreen;
                blue += ogImage[i+1][j-1].rgbtBlue;
                counter++;
            }
            if ((i + 1 >= 0 && j + 1 >= 0) && (i + 1 < height && j + 1 < width))
            {
                red += ogImage[i+1][j+1].rgbtRed;
                green += ogImage[i+1][j+1].rgbtGreen;
                blue += ogImage[i+1][j+1].rgbtBlue;
                counter++;
            }

            image[i][j].rgbtRed = round(red / (counter * 1.0));
            image[i][j].rgbtGreen = round(green / (counter * 1.0));
            image[i][j].rgbtBlue = round(blue / (counter * 1.0));
        }
    }

    return;
}

我知道已经很晚了,但也许会对某人有所帮助。

答案 2 :(得分:0)

对于将来有疑问的人

您不需要那么多条件,只需认为您正在使用另一个矩阵即可。

完成此操作后,只需放置一个条件,以防工作位置未超出矩阵限制。

示例

当前行+子矩阵行不能小于零,因为这将超出限制。

L:矩阵线

sL:子矩阵行

[L + sL] [0]! <0

[0 +(-1)[0]应该是推断。

现在也要考虑其他情况。

void blur(int height, int width, RGBTRIPLE image[height][width])
    {
        // average of the ORIGINAL value of the pixels around it
        int avgR, avgG, avgB, counter;

        // make a copy of the original image for the calculations

        RGBTRIPLE copy[height][width];

        for (int h = 0; h < height; h++)
        {
            for (int w = 0; w < width; w++)
            {
                copy[h][w] = image[h][w];
            }
        }

        // go across the image
        for (int linha = 0; linha < height; linha++)
        {
            for (int coluna = 0; coluna < width; coluna++)
            {
                // initialize the variables and reset them to 0
                avgR = 0;
                avgG = 0;
                avgB = 0;
                counter = 0;
                // go across the pixels around
                for (int row = -1; row < 2; row++)
                {
                    for (int column = -1; column < 2; column++)
                    {
                        if (linha + row < 0 || coluna + column < 0 || linha + row >= height || coluna + column >= width)
                        {

                        }
                        else
                        {
                            avgR += copy[linha + row][coluna + column].rgbtRed;
                            avgG += copy[linha + row][coluna + column].rgbtGreen;
                            avgB += copy[linha + row][coluna + column].rgbtBlue;
                            counter ++;
                        }
                    }
                }
                image[linha][coluna].rgbtRed = round(avgR / (float) counter);
                image[linha][coluna].rgbtGreen = round(avgG / (float) counter);
                image[linha][coluna].rgbtBlue = round(avgB / (float) counter);
            }
        }

        return;
    }

答案 3 :(得分:0)

Fernando的回答很好(我没有代表直接对此发表评论),但是为了处理边缘情况,我将像素的for循环的起点和终点转换为变量,如果您正在使用它进行调整边缘(“ i”和“ j”是我的外循环计数器):

#include <stdio.h>
#include <stdint.h>

#define u8 uint8_t
#define u32 uint32_t

u8 to_hex_digit(char a, char b) {
    u8 result = 0;

    if (a >= 0x30 && a <= 0x39) {
        result = (a - 0x30) << 4;
    } else if (a >= 0x41 && a <= 0x46) {
        result = (a - 0x41 + 10) << 4;
    } else if (a >= 0x61 && a <= 0x7A) {
        result = (a - 0x61 + 10) << 4;
    } else {
        printf("invalid hex digit: '%c'\n", a);
    }

    if (b >= 0x30 && b <= 0x39) {
        result |= b - 0x30;
    } else if (b >= 0x41 && b <= 0x46) {
        result |= b - 0x41 + 10;
    } else if (b >= 0x61 && b <= 0x7A) {
        result |= b - 0x61 + 10;
    } else {
        printf("invalid hex digit: '%c'\n", b);
    }

    return result;
}

u32 main() {
    u8 result = to_hex_digit('F', 'F');
    printf("0x%X (%d)\n", result, result);

    return 0;
}

答案 4 :(得分:0)

我在伪代码中的策略如下:

  1. 将整个图像另存为tmp
  2. 遍历每个像素
  3. 对于每个像素,以一个3x3正方形的图像为中心,所述像素为中心。检查3x3正方形的每个像素(如果存在)。如果是这样,将总和相加。最后计算平均值
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    //store entire image in tmp to maintain original value
    RGBTRIPLE tmp[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            tmp[i][j] = image[i][j];
        }
    }
    
    //loop through each pixel
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            float n = 0, r = 0, b = 0, g = 0;
                
            // loop the 9box
            for (int ii = 0; ii < 3; ii++)
            {
                for (int jj = 0; jj < 3; jj++)
                {
                    //calculate average. ONLY if that pixel exists.
                    if ((i + ii - 1 >= 0 && i + ii - 1 < height) && (j + jj - 1 >= 0 && j + jj - 1 < width))
                    {
                        b = b + (float)tmp[i + ii - 1][j + jj - 1].rgbtBlue;
                        r = r + (float)tmp[i + ii - 1][j + jj - 1].rgbtRed;
                        g = g + (float)tmp[i + ii - 1][j + jj - 1].rgbtGreen;
                        n++;
                    }                        
                }
            }
                
            //calculate
            image[i][j].rgbtBlue = (int)round(b / n);
            image[i][j].rgbtRed = (int)round(r / n);
            image[i][j].rgbtGreen = (int)round(g / n);
        }
    }

    return;
}