Professional Documents
Culture Documents
1/20 Trang
Mã hó a nguồ n chính là nén dữ liệu từ nguồ n tín hiệu trướ c khi
truyền đi để giả m lượ ng dữ liệu phả i truyền đồ ng thờ i thu nhỏ cỡ tậ p
tin giú p cho việc truyền thô ng có hiệu quả hơn.
2/20 Trang
Phân loại và ứng dụng
Có mộ t số phương phá p nén đượ c dù ng phổ biến như: Phương
phá p mã hoá độ dà i loạ t (Run-Length Encoding), Phương phá p nén
LZW, mã hó a Huffman,… Tuy nhiên, thuậ t toá n Huffman có ưu điểm là
hệ số nén tương đố i cao, phương phá p thự c hiện tương đố i đơn giả n,
đò i hỏ i ít bộ nhớ , có thể xâ y dự ng dự a trên cá c mả ng bé hơn 64KB.
Nhượ c điểm củ a nó là phả i chứ a cả bả ng mã và o tậ p tin nén thì phía
nhậ n mớ i có thể giả i mã đượ c do đó hiệu suấ t nén chỉ cao khi ta thự c
hiện nén các tậ p tin lớ n.
3.3.3 Mã Huffman
Cá c tậ p tin củ a má y tính đượ c lưu dướ i dạ ng các kí tự có chiều
dà i khô ng đổ i là 8 bits. Trong nhiều tậ p tin, xá c suấ t xuấ t hiện các kí tự
nà y là nhiều hơn cá c kí tự khá c, từ đó ta thấ y ngay rằ ng nếu chỉ dù ng
mộ t và i bit để biểu diễn cho cá c kí tự có xác suấ t xuấ t hiện lớ n và dù ng
nhiều bit hơn để biểu diễn cho cá c kí tự có xá c suấ t xuấ t hiện nhỏ thì
có thể tiết kiệm đượ c độ dà i tậ p tin mộ t cách đá ng kể. Ví dụ , để mã hoá
mộ t chuỗ i như sau:
"ABRACADABRA"
Nếu mã hoá chuỗ i trên trong dạ ng mã nhị phâ n 4 bit ta sẽ có độ
dà i dãy bit cầ n mã hó a cho chuỗ i ký tự trên là 44.
Ðể giả i mã thô ng điệp nà y, chỉ đơn giả n là đọ c ra 4 bit ở từ ng thờ i
điểm và chuyển đổ i nó tương ứ ng vớ i việc mã hoá nhị phâ n đã đượ c
định nghĩa ở trên. Trong mã chuẩ n nà y, chữ D xuấ t hiện chỉ mộ t lầ n sẽ
cầ n số lượ ng bit giố ng chữ A xuấ t hiện nhiều lầ n.
Ta có thể gá n cá c chuỗ i bit ngắ n nhấ t cho các kí tự đượ c dù ng
nhiều nhấ t, giả sử ta gá n: A là 0, B là 1, R là 01, C là 10 và D là 11 thì
chuỗ i trên đượ c biễu diễn như sau:
0 1 01 0 10 0 11 0 1 01 0
Ví dụ nà y chỉ dù ng 15 bit so vớ i 55 bit như ở trên, nhưng nó
khô ng thự c sự là mộ t mã vì phả i lệ thuộ c và o khoả ng trố ng để phâ n
cá ch cá c kí tự . Nếu khô ng có dấ u phâ n cá ch thì ta khô ng thể giả i mã
đượ c thô ng điệp nà y. Ta cũ ng có thể chọ n cá c từ mã sao cho thô ng
điệp có thể đượ c giả i mã mà khô ng cầ n dấ u phâ n cách, ví dụ như: A là
11, B là 00, C là 010, D là 10 và R là 011, các từ mã nà y gọ i là cá c từ mã
có tính prefix (Khô ng có từ mã nà o là tiền tố củ a từ mã khá c). Vớ i cá c
từ mã nà y, ta có thể mã hoá thô ng điệp trên như sau:
1100011110101110110001111
3/20 Trang
Vớ i chuỗ i đã mã hoá nà y ta hoà n toà n có thể giả i mã đượ c mà
khô ng cầ n dấ u phâ n cách. Nhưng bằ ng cá ch nà o để tìm ra bả ng mã
mộ t cá ch tố t nhấ t ? Và o nă m 1952, D.Huffman đã phá t minh ra mộ t
cá ch tổ ng quá t để tìm ra bả ng mã nà y như sau:
- Bướ c đầ u tiên trong việc xâ y dự ng mã Huffman là đếm số lầ n xuấ t
hiện củ a mỗ i kí tự trong tậ p tin sẽ đượ c mã hoá .
- Bướ c tiếp theo là xâ y dự ng mộ t câ y nhị phâ n vớ i các tầ n suấ t đượ c
chứ a trong cá c nú t. Hai nú t có tầ n số bé nhấ t đượ c tìm thấ y và mộ t nú t
mớ i đượ c tạ o ra vớ i hai nú t con là cá c nú t đó vớ i giá trị tầ n số củ a nú t
mớ i bằ ng tổ ng tầ n suấ t củ a hai nú t con. Tiếp theo hai nú t mớ i vớ i tầ n
suấ t nhỏ nhấ t lạ i đượ c tìm thấ y và mộ t nú t mớ i nữ a lạ i đượ c tạ o ra
theo cá ch trên. Lặ p lạ i như vậ y cho đến khi tấ t cả cá c nú t đượ c tổ hợ p
thà nh mộ t câ y duy nhấ t.
- Sau khi có câ y nhị phâ n, bả ng mã Huffman đượ c phá t sinh bằ ng cách
thay thế cá c tầ n suấ t ở nú t đáy bằ ng cá c kí tự tương ứ ng.
Ưu điểm củ a phương phá p mã hoá Huffman là đạ t đượ c hệ số
nén cao (Hệ số nén tuỳ thuộ c và o cấ u trú c củ a cá c tậ p tin). Nhượ c
điểm củ a phương phá p nà y là bên nhậ n muố n giả i mã đượ c thô ng điệp
thì phả i có mộ t bả ng mã giố ng như bả ng mã ở bên gử i, do đó khi nén
cá c tậ p tin bé hệ số nén khô ng đượ c cao.
Ví dụ:
Mã hó a cho chuỗ i ký tự a từ A đến H vớ i xá c suấ t xuấ t hiện củ a cá c ký
tự như sau:
Ký tự A B C D E F G H
Xá c suấ t (p(m)) 0.1 0.18 0.4 0.05 0.06 0.1 0.07 0.04
Entropy củ a nguồ n là :
8
1
H = ∑ p( m)log 2 = 2.55 (bit/ký tự ) (8.1)
m=1 p (m)
4/20 Trang
Thự c hiện cá c bướ c như sau:
1. Sắ p xếp cá c ký tự theo thứ tự xá c suấ t giả m dầ n.
2. Gá n cho hai ký tự có xá c suấ t xuấ t hiện thấ p nhấ t vớ i hai nhá nh
(0) và (1) củ a câ y mã . Từ hai ký tự có xác suấ t thấ p nhấ t giả m
cò n mộ t ký tự vớ i xá c suấ t bằ ng tổ ng củ a hai xác suấ t.
3. Lặ p lạ i từ bướ c (1) cho đến khi chỉ cò n lạ i mộ t ký tự duy nhấ t
vớ i xá c suấ t là 1.
4. Duyệt cây mã để tìm ra từ mã tương ứ ng vớ i từ ng ký tự củ a
nguồ n.
Quy ướ c gá n cho nhá nh đi ra từ ký hiệu có xác suấ t cao hơn là 1
và nhá nh kia là 0 thì ta có thể vẽ lạ i câ y mã Huffman vừ a đượ c lậ p như
hình 2.1
5/20 Trang
Nhìn và o câ y mã ta thấ y kết quả mã hó a nguồ n tin như sau:
Ký tự A B C D E F G H
6/20 Trang
Bước 2: Nhập mã nguồn cho các Pushbutton:
function varargout = GuideHuffman1(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @GuideHuffman1_OpeningFcn, ...
'gui_OutputFcn', @GuideHuffman1_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function GuideHuffman1_OpeningFcn(hObject, eventdata, handles,
varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = GuideHuffman1_OutputFcn(hObject, eventdata,
handles)
varargout{1} = handles.output;
function push1_Callback(hObject, eventdata, handles)
my_str =get(handles.input,'string');
auto_prob = 1;
if (auto_prob == 1)
prob_dist = double(my_str);
else
prob_dist = [10 19 30 40 50];
end
num_bits = ceil(log2(length(prob_dist)));
disp('Bang Ma ASCII cua cac ky tu:');
for i = 1:length(prob_dist)
display(strcat(my_str(i),' Ma ASCII la: ',num2str(prob_dist(i))));
end
total = sum(prob_dist);
for i = 1:length(my_str)
sorted_str{i} = my_str(i);
7/20 Trang
end
init_str = sorted_str;
init_prob = prob_dist;
sorted_prob = prob_dist;
rear = 1;
while (length(sorted_prob) > 1)
[sorted_prob,indeces] = sort(sorted_prob,'ascend');
sorted_str = sorted_str(indeces);
new_node = strcat(sorted_str(2),sorted_str(1));
new_prob = sum(sorted_prob(1:2));
sorted_str = sorted_str(3:length(sorted_str));
sorted_prob = sorted_prob(3:length(sorted_prob));
sorted_str = [sorted_str, new_node];
sorted_prob = [sorted_prob, new_prob];
newq_str(rear) = new_node;
newq_prob(rear) = new_prob;
rear = rear + 1;
end
tree = [newq_str,init_str];
tree_prob = [newq_prob, init_prob];
[sorted_tree_prob,indeces] = sort(tree_prob,'descend');
sorted_tree = tree(indeces);
parent(1) = 0;
num_children = 2;
for i = 2:length(sorted_tree)
me = sorted_tree{i};
count = 1;
parent_maybe = sorted_tree{i-count};
diff = strfind(parent_maybe,me);
while (isempty(diff))
count = count + 1;
parent_maybe = sorted_tree{i-count};
diff = strfind(parent_maybe,me);
end
parent(i) = i - count;
end
treeplot(parent);
title(strcat('So do Ma cay Huffman - "',my_str,'"'));
display(sorted_tree)
display(sorted_tree_prob)
[xs,ys,h,s] = treelayout(parent);
text(xs,ys,sorted_tree);
for i = 2:length(sorted_tree)
my_x = xs(i);
my_y = ys(i);
parent_x = xs(parent(i));
parent_y = ys(parent(i));
mid_x = (my_x + parent_x)/2;
mid_y = (my_y + parent_y)/2;
slope = (parent_y - my_y)/(parent_x - my_x);
if (slope > 0)
weight(i) = 1;
else
weight(i) = 0;
end
text(mid_x,mid_y,num2str(weight(i)));
end
for i = 1:length(sorted_tree)
code{i} = '';
index = i;
p = parent(index);
8/20 Trang
while(p ~= 0)
w = num2str(weight(index));
code{i} = strcat(w,code{i});
index = parent(index);
p = parent(index);
end
end
function input_Callback(hObject, eventdata, handles)
function input_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function pushbutton2_Callback(hObject, eventdata, handles)
my_str =get(handles.input,'string');
auto_prob = 1;
if (auto_prob == 1)
prob_dist = double(my_str);
else
prob_dist = [10 19 30 40 50];
end
num_bits = ceil(log2(length(prob_dist)));
disp('Bang Ma ASCII cua cac ky tu:');
for i = 1:length(prob_dist)
display(strcat(my_str(i),' Ma ASCII la: ',num2str(prob_dist(i))));
end
total = sum(prob_dist);
for i = 1:length(my_str)
sorted_str{i} = my_str(i);
end
init_str = sorted_str;
init_prob = prob_dist;
sorted_prob = prob_dist;
rear = 1;
while (length(sorted_prob) > 1)
[sorted_prob,indeces] = sort(sorted_prob,'ascend');
sorted_str = sorted_str(indeces);
new_node = strcat(sorted_str(2),sorted_str(1));
new_prob = sum(sorted_prob(1:2));
sorted_str = sorted_str(3:length(sorted_str));
sorted_prob = sorted_prob(3:length(sorted_prob));
sorted_str = [sorted_str, new_node];
sorted_prob = [sorted_prob, new_prob];
newq_str(rear) = new_node;
newq_prob(rear) = new_prob;
rear = rear + 1;
end
tree = [newq_str,init_str];
tree_prob = [newq_prob, init_prob];
[sorted_tree_prob,indeces] = sort(tree_prob,'descend');
sorted_tree = tree(indeces);
parent(1) = 0;
num_children = 2;
for i = 2:length(sorted_tree)
me = sorted_tree{i};
count = 1;
parent_maybe = sorted_tree{i-count};
diff = strfind(parent_maybe,me);
while (isempty(diff))
count = count + 1;
parent_maybe = sorted_tree{i-count};
9/20 Trang
diff = strfind(parent_maybe,me);
end
parent(i) = i - count;
end
treeplot(parent);
title(strcat('So do Ma cay Huffman - "',my_str,'"'));
display(sorted_tree)
display(sorted_tree_prob)
[xs,ys,h,s] = treelayout(parent);
text(xs,ys,sorted_tree);
for i = 2:length(sorted_tree)
my_x = xs(i);
my_y = ys(i);
parent_x = xs(parent(i));
parent_y = ys(parent(i));
mid_x = (my_x + parent_x)/2;
mid_y = (my_y + parent_y)/2;
slope = (parent_y - my_y)/(parent_x - my_x);
if (slope > 0)
weight(i) = 1;
else
weight(i) = 0;
end
text(mid_x,mid_y,num2str(weight(i)));
end
for i = 1:length(sorted_tree)
code{i} = '';
index = i;
p = parent(index);
while(p ~= 0)
w = num2str(weight(index));
code{i} = strcat(w,code{i});
index = parent(index);
p = parent(index);
end
end
codeBook = [sorted_tree', code']
set(handles.text2,'string',sorted_tree);
set(handles.text3,'string',code);
function axes2_CreateFcn(hObject, eventdata, handles)
function axes3_CreateFcn(hObject, eventdata, handles)
function edit3_Callback(hObject, eventdata, handles)
function edit3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function axes4_CreateFcn(hObject, eventdata, handles)
imshow('C:\Users\Public\Pictures\Sample Pictures\logo\5.jpg');
function axes5_CreateFcn(hObject, eventdata, handles)
imshow('C:\Users\Public\Pictures\Sample Pictures\logo\logokhoa.png');
function pushbutton4_Callback(hObject, eventdata, handles)
dos command;
Bước 3: Nhập số liệu và chạy chương trình tạo mã Huffman cho kết quả
như sau:
10/20 Trang
II. Phần mềm nén dữ liệu ứng dụng mã huffman
Chương trình nén file dùng mã Huffman viết bằng ngôn ngữ Visual
Studio 2010, sau khi chạy chương trình xuất ra file Huffman.exe giả sử đặt
trong ổ D\truyensolieu\mahoa\Huffman.exe, để chạy chương trình nén/giải
nén file bất kỳ từ giao diện Guide bấm vào Nén/Giải nén hoặc từ cửa sổ
lệnh của Matlab ta vào đường dẫn trên như sau:
11/20 Trang
Sau khi nén xong xuất ra file nén dưới dạng .huf, sau khi giải nén ra file
ban đầu.
3.5. BÀI TẬP
Viết chương trình tạ o mã Shanon-Fano và mộ t số loạ i mã nguồ n khá c.
2.6. BÁO CÁO TỔNG KẾT
12/20 Trang