CS50 pset4 - фильтр (менее удобный), функция размытия - PullRequest
0 голосов
/ 15 апреля 2020

Я написал код для функции размытия фильтра pset. Однако всякий раз, когда я пытаюсь скомпилировать код, я получаю сообщение об ошибке. Может кто-то увидеть, где лежит моя ошибка?

Код:


// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    int count = 0;

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

            if (j - 1 >= 0 && j - 1  <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255)
            {
                red += image[i][j + 1].rgbtRed;
                green += image[i][j + 1].rgbtGreen;
                blue += image[i][j + 1].rgbtBlue;
                count++;
            }

            if (j - 1 >= 0 && j - 1  <= 255 && i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255 && i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (j - 1 >= 0 && j - 1  <= 255 && i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255 && i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

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

        }

    }
    return;
}

Сообщение об ошибке:


helpers.c:170:24: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:171:26: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:172:25: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:178:24: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:179:26: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:180:25: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:146:24: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:147:26: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:148:25: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:154:24: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:155:26: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'
helpers.c:156:25: runtime error: index -1 out of bounds for type 'RGBTRIPLE [width]'

Мой ввод:

./filter -b stadium.bmp outfile.bmp

Если кому-то нужна дополнительная информация о pset, перейдите на собственную страницу CS50:

https://cs50.harvard.edu/x/2020/psets/4/filter/less/

обновленный код:

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE copy[height][width];
    int count = 0;

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


            if (j - 1 >= 0 & j - 1  <= 255)
            {
                red += image[i][j - 1].rgbtRed;
                green += image[i][j - 1].rgbtGreen;
                blue += image[i][j - 1].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255)
            {
                red += image[i][j + 1].rgbtRed;
                green += image[i][j + 1].rgbtGreen;
                blue += image[i][j + 1].rgbtBlue;
                count++;
            }

            if (j - 1 >= 0 && j - 1  <= 255 && i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i - 1][j - 1].rgbtRed;
                green += image[i - 1][j - 1].rgbtGreen;
                blue += image[i - 1][j - 1].rgbtBlue;
                count++;
            }

            if (i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i - 1][j].rgbtRed;
                green += image[i - 1][j].rgbtGreen;
                blue += image[i - 1][j].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255 && i - 1 >= 0 && i - 1 <= 255)
            {
                red += image[i - 1][j + 1].rgbtRed;
                green += image[i- 1][j + 1].rgbtGreen;
                blue += image[i- 1][j + 1].rgbtBlue;
                count++;
            }

            if (j - 1 >= 0 && j - 1  <= 255 && i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i + 1][j - 1].rgbtRed;
                green += image[i + 1] [j - 1].rgbtGreen;
                blue += image[i + 1][j - 1].rgbtBlue;
                count++;
            }

            if (i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i+ 1][j ].rgbtRed;
                green += image[i+ 1][j].rgbtGreen;
                blue += image[i+ 1][j].rgbtBlue;
                count++;
            }

            if (j + 1 >= 0 && j + 1  <= 255 && i + 1 >= 0 && i + 1 <= 255)
            {
                red += image[i + 1][j + 1].rgbtRed;
                green += image[i+ 1][j + 1].rgbtGreen;
                blue += image[i+ 1][j + 1].rgbtBlue;
                count++;
            }

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

        }

    }

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

обновление 2:


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


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

            int count = 0;

            if (j >= 0 )
            {
                red += image[i][j].rgbtRed;
                green += image[i][j].rgbtGreen;
                blue += image[i][j].rgbtBlue;
                count++;
            }

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

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

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

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

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

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

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

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

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


        }

    }

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

сообщение об ошибке после запуска тестового кода:


:( blur correctly filters middle pixel
    expected "127 140 149\n", not "70 85 95\n"
:( blur correctly filters pixel on edge
    expected "80 95 105\n", not "81 101 65\n"
:( blur correctly filters pixel in corner
    expected "70 85 95\n", not "45 72 71\n"
:( blur correctly filters 3x3 image
    expected "70 85 95\n80 9...", not "49 57 71\n61 6..."
:( blur correctly filters 4x4 image
    expected "70 85 95\n80 9...", not "46 60 79\n85 8..."

1 Ответ

0 голосов
/ 15 апреля 2020

В вашем коде есть разные ошибки.

  1. Недопустимые значения индекса вызваны неправильными условиями доступа к пикселям:

        if (j + 1 >= 0 && j + 1  <= 255 && i - 1 >= 0 && i - 1 <= 255)
        {
            red += image[i][j - 1].rgbtRed;
            green += image[i][j - 1].rgbtGreen;
            blue += image[i][j - 1].rgbtBlue;
            count++;
        }
    

    Условие будет true для j==0, что приведет к доступу к image[i][-1], как указано в сообщении об ошибке.

  2. Вы никогда не сбросите count. Переменная count предназначена для отслеживания количества соседних пикселей, которые были включены в расчет среднего значения. Это должно быть сброшено для каждого пикселя, а не расти бесконечно.

  3. Вы используете целые числа для расчета. Вопрос просит вас применить правильное округление до ближайшего цвета. Это подразумевает использование переменных с плавающей точкой вместо целых чисел, поскольку целочисленное деление всегда округляется вниз.

  4. Вы должны использовать все соседние пиксели. Это означает, что вам нужно использовать смещение -1,0, + 1 внутри строки, а также внутри столбца. Другими словами, вы должны использовать значения индекса [i-1][...], [i][...] и [i+1][...], а также [...][j-1], [...][j] и [...][j+1]. В общей сложности вы должны учитывать 9 пикселей для всех не краевых пикселей. Ваш текущий код использует [i][j - 1] намного чаще, чем любой другой пиксель, что придает ему гораздо больший вес, чем другие пиксели. Некоторые соседи никогда не используются.

  5. Условия принимают фиксированное значение c число 255 для ширины и высоты растрового изображения. Вместо этого следует использовать переменные height и width.

  6. Условия слишком сложные. В каждом условном блоке вы получаете доступ к пикселю, который выключен на 1 в любом направлении. Если вы используете j+1, вам не нужно проверять, меньше ли оно 0. Также, если вы используете i-1, нет необходимости сравнивать с верхней границей. И если вы не используете смещение ([i]), вам вообще не нужно проверять диапазон i, поскольку внешние петли об этом уже позаботятся.

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            double red   = image[i][j].rgbtRed;
            double green = image[i][j].rgbtGreen;
            double blue  = image[i][j].rgbtBlue;
            int count = 1;

            if (j > 0)
            {
                red += image[i][j-1].rgbtRed;
                green += image[i][j-1].rgbtGreen;
                blue += image[i][j-1].rgbtBlue;
                count++;
            }
            ...
            if (i < height-1 && j > 0)
            {
                red += image[i+1][j-1].rgbtRed;
                green += image[i+1][j-1].rgbtGreen;
                blue += image[i+1][j-1].rgbtBlue;
                count++;
            }
Вы уже используете размытые пиксели при расчете. Если вы обновите пиксель image[i][j] новым значением и в следующем шаге вы будете использовать его снова через image[i][j-1], вы получите ложные результаты. Вместо этого используйте копию изображения, чтобы сохранить полученные пиксели.
...