圖像壓縮編解碼實驗(DCT編碼+量化+熵編碼(哈夫曼編碼))【MATLAB】


課程要求

Assignment IV Transform + Quantization + Entropy Coding

Input: an intra-frame or a residue picture after motion compensation.

Task: Code the input picture into a bitstream  and decode the picture from the generated bitstream.

Specifications: Implement a transform-based codec, consisting transform, quantization, and entropy coding.  The block size can be 8x8, 16x16, or other reasonable sizes. As in most existing image/video codecs, you can use 2D DCT. A simple uniform quantizer could be used for verification purpose.  For the entropy coding, you can use either Huffman coding or arithmetic coding 

README

運行main函數,注意main函數用到了下面的Normalize函數
指定待處理的圖片,依次對圖片進行一下變換:
一、灰度化
二、8 * 8 DCT變換(這一步r)如果加上一個掩模可以去除圖片中人眼不敏感的高頻分量,從而進一步壓縮圖片
三、量化處理(采用JPEG亮度量化表,將DCT舉證除以量化碼表),由於量化后有取整操作,因此是有損壓縮圖片
四、Huffman編碼,編碼得到的比特流序列比原序列更加短小,進一步提高傳輸效率
五、發送方比特流序列傳輸(將上一步得到的比特流進行傳輸)
%中間對比了直接傳輸圖片的比特流長度和經過壓縮變換得到的比特流長度
六、接收方接收比特流序列
七、解碼,是Huffman編碼的逆過程,得到量化后的序列
八、反量化處理,是第三步的逆過程,將量化后的矩陣乘以量化碼表
九、反DCT變換得到圖片

main函數:

 1 clc;clear;
 2   
 3   %采用JPEG亮度量化表
 4 Q =[16 11 10 16  24  40  51  61
 5     12 12 14 19  26  58  60  55
 6     14 13 16 24  40  57  69  56
 7     14 17 22 29  51  87  80  62
 8     18 22 37 56  68 109 103  77
 9     24 35 55 64  81 104 113  92
10     49 64 78 87 103 121 120 101
11     72 92 95 98 112 100 103 99];
12 
13 X = 8;%分塊大小
14 
15 I=imread('cameraman.jpg');%讀取圖像
16 gray_img = rgb2gray(I);%灰度化
17 
18 
19 I_DCT = blkproc(gray_img,[X X],'dct2');%對圖像進行DCT變換,
20 
21 Iq = round(blkproc(I_DCT,[X X],'x./P1',Q));%量化處理
22 
23 Iq = Iq + 120;%量化處理之后,序列的symbol取-120到+120之間,為了方便編碼,將其平移到0-255的區間
24 
25 %哈夫曼編碼
26 [M,N] = size(Iq);
27 I1 = Iq(:);
28 P = zeros(1,256);
29 for i = 0:255
30     P(i+1) = length(find(I1 == i))/(M*N);
31 end
32 k = 0:255;
33 dict = huffmandict(k,P); %生成字典
34 enco = huffmanenco(I1,dict); %編碼
35 %bitstream傳輸
36 
37         %計算編碼長度,計算壓縮率
38         binaryComp = de2bi(enco);
39         encodedLen = numel(binaryComp);
40         imgLen = numel(de2bi(I1));
41         disp(strcat(['編碼后傳輸的比特流長度為' num2str(encodedLen)]))
42         disp(strcat(['原圖片二進制編碼比特長度為' num2str(imgLen)]))
43         disp(strcat(['壓縮率為' num2str(100*(imgLen-encodedLen)/imgLen) '%']))
44 
45 %bitstream接收
46 %哈夫曼解碼
47 deco = huffmandeco(enco,dict);
48 Idq = col2im(deco,[M,N],[M,N],'distinct')-120; %把向量重新轉換成圖像塊,記得要把圖像平移回去原來的區間;
49 
50 
51 I_rq =  round(blkproc(Idq,[X X],'x.*P1',Q));%反量化
52 
53 I_rDCT = round(blkproc(I_rq,[X X],'idct2'));%對圖像進行DCT反變換
54 
55 I_rDCT = Normalize(I_rDCT);%歸一化到0-255區間
56 
57 
58 
59 figure
60 subplot(1,2,1)
61 imshow(gray_img);
62 title('原圖')
63 
64 
65 subplot(1,2,2)
66 %在matlab處理完數據好,我們希望顯示或者imwrite寫入圖片時候,需要注意。如果直接對double之間的數據矩陣I運行imshow(I),
67 %我們會發現有時候顯示的是一個白色的圖像。 這是因為imshow()顯示圖像時對double型是認為在0~1范圍內,即大於1時都是顯示為白色,
68 %而imshow顯示uint8型時是0~255范圍。所以對double類型的圖像顯示的時候,要么歸一化到0~1之間,
69 %要么將double類型的0~255數據轉為uint8類型
70 imshow(I_rDCT/255);
71 title('經壓縮傳輸后解壓的圖像')
72 
73 
74   

Normalize函數:

1 function OutImg = Normalize(InImg)
2 ymax=255;ymin=0;
3 xmax = max(max(InImg)); %求得InImg中的最大值
4 xmin = min(min(InImg)); %求得InImg中的最小值
5 OutImg = round((ymax-ymin)*(InImg-xmin)/(xmax-xmin) + ymin); %歸一化並取整
6 end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM