Функция размытия для cs50 PSET4, где ошибки? - PullRequest
0 голосов
/ 14 июля 2020

Я застрял в этой функции уже несколько дней. Я смотрел на вопросы других людей, смотрел обучающие видеоролики на YouTube, но не могу понять. Это задание является частью курса CS50 Гарварда (https://cs50.harvard.edu/x/2020/psets/4/filter/less/). Мы будем очень благодарны за любую помощь! Я действительно не хочу go продолжать курс, не понимая, в чем проблема.

//check if pixels are valid
bool valid_pixel(int r, int c, int height, int width)
{
    return r >= 0 && c >= 0 && r < height && c < width;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    //create a copy of the original image
    RGBTRIPLE temp[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            temp[i][j] = image[i][j];
        }
    }

    int red, green, blue, count;
    red = green = blue = count = 0;
    //iterate through rows
    for (int i = 0; i < height; i++)
    {
        //iterate through columns
        for (int j = 0; j < width; j++)
        {
            //move one pixel up to one pixel down in the rows
            for (int r = i - 1; r <= i + 1; r++)
            {
                //move one pixel left to one pixel right in the columns
                for (int c = j - 1; c <= j + 1; c++)
                {
                    //check if they are unvalid pixels
                    if (valid_pixel(r, c, height, width))
                    {
                        //count every valid pixel
                        count ++;
                        //"store" every pixel color
                        red += image[r][c].rgbtRed;
                        green += image[r][c].rgbtGreen;
                        blue += image[r][c].rgbtBlue;
                    }
                }
            }
            //calculate average values
            temp[i][j].rgbtRed = round((float)red / count);
            temp[i][j].rgbtGreen = round((float)green / count);
            temp[i][j].rgbtBlue = round((float)blue / count);
        }
    }

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

1 Ответ

0 голосов
/ 15 июля 2020

Основная проблема заключается в том, что вы забываете сбрасывать переменные red, blue и green (которые вы суммируете) после каждой внешней l oop итерации. Вы должны поместить эту строку внутри основного l oop -

red = green = blue = count = 0;

Кроме того, вы копируете изображение в другое временное изображение и в конце снова копируете это временное изображение в исходное изображение. Это очень неэффективно. Вы не должны сначала копировать пиксели исходного изображения в размытое изображение. Вы можете поместить измененные значения прямо во временный образ. И, наконец, используйте memmove, чтобы одновременно эффективно перемещать целые строки к исходному изображению. (Не забудьте #include <string.h>)

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    
    RGBTRIPLE blurred_img[height][width];
    //iterate through rows
    for (int i = 0; i < height; i++)
    {
        //iterate through columns
        for (int j = 0, red, green, blue, count; j < width; j++)
        {
            // Reset the variables
            red = blue = green = count = 0;
            //move one pixel up to one pixel down in the rows
            for (int r = i - 1; r <= i + 1; r++)
            {
                //move one pixel left to one pixel right in the columns
                for (int c = j - 1; c <= j + 1; c++)
                {
                    //check if they are unvalid pixels
                    if (valid_pixel(r, c, height, width))
                    {
                        //count every valid pixel
                        count++;
                        //"store" every pixel color
                        red += image[r][c].rgbtRed;
                        green += image[r][c].rgbtGreen;
                        blue += image[r][c].rgbtBlue;
                    }
                }
            }
            //calculate average values
            blurred_img[i][j].rgbtRed = round((float)red / count);
            blurred_img[i][j].rgbtGreen = round((float)green / count);
            blurred_img[i][j].rgbtBlue = round((float)blue / count);
        }
    }
    for (int i = 0; i < height; i++)
    {
        // Copy the new image over to the original, row by row
        memmove(image[i], blurred_img[i], sizeof(RGBTRIPLE) * width);
    }
    return;
}

Предполагается, что valid_pixel правильно. Чтобы определить, является ли позиция пикселя допустимой, вы можете просто сделать-

if (k > 0 && k < height && l > -1 && l < width))

Обратите внимание, однако, когда r (строка) недопустима, самое внутреннее l oop (столбец l oop) будет все еще повторяется до c == width, хотя весь этот l oop бесполезен, потому что r недействителен и будет оставаться таким, пока не завершится самый внутренний l oop и не будет увеличиваться r.

Для эффективности вы должны break, если r недействительно -

if (r < 0 || r > height - 1)
{
    break;
}
if (c > -1 && c < width)
{
    //count every valid pixel
    count++;
    //"store" every pixel color
    red += image[r][c].rgbtRed;
    green += image[r][c].rgbtGreen;
    blue += image[r][c].rgbtBlue;
}
...