Размытие изображения в пиксель за пикселем - особые случаи - PullRequest
1 голос
/ 09 октября 2019

Я работаю над программой, которая немного размывает изображение в c.

Зная, что мне нужны средние значения и значения rgb для 8 окружающих пикселей и выбранного пикселя, чтобы изменить цвет этого пикселя, я добавил их вместе и взял среднее значение.

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

Я планирую скопировать tempimage обратно в image в третьем цикле for в конце.

Структура RGBTRIPLE содержит значения rgb для пикселя.

    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;

Теперь моя проблема связана с особыми случаями, такими как края изображения или пиксели на стороне.

Как получить значения окружающих пикселей, если выбранный пиксель не окружен 9 пикселями?

Вот мой код:

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // copy all values to temporary image
    RGBTRIPLE tempimage[height][width];
    int avgRed = 0;
    int avgGreen = 0;
    int avgBlue = 0;
    //copy pixels to temp image
    for ( int x = 0; x < height; x++)
    {
        for (int y = 0; y < width; y++)
        {
            tempimage[x][y] = image[x][y];
        }
    }
    //get average of surrounding pixels
    for ( int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            //TODO: edge check
            //surrounding pixels
            avgRed = round(((float)(image[i][j].rgbtRed
            + image[i][j - 1].rgbtRed + image[i][j + 1].rgbtRed
            + image[i - 1][j].rgbtRed + image[i - 1][j - 1].rgbtRed
            + image[i - 1][j + 1].rgbtRed + image[i + 1][j].rgbtRed
            + image[i + 1][j - 1].rgbtRed + image[i + 1][j + 1].rgbtRed)) / 9);

            avgGreen = round(((float)(image[i][j].rgbtGreen
            + image[i][j - 1].rgbtGreen + image[i][j + 1].rgbtGreen
            + image[i - 1][j].rgbtGreen + image[i - 1][j - 1].rgbtGreen
            + image[i - 1][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen
            + image[i + 1][j - 1].rgbtGreen + image[i + 1][j + 1].rgbtGreen)) / 9);

            avgBlue = round(((float)(image[i][j].rgbtBlue
            + image[i][j - 1].rgbtBlue + image[i][j + 1].rgbtBlue
            + image[i - 1][j].rgbtBlue + image[i - 1][j - 1].rgbtBlue
            + image[i - 1][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue
            + image[i + 1][j - 1].rgbtBlue + image[i + 1][j + 1].rgbtBlue)) / 9);


            tempimage[i][j].rgbtRed = avgRed;
            tempimage[i][j].rgbtGreen = avgGreen;
            tempimage[i][j].rgbtBlue = avgBlue;

        }
    }

    //TODO: for loop to copy tempimage back to image here
    return;
}

1 Ответ

0 голосов
/ 09 октября 2019

Существуют различные способы обработки «крайних» случаев в алгоритме, подобном вашему. В приведенном ниже коде используется текущий «ряд» или «столбец» (вместо этого выше / ниже или слева / справа от него), если он находится на соответствующем ребре:

for ( int i = 0; i < height; i++)
{
    // Edge check (A for 'above' index and B for 'below':
    int A = i - 1; if (i < 0) i = 0;
    int B = i + 1; if (i > height - 1) i = height - 1;
    for (int j = 0; j < width; j++)
    {
        // Edge check (L = 'left of', R = 'right of'):
        int L = j - 1; if (j < 0) j = 0;
        int R = j + 1; if (j > width - 1) j = width - 1;
        // Then change all your 'i-1'|'i+i'|'j-i'|j+1' indexes to A|B|L|R:
        avgRed = round(((float)(image[i][j].rgbtRed
        + image[i][L].rgbtRed + image[i][R].rgbtRed
        + image[A][j].rgbtRed + image[A][L].rgbtRed
        + image[A][R].rgbtRed + image[B][j].rgbtRed
        + image[B][L].rgbtRed + image[B][R].rgbtRed)) / 9);
        // ... and similarly for green and blue ...

Кстати, я заметил, что у вас естьиндексы пикселей в виде изображения [столбец] [строка] (= порядок столбцов ). Обычно, C и C++ 2D-массивы определяются наоборот, как image [row] [column] (= row-major order);однако, если вы уверены, что это то, что у вас есть, то нет проблем!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...