JPEG压缩matlab实现
請注意:本文代碼參考用MATLAB實現JPEG壓縮過程 原作者為新浪博客:dzh_漫漫修行路
文章目錄
- JPEG原理流程
- 源代碼
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 6112 12 14 19 26 58 60 5514 13 16 24 40 57 69 5614 17 22 29 51 87 80 6218 22 37 56 68 109 103 7724 35 55 64 81 104 113 9249 64 78 87 103 121 120 10172 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];源代碼
請注意:源代碼包括三個m文件,請將它們放在同一文件夾下,并且運行JPEGEncodeDecode.m文件進行Jpeg壓縮的試驗。
JPEGEncodeDecode.m文件
Dct_Quantize.m文件
Inverse_Quantize_Dct.m文件
下面分別給出3個m文件。
JPEGEncodeDecode.m文件
function JPEGEncodeDecodeimg=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_expandimg_ycbcr(i,:,:)=img_ycbcr(row,:,:);endendcol_expand=ceil(col/16)*16; %列數上取整if mod(col,16)~=0 %列數不是16的倍數,用最后一列進行擴展for j=col:col_expandimg_ycbcr(:,j,:)=img_ycbcr(:,col,:);endend%對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/2for 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)); endendfor i=1:row_expand/2for 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)); endend%分別對三種顏色分量進行編碼Y_Table=[16 11 10 16 24 40 51 6112 12 14 19 26 58 60 5514 13 16 24 40 57 69 5614 17 22 29 51 87 80 6218 22 37 56 68 109 103 7724 35 55 64 81 104 113 9249 64 78 87 103 121 120 10172 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.5和3之間,越小質量越好文件越大%對三個通道分別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);%對三個通道分別反量化和反DCTY_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/2for j=1:col_expand/2YCbCr_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);endendI_in=ycbcr2rgb(YCbCr_in);I_in(row+1:row_expand,:,:)=[];%去掉擴展的行I_in(:,col+1:col_expand,:)=[];%去掉擴展的列subplot(122);imshow(I_in);title('重構后的圖片');endDct_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變換,得變換系數矩陣CoefI=blkproc(I,[8 8],'dct2(x)');Qua_Matrix=Qua_Factor.*Qua_Table; %量化矩陣I=blkproc(I,[8 8],'round(x./P1)',Qua_Matrix); %量化,四舍五入Matrix=I; %得到量化后的矩陣endInverse_Quantize_Dct.m文件
function [ Matrix ] = Inverse_Quantize_Dct( I,Qua_Factor,Qua_Table )%UNTITLED3 Summary of this function goes here% Detailed explanation goes hereQua_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:rowfor j=1:columnif I(i,j)>255I(i,j)=255;elseif I(i,j)<0I(i,j)=0;endendendMatrix=I; %反量化和反Dct后的矩陣end其中一個函數解釋
函數blkproc會顯示不推薦使用,但是運行時并不會報錯
B = blkproc(A,[M N],FUN) processes the image A by applying the functionFUN to each distinct M-by-N block of A, padding A with zeros ifnecessary. FUN is a FUNCTION_HANDLE that accepts an M-by-N matrix, X,and returns a matrix, vector, or scalar Y:總結
以上是生活随笔為你收集整理的JPEG压缩matlab实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 窝小芽推荐的一顿饭量是多少,如何判断多了
- 下一篇: VS2019中配置opencv4.3.0