根據相關參考資料說明,圖像編碼解碼的大緻結構框圖如下所示:
本系統,我們主要将完成這個結構框圖中介紹的各個子產品。
2.各個子產品設計與仿真
function im_encode(left_name, right_name, parameter);
發送端的說明
2.1 獲得左右兩個圖像
·MATLAB代碼
imag_L = imread('stereo_images/corridor1.pgm');
imag_R = imread('stereo_images/corridor2.pgm');
figure(1);
subplot(121),imshow(imag_L);title('left');
subplot(122),imshow(imag_R);title('right');
·仿真效果
圖2 左右眼睛看到的圖像
·代碼說明
通過讀取兩個圖檔,來模拟人兩個眼睛所看到的圖像。
2.2 Transform子產品
這個子產品主要使用DCT變換,但是這裡設計到一個問題,就是将兩個圖檔信号變為一路信号的問題。就本課題而言,這裡有以下幾個方法實作;
·由于這兩個圖檔是雙目信号,是以可以先進行立體比對得到一個圖檔,然後再接收端分解成兩個雙目圖檔;
·由小波分解進行融合得到一路信号,然後在接收端進行反變換,但是這種做法也較複雜。
·進行圖檔的采樣處理,對兩個圖檔進行間隔采樣,然後在接收端進行内插得到原圖像,這種方法比較簡單,本子產品采用這個方法。
其代碼如下所示:
[R,L] = size(imag_L);
for i = 1:R
for j = 1:L
if mod(i+j,2)==0
image(i,j) = imag_L(i,j);
else
image(i,j) = imag_R(i,j);
end
end
end
2.3 DCT變換
我們在這裡使用MATLAB内部的dct2函數。這裡就不多做介紹了。其仿真結果如下所示:
其代碼如下所示:
DCT_out = dct2(image);
2.4 ZIGZAG算法
其基本原理如下所示:
通過這個方法,我們可以将一個圖像的二維資料變為一個串行的資料流。
其對應的代碼如下所示:
function [y]=toZigzag(x)
% transform a matrix to the zigzag format
[row col]=size(x);
if row~=col
disp('toZigzag() fails!! Must be a square matrix!!');
return
end
y=zeros(row*col,1);
count=1;
for s=1:row
if mod(s,2)==0
for m=s:-1:1
y(count)=x(m,s+1-m);
count=count+1;
end;
else
for m=1:s
y(count)=x(m,s+1-m);
count=count+1;
end
end
end
if mod(row,2)==0
flip=1;
else
flip=0;
end
for s=row+1:2*row-1
if mod(flip,2)==0
for m=row:-1:s+1-row
y(count)=x(m,s+1-m);
count=count+1;
end
else
for m=row:-1:s+1-row
y(count)=x(s+1-m,m);
count=count+1;
end;
end;
flip=flip+1;
end
μ律(m-Law)壓擴主要用在北美和日本等地區的數字電話通信中。m為确定壓縮量的參數,它反映最大量化間隔和最小量化間隔之比,通常取100≤m≤500。由于m律壓擴的輸入和輸出關系是對數關系,是以這種編碼又稱為對數PCM。
A律(A-Law)壓擴主要用在歐洲和中國大陸等地區的數字電話通信中。A為确定壓縮量的參數,它反映最大量化間隔和最小量化間隔之比。A律壓擴的前一部分是線性的,其餘部分與μ律壓擴相同。
15折線特性給出的小信号的信号量噪比約是13折線特性的兩倍。 但是,對于大信号而言,15折線特性給出的信号量噪比要比13折線特性時稍差。在保證小信号的量化間隔相等的條件下,均勻量化需要11比特編碼,而非均勻量化隻要7比特就夠了。
其對應的待明如下所示:
function ypcm=mulaw(yn)
x=yn;
s=sign(x);
x=abs(x);
ypcm=zeros(length(x),1);
%進行基于15折線的分段映射
for i=1:length(x)
if x(i)<1/255 %序列值位于第1折線
ypcm(i)=255/8*x(i);
elseif x(i)<3/255 %序列值位于第2折線
ypcm(i)=255/16*x(i)+1/16;
elseif x(i)<7/255 %序列值位于第3折線
ypcm(i)=255/32*x(i)+5/32;
elseif x(i)<15/255 %序列值位于第4折線
ypcm(i)=255/64*x(i)+17/64;
elseif x(i)<31/255 %序列值位于第5折線
ypcm(i)=255/128*x(i)+49/128;
elseif x(i)<63/255 %序列值位于第6折線
ypcm(i)=255/256*x(i)+129/256;
elseif x(i)<127/255 %序列值位于第7折線
ypcm(i)=255/512*x(i)+321/512;
else %序列值位于第8折線
ypcm(i)=255/1024*x(i)+769/1024;
end
end
ypcm=ypcm.*(2^7);
ypcm=floor(ypcm);
ypcm=ypcm.*s;
2.6 編碼子產品
發送的最後我們需要将量化後的資料進行壓縮,得到二進制比特率進行發送,這裡我們使用huffman編碼。Huffman編碼的基本原理如下所示:
哈夫曼編碼是用于資料檔案壓縮的一個十分有效的編碼方法,其壓縮率通常在20%~90%之間。哈夫曼編碼算法使用字元在檔案中出現的頻率表來建立一個0,1串,以表示各個字元的最優表示方式。
它是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。 Huffman于1952年提出一種編碼方法,該方法完全依據字元出現機率來構造異字頭的平均長 度最短的碼字,有時稱之為最佳編碼,一般就叫作Huffman編碼。 以哈夫曼樹─即最優二叉樹,帶權路徑長度最小的二叉樹,經常應用于資料壓縮。 在計算機資訊進行中,“哈夫曼編碼”是一種一緻性編碼法(又稱"熵編碼法"),用于資料的無損耗壓縮。這一術語是指使用一張特殊的編碼表将源字元(例如某檔案中的一個符号)進行編碼。這張編碼表的特殊之處在于,它是根據每一個源字元出現的估算機率而建立起來的(出現機率高的字元使用較短的編碼,反之出現機率低的則使用較長的編碼,這便使編碼之後的字元串的平均期望長度降低,進而達到無損壓縮資料的目的)。這種方法是由David.A.Huffman發展起來的。 例如,在英文中,e的出現機率很高,而z的出現機率則最低。當利用哈夫曼編碼對一篇英文進行壓縮時,e極有可能用一個位(bit)來表示,而z則可能花去25個位(不是26)。用普通的表示方法時,每個英文字母均占用一個位元組(byte),即8個位。二者相比,e使用了一般編碼的1/8的長度,z則使用了3倍多。倘若我們能實作對于英文中各個字母出現機率的較準确的估算,就可以大幅度提高無損壓縮的比例。
根據變長最佳編碼定理,Huffman編碼步驟如下:
(1)将信源符号xi按其出現的機率,由大到小順序排列。
(2)将兩個最小的機率的信源符号進行組合相加,并重複這一步驟,始終将較大的機率分支放在上部,直到隻剩下一個信源符号且機率達到1.0為止;
(3)對每對組合的上邊一個指定為1,下邊一個指定為0(或相反:對上邊一個指定為0,下邊一個指定為1);
(4)畫出由每個信源符号到機率1.0處的路徑,記下沿路徑的1和0;
(5)對于每個信源符号都寫出1、0序列,則從右到左就得到非等長的Huffman碼。
其對應的代碼如下所示:
function [compression,dict] = huffman_module(image);
s = image;
%entropy
p = hist(s,length(s));
idx=find(p~=0);
prob=p(idx)/length(s);
entropy=-prob*log2(prob)';
%redundancy
entropymax=log2(length(prob));
redundancy=(entropymax-entropy)/entropymax;
reff=sort(s);
ref2=reff(2:end);
ref=reff(1:end-1);
chg=ref2-ref;
idx2=find(chg~=0);
sig=ref2(idx2);
symbols=[ref(1);sig];
%huffman table
set(0,'RecursionLimit',2000);
[dict,avglen] = huffmandict(symbols,prob);
% %huffman encoder
compression = huffmanenco(s,dict);
3.各個子產品設計與仿真
3.系統總體仿真說明
系統的仿真結果如下所示:
讀入兩個圖檔
DCT變換值
量化值
壓縮比特流
最後接收到的雙目圖檔。
最後我們可以得到PSNR值為