C # прогнозирующее кодирование для сжатия изображений - PullRequest
4 голосов
/ 12 апреля 2011

Я играл с Huffman Compression на изображениях, чтобы уменьшить их размер, сохраняя при этом изображение без потерь, но я также читал, что вы можете использовать интеллектуальное кодирование для дальнейшего сжатия данных изображения путем уменьшения энтропии.

ОтНасколько я понимаю, в стандарте JPEG без потерь каждый пиксель прогнозируется как средневзвешенное значение смежных 4 пикселей, уже встречающихся в растровом порядке (три сверху и один слева).например, попытка предсказать значение пикселя a на основе предыдущих пикселей x слева и выше a:

x x x
x a 

Затем вычислить и закодировать остаток (разность между предсказанным и фактическим значением).

Но что я не получаю, так это то, что если средние 4 соседних пикселя не кратны 4, вы бы получили правильную дробь?Следует ли игнорировать эту дробь?Если да, то будет ли правильное кодирование 8-битного изображения (сохраненного в byte[]) примерно таким:

public static void Encode(byte[] buffer, int width, int height)
{
    var tempBuff = new byte[buffer.Length];

    for (int i = 0; i < buffer.Length; i++)
    {
        tempBuff[i] = buffer[i];
    }

    for (int i = 1; i < height; i++)
    {
        for (int j = 1; j < width - 1; j++)
        {
            int offsetUp = ((i - 1) * width) + (j - 1);
            int offset = (i * width) + (j - 1);

            int a = tempBuff[offsetUp];
            int b = tempBuff[offsetUp + 1];
            int c = tempBuff[offsetUp + 2];
            int d = tempBuff[offset];
            int pixel = tempBuff[offset + 1];

            var ave = (a + b + c + d) / 4;
            var val = (byte)(ave - pixel);
            buffer[offset + 1] = val;
        }
    }
}

public static void Decode(byte[] buffer, int width, int height)
{
    for (int i = 1; i < height; i++)
    {
        for (int j = 1; j < width - 1; j++)
        {
            int offsetUp = ((i - 1) * width) + (j - 1);
            int offset = (i * width) + (j - 1);

            int a = buffer[offsetUp];
            int b = buffer[offsetUp + 1];
            int c = buffer[offsetUp + 2];
            int d = buffer[offset];
            int pixel = buffer[offset + 1];

            var ave = (a + b + c + d) / 4;
            var val = (byte)(ave - pixel);
            buffer[offset + 1] = val;
        }
    }
}

Я не понимаю, как это действительно уменьшит энтропию?Как это поможет сжимать мои изображения, оставаясь без потерь?

Спасибо за просветление

РЕДАКТИРОВАТЬ:

Итак, поиграв с изображениями с прогнозирующим кодированием, я заметил, чтоДанные гистограммы показывают много + -1 различных пикселей.В некоторых случаях это немного снижает энтропию.Вот скриншот:

enter image description here

1 Ответ

3 голосов
/ 12 апреля 2011

Да, просто обрезать. Не имеет значения, потому что вы храните разницу. Это уменьшает энтропию, потому что вы храните только небольшие значения, многие из них будут -1, 0 или 1. В вашем фрагменте есть пара ошибок, не связанных с одним.

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