JPEG壓縮matlab實現

請注意:本文代碼參考用MATLAB實現JPEG壓縮過程 原作者爲新浪博客:dzh_漫漫修行路

本文是一個代碼的搬移,其他知識爲學習和補充,如有侵權,請聯繫作者刪除。

JPEG原理流程
1.色彩空間轉換及相應預處理

在進行JPEG 壓縮之前,我們先將圖像由rgb 顏色空間轉換成YCbCr 空間。然後,我們對圖像進行擴展,以保證圖像的行列都是8 的倍數。

2.色度抽樣
在YCbCr 模型中,Cb 通道和Cr 通道中所包含的信息量遠遠少於Y 通道中包含的信息量,同時,人眼對色彩的敏感程度有限,因此,JPEG 的壓縮算法主要對Cb 和Cr 通道中的數據進行縮減取樣,取樣的比例可以是4:4:4(無縮減取樣)、4:2:2(在水平方向2 的倍數中取樣)和4:2:0(在水平方向和垂直方向的2 的倍數中取樣),其中,以4:2:0 最爲常見。

3.圖像分塊並進行DCT 變換
將顏色空間轉換後的圖像進行8*8 的分塊,然後對每一塊進行DCT 變換。注意,在dct 變換之前,先將每個像素值減去128(直流電平下移)。

4.對三個通道分別量化
所謂量化就是用像素值÷量化表對應值所得的結果(四捨五入)。由於量化表左上角的值較小,右上角的值較大,這樣就起到了保持低頻分量,抑制高頻分量的目的。JPEG使用的顏色是YCrCb 格式。我們提到過,Y 分量代表了亮度信息,CrCb 分量代表了色差信息。相比而言,Y 分量更重要一些。我們可以對Y 採用細量化,對CrCb 採用粗量化,可進一步提高壓縮比。所以上面所說的量化表通常有兩張,一張是針對Y 的;一張是針對CrCb 的。通過量化可以達到通低頻減高頻的效果。

5.反量化和反DCT
這個過程就是量化和DCT 的逆過程。

6.恢復出YCBCR 圖像並去掉擴展的行和列
這一步驟後便可得到壓縮後又恢復的圖像。

下面給出三個.m文件,如原作者之言,運行JPEGEncodeDecode.m的確能夠運行

暫時給出運行結果
在這裏插入圖片描述

亮度量化表

%亮度量化表
Y_Table=[16 11  10  16 24  40  51 61

   12  12  14 19  26  58 60  55

   14  13  16 24  40  57 69  56

   14  17  22 29  51  87 80  62

   18  22  37 56  68 109 103 77

   24  35  55 64  81 104 113 92

   49  64  78  87 103 121 120 101

   72  92  95  98 112 100 103  99];

色差量化表

%色差量化表
CbCr_Table=[17, 18, 24, 47, 99, 99, 99, 99;

   18, 21, 26, 66, 99, 99, 99, 99;

   24, 26, 56, 99, 99, 99, 99, 99;

   47, 66, 99 ,99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

    99, 99, 99, 99, 99, 99, 99, 99];

請注意:本文代碼參考用MATLAB實現JPEG壓縮過程 原作者爲新浪博客:dzh_漫漫修行路

本文是一個代碼的搬移,其他知識爲學習和補充,如有侵權,請聯繫作者刪除。

JPEGEncodeDecode.m文件

function JPEGEncodeDecode

img=imread('lena.jpg');

subplot(121);imshow(img);title('原圖');         %顯示原圖

img_ycbcr = rgb2ycbcr(img);            % rgb->yuv轉換

[row,col,~]=size(img_ycbcr);      % 取出行列數,~表示3個通道算1%對圖像進行擴展

row_expand=ceil(row/16)*16;       %行數上取整再乘16,及擴展成16的倍數

if mod(row,16)~=0           %行數不是16的倍數,用最後一行進行擴展

   for i=row:row_expand

       img_ycbcr(i,:,:)=img_ycbcr(row,:,:);

   end

end

col_expand=ceil(col/16)*16; %列數上取整

if mod(col,16)~=0        %列數不是16的倍數,用最後一列進行擴展

   for j=col:col_expand

       img_ycbcr(:,j,:)=img_ycbcr(:,col,:);

   end

end

 
%對Y,Cb,Cr分量進行4:2:0採樣

Y=img_ycbcr(:,:,1);                   %Y分量

Cb=zeros(row_expand/2,col_expand/2);       %Cb分量

Cr=zeros(row_expand/2,col_expand/2);       %Cr分量

for i=1:row_expand/2

    for j=1:2:col_expand/2-1         %奇數列

       Cb(i,j)=double(img_ycbcr(i*2-1,j*2-1,2));     

       Cr(i,j)=double(img_ycbcr(i*2-1,j*2+1,3));     

   end

end

for i=1:row_expand/2

    for j=2:2:col_expand/2           %偶數列

       Cb(i,j)=double(img_ycbcr(i*2-1,j*2-2,2));     

       Cr(i,j)=double(img_ycbcr(i*2-1,j*2,3));     

   end

end


%分別對三種顏色分量進行編碼

Y_Table=[16 11  10  16 24  40  51 61

   12  12  14 19  26  58 60  55

   14  13  16 24  40  57 69  56

   14  17  22 29  51  87 80  62

   18  22  37 56  68 109 103 77

   24  35  55 64  81 104 113 92

   49  64  78  87 103 121 120 101

   72  92  95  98 112 100 103  99];%亮度量化表

CbCr_Table=[17, 18, 24, 47, 99, 99, 99, 99;

   18, 21, 26, 66, 99, 99, 99, 99;

   24, 26, 56, 99, 99, 99, 99, 99;

   47, 66, 99 ,99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

   99, 99, 99, 99, 99, 99, 99, 99;

    99, 99, 99, 99, 99, 99, 99, 99];%色差量化表


Qua_Factor=0.5;%量化因子,最小爲0.01,最大爲255,建議在0.53之間,越小質量越好文件越大

%對三個通道分別DCT和量化

Y_dct_q=Dct_Quantize(Y,Qua_Factor,Y_Table);

Cb_dct_q=Dct_Quantize(Cb,Qua_Factor,CbCr_Table);

Cr_dct_q=Dct_Quantize(Cr,Qua_Factor,CbCr_Table);


%對三個通道分別反量化和反DCT

Y_in_q_dct=Inverse_Quantize_Dct(Y_dct_q,Qua_Factor,Y_Table);

Cb_in_q_dct=Inverse_Quantize_Dct(Cb_dct_q,Qua_Factor,CbCr_Table);

Cr_in_q_dct=Inverse_Quantize_Dct(Cr_dct_q,Qua_Factor,CbCr_Table);


%恢復出YCBCR圖像

YCbCr_in(:,:,1)=Y_in_q_dct;

for i=1:row_expand/2

   for j=1:col_expand/2

       YCbCr_in(2*i-1,2*j-1,2)=Cb_in_q_dct(i,j);

       YCbCr_in(2*i-1,2*j,2)=Cb_in_q_dct(i,j);

       YCbCr_in(2*i,2*j-1,2)=Cb_in_q_dct(i,j);

       YCbCr_in(2*i,2*j,2)=Cb_in_q_dct(i,j);

       
       YCbCr_in(2*i-1,2*j-1,3)=Cr_in_q_dct(i,j);

       YCbCr_in(2*i-1,2*j,3)=Cr_in_q_dct(i,j);

       YCbCr_in(2*i,2*j-1,3)=Cr_in_q_dct(i,j);

       YCbCr_in(2*i,2*j,3)=Cr_in_q_dct(i,j);

   end

end

I_in=ycbcr2rgb(YCbCr_in);

I_in(row+1:row_expand,:,:)=[];%去掉擴展的行

I_in(:,col+1:col_expand,:)=[];%去掉擴展的列

subplot(122);imshow(I_in);title('重構後的圖片');

end

Dct_Quantize.m文件

function [Matrix]=Dct_Quantize(I,Qua_Factor,Qua_Table)
%Dct量化
%I:
%Qua_Factor:
%Qua_Table
I=double(I)-128;  %層次移動128個灰度級

%t2變換:把ImageSub分成8*8像素塊,分別進行dct2變換,得變換系數矩陣Coef

I=blkproc(I,[8 8],'dct2(x)');

Qua_Matrix=Qua_Factor.*Qua_Table;             %量化矩陣

I=blkproc(I,[8 8],'round(x./P1)',Qua_Matrix); %量化,四捨五入

Matrix=I;         %得到量化後的矩陣

end

Inverse_Quantize_Dct.m文件

function [ Matrix ] = Inverse_Quantize_Dct( I,Qua_Factor,Qua_Table )

%UNTITLED3 Summary of this function goes here

%   Detailed explanation goes here

Qua_Matrix=Qua_Factor.*Qua_Table;    %反量化矩陣

I=blkproc(I,[8 8],'x.*P1',Qua_Matrix);%反量化,四捨五入

[row,column]=size(I);

I=blkproc(I,[8 8],'idct2(x)');  %T反變換

I=uint8(I+128);

for i=1:row

   for j=1:column

       if I(i,j)>255

           I(i,j)=255;

       elseif I(i,j)<0

           I(i,j)=0;

       end

   end

end

Matrix=I;      %反量化和反Dct後的矩陣

end

其中一個函數解釋

函數blkproc會顯示不推薦使用,但是運行時並不會報錯

 B = blkproc(A,[M N],FUN) processes the image A by applying the function
    FUN to each distinct M-by-N block of A, padding A with zeros if
    necessary.  FUN is a FUNCTION_HANDLE that accepts an M-by-N matrix, X,
    and returns a matrix, vector, or scalar Y:
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章