1. 程式人生 > >matlab實現jpeg (ycbc4:2:0取樣壓縮 + 量化表ycbc量化壓縮)和(ycbc4:4:4取樣 + 量化表ycbc量化壓縮)

matlab實現jpeg (ycbc4:2:0取樣壓縮 + 量化表ycbc量化壓縮)和(ycbc4:4:4取樣 + 量化表ycbc量化壓縮)

如果對ycbcr取樣不太瞭解的同學,warp gate:https://blog.csdn.net/xueyushenzhou/article/details/40817949

簡單的說,4:2:0就是第一行為y:cb=4:2,沒有cr分量,那麼第二行就是y:cr=4:2,沒有cb分量。以後每一行一直這樣迴圈。

%ycbc4:2:0取樣壓縮 + 量化表ycbc量化壓縮
 
clear all;
f=imread('lena.tif');
img_ycbcr=rgb2ycbcr(f)
[row,col,~]=size(img_ycbcr);
 
%對Y,Cb,Cr分量進行4:2:0取樣
Y(:,:,1)=img_ycbcr(:,:,1);  %Y分量
for i=1:2:row-1
    for j=1:2:col-1 
        Cb((i+1)/2,(j+1)/2)=double(img_ycbcr(i,j,2)); 
    end
end
 
for i=2:2:row
    for j=1:2:col-1 
        Cr(i/2,(j+1)/2)=double(img_ycbcr(i,j,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 ];%色差量化表
 
 
%對三個通道分別DCT和量化
Y_dct_q=Dct_Quantize(Y,Y_Table);
Cb_dct_q=Dct_Quantize(Cb,CbCr_Table);
Cr_dct_q=Dct_Quantize(Cr,CbCr_Table);
 
%對三個通道分別反量化和反DCT
Y_in_q_dct=Inverse_Quantize_Dct(Y_dct_q,Y_Table);
Cb_in_q_dct=Inverse_Quantize_Dct(Cb_dct_q,CbCr_Table);
Cr_in_q_dct=Inverse_Quantize_Dct(Cr_dct_q,CbCr_Table);
 
%恢復出YCBCR影象
YCbCr_in(:,:,1)=Y_in_q_dct;
for i=1:row/2
    for j=1:col/2
        YCbCr_in(2*i-1,2*j-1,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-1,2*j,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,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,3)=Cr_in_q_dct(i,j); 
    end
end
image=ycbcr2rgb(YCbCr_in);
MAX=255;
MES=sum(sum((f-image).^2))/(row*col);     %均方差
PSNR=20*log10(MAX/sqrt(MES));             %峰值信噪比
subplot(121),imshow(f);title('原圖');
subplot(122),imshow(image);title({'重構後圖片';'rgb三通道PSNR為';num2str(PSNR)});
 
 
%ycbc4:4:4取樣 + 量化表ycbc量化壓縮

clear all;
f=imread('lena.tif');
img_ycbcr=rgb2ycbcr(f)
[row,col,~]=size(img_ycbcr); 


Y=img_ycbcr(:,:,1);               %Y分量
Cb=img_ycbcr(:,:,2);
Cr=img_ycbcr(:,:,3);
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];%色差量化表

%對三個通道分別DCT和量化
Y_dct_q=Dct_Quantize(Y,Y_Table);
Cb_dct_q=Dct_Quantize(Cb,CbCr_Table);
Cr_dct_q=Dct_Quantize(Cr,CbCr_Table); 

%對三個通道分別反量化和反DCT
Y_in_q_dct=Inverse_Quantize_Dct(Y_dct_q,Y_Table);
Cb_in_q_dct=Inverse_Quantize_Dct(Cb_dct_q,CbCr_Table);
Cr_in_q_dct=Inverse_Quantize_Dct(Cr_dct_q,CbCr_Table);

%恢復出YCBCR影象
YCbCr_in(:,:,1)=Y_in_q_dct;
YCbCr_in(:,:,2)=Cb_in_q_dct;
YCbCr_in(:,:,3)=Cr_in_q_dct;

I=ycbcr2rgb(YCbCr_in);
MAX=255;
MES=sum(sum((I-f).^2))/(row*col);     %均方差
PSNR=20*log10(MAX/sqrt(MES));             %峰值信噪比
subplot(121),imshow(f);title('原圖');
subplot(122),imshow(I);title({'重構後圖片';'rgb三通道PSNR為';num2str(PSNR)});
 

DCT和IDCT函式

function [Matrix]=Dct_Quantize(I,Qua_Table)

I=double(I)-128;   %層次移動128個灰度級
I=blkproc(I,[8 8],'dct2(x)');      %x就是每一個分成的8*8大小的塊
Qua_Matrix=Qua_Table;              %量化矩陣
I=blkproc(I,[8 8],'fix(x./P1)',Qua_Matrix);  %量化,四捨五入
Matrix=I;          %得到量化後的矩陣


function [ Matrix ] = Inverse_Quantize_Dct(I,Qua_Table)
Qua_Matrix=Qua_Table;     %反量化矩陣
I=blkproc(I,[8 8],'x.*P1',Qua_Matrix);%反量化,四捨五入
I=blkproc(I,[8 8],'idct2(x)');  
I=uint8(I+128);
I(I>255)=255;
I(I<0)=0;
Matrix=I;       %反量化和反Dct後的矩陣

結果: