2011-04-11 54 views
4

我一直在使用霍夫曼压缩图像来减小尺寸,同时保持无损图像,但我也读过,您可以使用预测编码通过减少熵来进一步压缩图像数据。C#预测编码图像压缩

据我所知,在无损JPEG标准中,每个像素被预测为已经按照光栅顺序(上面三个和左边一个)遇到的相邻4个像素的加权平均值。例如,试图预测的像素的值的基础上前述像素,X,向左以及上方的:

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; 
     } 
    } 
} 

我看不出这真的会降低熵?这将如何帮助进一步压缩我的图像,同时仍然无损?

感谢任何启蒙

编辑:

所以与预测编码图像播放后,我注意到,直方图数据显示很多varous像素+ -1年代。在某些情况下,这会减少熵。下面是截图:

enter image description here

回答

3

是的,就截断。没关系,因为你存储的差异。它减少了熵,因为你只存储很小的值,其中很多会是-1,0或1.在你的代码片段中有几个错误的错误。

+0

真的吗?你能指出哪些部件是一个接一个的吗?这将是优秀的:)另外,谈到-1值,我将如何处理负值?只要让他们循环到255? – 2011-04-11 23:16:55

+0

好的,我现在看到它,你正在避开边界。是的,让溢出。 – 2011-04-11 23:22:54

+0

好吧,我对柱状图做了一个快速比较,我看到你在说什么!我会张贴它的样子。谢谢你的解释! – 2011-04-11 23:25:50