Почему эти две функции фильтра не работают соответственно? CS50 - PullRequest
0 голосов
/ 24 апреля 2020

У меня небольшие проблемы с двумя из этих функций. Я не ищу полных ответов, только хочу иметь некоторые указания относительно того, как подойти к этому. У меня проблема с оттенками серого и функцией размытия. это часть проблемы cs50, и я не ищу полных ответов, просто не знаю, где отсюда go. Таким образом, серая шкала состоит в том, чтобы просто преобразовать пиксели в оттенки серого, найдя среднее значение rbg и затем присвоив его, однако при запуске проверки 50, чтобы увидеть, работает ли она, это, кажется, преобразовывает пиксели единичных и простых изображений, но не может обрабатывать больше сложные. результаты приведены ниже:

:) Оттенки серого корректно фильтруют один пиксель со средним целым числом. Тестирование журнала с работающим пикселем (20, 40, 90) ./testing 0 0 ... проверка на вывод "50 50 50 \ n "... :( Оттенки серого правильно фильтруют один пиксель без ожидаемого среднего целого числа" 28 28 28 \ n ", а не" 27 27 27 \ n "Тестирование журнала с работающими пикселями (27, 28, 28) ./ тестирование 0 1 ... проверка вывода "28 28 28 \ n" ...

Ожидаемый результат: 28 28 28 Фактический результат: 27 27 27 :) Оттенки серого оставляют только пиксели, которые уже серые. работает пиксель (50, 50, 50) ./testing 0 2 ... проверка на вывод "50 50 50 \ n" ... :) Оттенки серого правильно фильтруют простое изображение 3x3 Журнал тестирования с образцом изображения 3x3 в первой строке: (255, 0, 0), (255, 0, 0), (255, 0, 0) вторая строка: (0, 255, 0), (0, 255, 0), (0, 0, 255) третья строка: ( 0, 0, 255), (0, 0, 255), (0, 0, 255) работает. / Тестирование 0 3 ... проверка на выход "85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n85 85 85 \ n ". .. :( Оттенки серого правильно фильтруют более сложное изображение 3x3, ожидаемое «20 20 20 \ n50 5 ...», а не «20 20 20 \ n50 5 ...» Журнал тестирования с образцом 3x3 изображения в первой строке: (10, 20, 30), (40, 50, 60), (70, 80, 90) второй ряд: (110, 130, 140), (120, 140, 150), (130, 150, 160) третий ряд: (200, 210, 220), (220, 230, 240), (240, 250, 255) работает. / Тестирование 0 4 ... проверка на выход "20 20 20 \ n50 50 50 \ n80 80 80 \ n127 127 127 \ n137 137 137 \ n147 147 147 \ n210 210 210 \ n230 230 230 \ n248 248 248 \ n "...

Ожидаемый результат: 20 20 20 50 50 50 80 80 80 127 127 127 137 137 137 147 147 147 210 210 210 230 230 230 248 248 248 Фактический результат: 20 20 20 50 50 50 80 80 80 126 126 126 136 136 136 146 146 146 210 210 210 230 230 230 248 248 248 :( Оттенки серого правильно фильтрует ожидаемое изображение 4x4 "20 20 20 \ n50 5 ... ", а не" 20 20 20 \ n50 5 ... "Тестирование журнала с образцом изображения 4х4 в первой строке: (10, 20, 30), (40, 50, 60), (70, 80, 90), (100, 110, 120) второй ряд: (110, 130, 140), (120, 140, 150), (130, 150, 160), (140, 160, 170)-й третий ряд: (195, 204, 213), (205, 214, 223), (225, 234, 243), (245, 254, 253), четвертый ряд: (50, 28, 90), (0, 0, 0), (255, 255, 255), (85, 85, 85) работает. / Тестирование 0 5 ... проверка на выход "20 20 20 \ n50 50 50 \ n80 80 80 \ n110 110 110 \ n127 127 127 \ n137 137 137 \ n147 147 147 \ n157 157 157 \ n204 204 204 \ n214 214 214 \ n234 234 234 \ n251 251 251 \ n56 56 56 \ n0 0 0 \ n255 255 255 \ n85 85 85 \ n "...

Ожидаемый результат: 20 20 20 50 50 50 80 80 80 110 110 110 127 127 127 137 137 137 147 147 147 157 157 157 204 204 204 214 214 214 234 234 234 251 251 251 56 56 56 0 0 0 255 255 255 85 85 85 Фактический объем производства: 20 20 20 50 50 50 80 80 80 110 110 110 126 126 126 136 136 136 146 146 146 156 156 156 204 204 204 214 214 214 234 234 234 250 250 250 56 56 56 0 0 0 255 255 255 85 85 85

Что касается размытия окна, то это размытие окна, которое я должен использовать, поэтому я пытался определить сумму единицы со всеми окружающими предметами и затем получая среднее значение, сначала я попытался присвоить значение союзник с: image[i][j].rbgtRed = round((image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 4), а для сине-зеленого. Но потом понял, что он принимает новые значения и, таким образом, просто сбрасывает все изображение в основном. Тогда я подумал использовать массив для переключения значений, похожих на отражение, и использовал:

    int tmpR[height][width];
    int tmpG[height][width];
    int tmpB[height][width];

тогда он не работал, поэтому работал в подсчете для подсчета единиц и сброса значений массива для ответа. после этого я пытался медленно go пройти через код, но еще не определил фактор. Ниже приведен код.

#include "helpers.h"
#include <math.h>

// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
    int gscale;
    //loop for all pixels in rows
    for (int i = 0; i < height; i++)
    {
        //loop for pixels in columns
        for (int j = 0; j < width; j++)
        {
            //get the average of all the variables
            gscale = round((image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3);

            image[i][j].rgbtRed = gscale;
            image[i][j].rgbtGreen = gscale;
            image[i][j].rgbtBlue = gscale;

        }

    }

    return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
    //set sepia float
    float sRed;
    float sGreen;
    float sBlue;
    // loop through pixels:rows
    for (int i = 0; i <= height; i++)
    {
        // loop through pixels:columns
        for (int j = 0; j < width; j++)
        {
            // change pixels to float
            float r = image[i][j].rgbtRed;
            float g = image[i][j].rgbtGreen;
            float b = image[i][j].rgbtBlue;

            //calculations
            sRed = ((.393 * r) + (.769 * g) + (.189 * b));
            sGreen = ((.349 * r) + (.686 * g) + (.168 * b));
            sBlue = ((.272 * r) + (.534 * g) + (.131 * b));

            //Limits
            if (sRed > 255)
            {
                sRed = 255;
            }
            if (sGreen > 255)
            {
                sGreen = 255;
            }
            if (sBlue > 255)
            {
                sBlue = 255;
            }

            //Reset pixels
            image[i][j].rgbtRed = round(sRed);
            image[i][j].rgbtGreen = round(sGreen);
            image[i][j].rgbtBlue = round(sBlue);
        }
    }
    return;
}

// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{

    for (int i = 0; i <= height; i++)
    {
        for (int j = 0; j < width / 2; j++)
        {

            //temp variables
            int tmpR = image[i][j].rgbtRed;
            int tmpG = image[i][j].rgbtGreen;
            int tmpB = image[i][j].rgbtBlue;
            // opposite end is = width - unit
            //Swap
            image[i][j].rgbtRed = image[i][(width - 1) - j].rgbtRed;
            image[i][j].rgbtGreen = image[i][(width - 1) - j].rgbtGreen;
            image[i][j].rgbtBlue = image[i][(width - 1) - j].rgbtBlue;

            image[i][(width - 1) - j].rgbtRed = tmpR;
            image[i][(width - 1) - j].rgbtGreen = tmpG;
            image[i][(width - 1) - j].rgbtBlue = tmpB;

        }
    }
    return;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    //count total pixels
    int counth = 0;
    int countw = 0;
    for (int a = 0; a <= height; a++)
    {
        for (int b = 0; b < width; b++)
        {
            countw++;
        }
        counth++;
    }
    //Temp arrays
    int tmpR[counth][countw];
    int tmpG[counth][countw];
    int tmpB[counth][countw];

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


            if(i == 0 && j == 0)
            {
                //build box for calculation for left top of box
                tmpR[i][j] = round((image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 4);
                tmpG[i][j] = round((image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 4);

            }
            else if (i == 0 && j == (width - 1))
            {
                //build box for calculation for right top corner of box
                tmpR[i][j] = round((image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed) / 4);
                tmpG[i][j] = round((image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue) / 4);

            }
            else if (i == height  && j == 0)
            {
                //build box for calculation for left bottom corner of box
                tmpR[i][j] = round((image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed) / 4);
                tmpG[i][j] = round((image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue) / 4);
            ;

            }
            else if (i == height && j ==  (width - 1))
            {
                //build box for calculation for right bottom corner of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed) / 4);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue) / 4);

            }
            else if (i == 0)
            {
                //build box for calculation for top of box
                tmpR[i][j] = round((image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 6);

            }
            else if (i == (height - 1))
            {
                //build box for calculation for bottom of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue) / 6);

            }
            else if (j == 0)
            {
                //build box for calculation for left of box
                tmpR[i][j] = round((image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 6);

            }
            else if (j == (width - 1))
            {
                //build box for calculation for right of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue) / 6);

            }
            else
            {
                //build box for calculation for center digits
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 9);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 9);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 9);

            }
        }
    }

    // Reset new values
    for (int i = 0; i <= height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j].rgbtRed = tmpR[i][j];
            image[i][j].rgbtGreen = tmpG[i][j];
            image[i][j].rgbtBlue = tmpB[i][j];
        }
    }
    return;
}

Пожалуйста, еще раз, я ищу больше подсказок, что все, что я знаю, код не настолько элегантен, как это может быть, однако я учусь, и это только мой 5-й письменный код, если вы Я мог бы посоветовать, как отказаться, или, если мой алгоритм имеет недостатки, я был бы чрезвычайно благодарен, а также совет о том, как лучше продумать код.

Но прежде всего я хочу понять, почему это не работает, и как его улучшить.

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Для gs-задачи достаточно поменять позиции. Нет необходимости прикасаться к значениям.

Размытость в настоящее время сводит меня с ума. Посмотрим, будет ли лучше после обеда: -D

Greetz

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

Для проблемы с оттенками серого

Если мы внимательно прочитаем вашу ошибку;

:( Оттенки серого правильно фильтруют один пиксель без ожидаемого среднего целого числа "28 28 28 \ n ", а не" 27 27 27 \ n ".

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

Например, 2/3 приведет к 0. round(0) => 0.

Если вы сделаете 2/3.0 = 0.6666.. (двойная точность), round(0.6666..) будет 1.

Сначала вычислите все в double, затем округлите в integer на последнем этапе.

...