C#图像压缩的预测编码技术

4
我一直在尝试使用哈夫曼压缩技术来减小图像的大小,同时保持图像的无损压缩。但我也读到了可以通过预测编码进一步压缩图像数据来降低熵的方法。
据我所知,在无损JPEG标准中,每个像素都被预测为已经按栅格顺序遇到的相邻4个像素的加权平均值(三个以上方和一个在左边)。例如,试图基于前面的像素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非常多。这在某些情况下会大大降低熵。以下是屏幕截图:
1个回答

3

是的,只需截断即可。这并不重要,因为您存储了差异。它可以降低熵,因为您只存储小值,其中很多将是-1、0或1。顺便说一下,您的片段中有几个偏移量错误。


真的吗?你能指出哪些部分是偏移一的吗?那太好了 :) 另外,谈到-1值,我该如何处理负值?只需让它们循环到255? - joe_coolish
好的,我现在明白了,你避免了边界。是的,让它溢出吧。 - Hans Passant
好的,我快速比较了直方图,我明白你的意思了!我会发布一张图片来展示它的样子。感谢你的解释! - joe_coolish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接