來手把手教你通過Matlab用兩種方法實現圖像壓縮與解壓(附超詳細代碼),趕緊點贊收藏吧

DCT圖像壓縮

DCT原理介紹

數字圖像處理DCT是數字圖像處理中的一種重要處理手段,被廣泛地用與圖像的壓縮編碼算法中,已有的各種成熟的壓縮標準如JPEG,MPEG,H.26X以及HDTV等都無一例外地採用基於DCT/IDCT的壓縮編碼。

離散餘弦變換(Discrete Cosine Transform) 是一種最主要的正交變換。它將圖像信號從空間域變換到DCT域,保持原始信號的熵和能量不變,卻使得DCT域係數之間的相關性減弱,然後再對DCT域係數進行量化和編碼,以達到壓縮的目的。

DCT將運動補償誤差或原畫面信息塊轉換成代表不同頻率分量的係數集,這有兩個優點
其一,信號常將其能量的大部分集中於頻率域的1個小範圍內,這樣一來,描述不重要的分量只需要很少的比特數;
其二,頻率域分解映射了人類視覺系統的處理過程,並允許後繼的 量化過程滿足其靈敏度的要求。

離散餘弦變換(Discrete Cosine Transform,簡稱DCT變換)是一種與傅立葉變換緊密相關的數學運算。在傅立葉級數展開式中,如果被展開的函數是實偶函數,那麼其傅立葉級數中只包含餘弦項,再將其離散化可導出餘弦變換,因此稱之爲離散餘弦變換。

離散餘弦變換(DCT)是N.Ahmed等人在1974年提出的正交變換方法。它常被認爲是對語音和圖像信號進行變換的最佳方法。爲了工程上實現的需要,國內外許多學者花費了很大精力去尋找或改進離散餘弦變換的快速算法。由於近年來數字信號處理芯片(DSP)的發展,加上專用集成電路設計上的優勢,這就牢固地確立離散餘弦變換(DCT)在目前圖像編碼中的重要地位,成爲H.261、JPEG、MPEG 等國際上公用的編碼標準的重要環節。

在視頻壓縮中,最常用的變換方法是DCT,DCT被認爲是性能接近K-L變換的準最佳變換,變換編碼的主要特點有:
(1)在變換域裏視頻圖像要比空間域裏簡單。
(2)視頻圖像的相關性明顯下降,信號的能量主要集中在少數幾個變換系數上,採用量化和熵編碼可有效地壓縮其數據。
(3)具有較強的抗干擾能力,傳輸過程中的誤碼對圖像質量的影響遠小於預測編碼。通常,對高質量的圖像,DMCP要求信道誤碼率 ,而變換編碼僅要求信道誤碼率 。

DCT等變換有快速算法,能實現實時視頻壓縮。
針對目前採用的幀內編碼加運動補償的視頻壓縮方法的不足, 我們在Westwater 等人提出三維視頻編碼的基礎上, 將三維變換的結構應用於視頻圖像壓縮, 進一步實現了新的視頻圖像序列的編碼方法。

碼率壓縮基於變換編碼和熵值編碼兩種算法。前者用於降低熵值,後者將數據變爲可降低比特數的有效編碼方式。

在MPEG標準中,變換編碼採用的是DCT,變換過程本身雖然並不產生碼率壓縮作用,但是變換後的頻率係數卻非常有利於碼率壓縮。

實際上壓縮數字視頻信號的整個過程分爲塊取樣、DCT、量化、編碼4個主要過程進行-----首先在時間域將原始圖像分成N(水平)×N(垂直)取樣塊,根據需要可選擇4×4、4×8、8×8、8×16、16×16等塊,這些取樣的像素塊代表了原圖像幀各像素的灰度值,其範圍在139-163之間,並依序送入DCT編碼器,以便將取樣塊由時間域轉換爲頻率域的DCT係數塊。DCT系統的轉換分別在每個取樣塊中進行,這些塊中每個取樣是數字化後的值,表示一場中對應像素的視頻信號幅度值。

DCT和它解壓時的反運算的具體算法

  • 當u,v = 0 時,離散餘弦正變換(DCT)後的係數若爲F(0,0)=1,則離散餘弦反變換(IDCT)後的重現函數f(x,y)=1/8,是個常數值,所以將F(0,0)稱爲直流(DC)係數;
  • 當u,v≠0時,正變換後的係數爲F(u,v)=0,則反變換後的重現函數f(x,y)不是常數,此時正變換後的係數F(u,v)爲交流(AC)係數。

詳細實現代碼

function Jpeg
I=imread('lena.jpg');
%該圖片在安裝matlab的目錄中找,原圖爲灰度圖象
I=im2double(I);%圖像存儲類型轉換
T=dctmtx(8);%離散餘弦變換矩陣
B=blkproc(I,[8 8],'P1*x*P2',T,T');
%對原圖像進行DCT變換
mask=[1 1 1 1 0 0 0 0
      1 1 1 0 0 0 0 0
      1 1 0 0 0 0 0 0
      1 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0];
B2=blkproc(B,[8 8],'P1.*x',mask);
%數據壓縮,丟棄右下角高頻數據
I2=blkproc(B2,[8 8],'P1*x*P2',T',T);
%進行DCT反變換,得到壓縮後的圖像
imshow(I)
title('原始圖像')
figure;
imshow(I2)
title('壓縮後的圖像')

結果展示

在這裏插入圖片描述
在這裏插入圖片描述

行程編碼壓縮與解壓

讀入圖像

matlab中利用imread函數讀入圖像,並將其進行灰度化,之後設置爲二值圖像,指明相應的閾值。

I=imread('lena1.jpg'); % 讀入圖像
I1=rgb2gray(I);	% 灰度化
I3=im2bw(I1,0.5); %將原圖轉換爲二值圖像,閾值爲 0.5

圖像轉爲矩陣

I2=I1(:); %將原始圖像寫成一維的數據並設爲 I2
I2length=length(I2); %計算 I2 的長度

X=I3(:); %令 X 爲新建的二值圖像的一維數據組
L=length(X);

行程編碼壓縮

行程編碼(Run-Length Encoding):僅存儲一個像素值以及具有相同顏色的像素數目的圖象數據編碼方式稱爲行程編碼,或稱遊程編碼,常用RLE(Run-Length Encoding)表示。該壓縮編碼技術相當直觀和經濟,運算也相當簡單,因此解壓縮速度很快。RLE壓縮編碼尤其適用於計算機生成的圖形圖像,對減少存儲容量很有效果。

在此方式下每兩個字節組成一個信息單元。第一個字節給出其後面相連的象素的個數。第二個字節給出這些象素使用的顏色索引表中的索引。例如:信息單元03 04,03表示其後的象素個數是3個,04表示這些象素使用的是顏色索引表中的第五項的值。壓縮數據展開後就是04 04 04 .同理04 05 可以展開爲05 05 05 05. 信息單元的第一個字節也可以是00,這種情況下信息單元並不表示數據單元,而是表示一些特殊的含義。這些含義通常由信息單元的第二個字節的值來描述。

給出的數據序列爲:A-A-A-A-A-B-B-C-D

未壓縮前:A-A-A-A-A-B-B-C-D

(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44)

壓縮後:5-A-2-B-1-C-1-D

(0x05-0x41-0x02-0x42-0x01-0x43-0x01-0x44)

j=1;
I4(1)=1;
for z=1:1:(length(X)-1) %行程編碼程序段
    if X(z)==X(z+1)
        
        I4(j)=I4(j)+1;
    else
        data(j)=X(z); % data(j)代表相應的像素數據
        j=j+1;
        I4(j)=1;
    end
end
data(j)=X(length(X)); %最後一個像素數據賦給 data
I4length=length(I4);  %計算行程編碼後的所佔字節數,記爲 I4length
CR=I2length/I4length; %比較壓縮前於壓縮後的大小

行程編碼解壓

l=1;
for m=1:I4length
    for n=1:1:I4(m);
        decode_image1(l)=data(m);
        l=l+1;
    end
end
decode_image=reshape(decode_image1,256,256); %重建二維圖像數組

顯示圖像

h=figure,set(h,'color','white')
x=1:1:length(X);
subplot(131),plot(x,X(x)); title('編碼前圖像數據');%顯示行程編碼之前的圖像數據
y=1:1:I4length ;
subplot(132),plot(y,I4(y)); title('編碼後圖像數據');%顯示編碼後數據信息
u=1:1:length(decode_image1);
subplot(133),plot(u,decode_image1(u));title('解壓後圖像數據'); %查看解壓後的圖像數據
h=figure;
subplot(131);imshow(I);title('原始圖像'); %顯示原圖的二值圖像
subplot(132);imshow(I3);title('原圖的二值圖像'); %顯示原圖的二值圖像
subplot(133),imshow(decode_image);title('解壓恢復後的圖像'); %顯示解壓恢復後的圖像
set(h,'color','white')
disp('壓縮比: ')
disp(CR);
disp('原圖像數據的長度:')
disp(L);
disp('壓縮後圖像數據的長度:')
disp(I4length);
disp('解壓後圖像數據的長度:')
disp(length(decode_image1));

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

完整代碼附錄

close all; clear all; clc;
I=imread('lena1.jpg'); %讀入圖像
I1=rgb2gray(I);
I2=I1(:); %將原始圖像寫成一維的數據並設爲 I2
I2length=length(I2); %計算 I2 的長度
I3=im2bw(I1,0.5); %將原圖轉換爲二值圖像,閾值爲 0.5
%以下程序爲對原圖像進行行程編碼,壓縮
X=I3(:); %令 X 爲新建的二值圖像的一維數據組
L=length(X);
j=1;
I4(1)=1;
for z=1:1:(length(X)-1) %行程編碼程序段
    if X(z)==X(z+1)
        
        I4(j)=I4(j)+1;
    else
        data(j)=X(z); % data(j)代表相應的像素數據
        j=j+1;
        I4(j)=1;
    end
end
data(j)=X(length(X)); %最後一個像素數據賦給 data
I4length=length(I4);  %計算行程編碼後的所佔字節數,記爲 I4length
CR=I2length/I4length; %比較壓縮前於壓縮後的大小
%下面程序是行程編碼解壓
l=1;
for m=1:I4length
    for n=1:1:I4(m);
        decode_image1(l)=data(m);
        l=l+1;
    end
end
decode_image=reshape(decode_image1,256,256); %重建二維圖像數組
h=figure,set(h,'color','white')
x=1:1:length(X);
subplot(131),plot(x,X(x)); title('編碼前圖像數據');%顯示行程編碼之前的圖像數據
y=1:1:I4length ;
subplot(132),plot(y,I4(y)); title('編碼後圖像數據');%顯示編碼後數據信息
u=1:1:length(decode_image1);
subplot(133),plot(u,decode_image1(u));title('解壓後圖像數據'); %查看解壓後的圖像數據
h=figure;
subplot(131);imshow(I);title('原始圖像'); %顯示原圖的二值圖像
subplot(132);imshow(I3);title('原圖的二值圖像'); %顯示原圖的二值圖像
subplot(133),imshow(decode_image);title('解壓恢復後的圖像'); %顯示解壓恢復後的圖像
set(h,'color','white')
disp('壓縮比: ')
disp(CR);
disp('原圖像數據的長度:')
disp(L);
disp('壓縮後圖像數據的長度:')
disp(I4length);
disp('解壓後圖像數據的長度:')
disp(length(decode_image1));

有用的話各位老鐵來個三連擊!!!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章