2011-04-11 55 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