Tải bản đầy đủ (.doc) (67 trang)

Tìm hiểu các phương pháp nén ảnh và ứng dụng biến đổi wavelet trong thông tin di động

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.19 MB, 67 trang )

MỤC LỤC
LỜI NÓI ĐẦU...........................................................................................................................................3
THUẬT NGỮ TIẾNG ANH.........................................................................................................................4
DANH MỤC CÁC HÌNH............................................................................................................................5
CHƯƠNG 1.............................................................................................................................................7
TỔNG QUAN VỀ NÉN ẢNH......................................................................................................................7
1.1 Giới thiệu về ảnh số và xử lý ảnh số: ............................................................................................7
1.1.1 Ảnh số:..................................................................................................................................7
1.1.2 Xử lý ảnh số:.........................................................................................................................7
1.2 Mục đích và sự cần thiết của nén ảnh:.........................................................................................8
1.3 Các khái niệm cơ bản:...................................................................................................................9
1.4 Cách phân loại các phương pháp nén ảnh:.................................................................................10
1.4.1 Cách phân loại dựa vào nguyên lý nén:...............................................................................10
1.4.2 Cách phân loại dựa vào cách thức thực hiện nén:..............................................................10
1.4.3 Cách phân loại dựa vào lý thuyết mã hoá:..........................................................................11
1.4.4 Quá trình nén và giải nén:....................................................................................................11
Chương 2..............................................................................................................................................12
CÁC PHƯƠNG PHÁP NÉN ẢNH.............................................................................................................12
2.1 Phương pháp mã hoá độ dài loạt RLE:........................................................................................12
2.1.1 Nguyên tắc:..........................................................................................................................12
2.1.2 Thuật toán:..........................................................................................................................14
2.1.3 Một số thủ tục chương trình:...............................................................................................14
2.2 Phương pháp mã hoá Huffman:.................................................................................................18
2.2.1 Nguyên tắc:..........................................................................................................................18
2.2.2 Thuật toán:..........................................................................................................................18
`2.2.3 Một số thủ tục chương trình:.............................................................................................21
2.3 Phương pháp mã hoá LZW:........................................................................................................23
2.3.1 Nguyên tắc:.........................................................................................................................23
2.3.2 Thuật toán:.........................................................................................................................26
2.3.3 Một số thủ tục chương trình:..............................................................................................28
2.4 Phương pháp mã hoá JPEG:........................................................................................................30


2.4.1 Nguyên tắc:.........................................................................................................................30
2.4.3 Một số thủ tục chương trình:..............................................................................................38
Chương 3..............................................................................................................................................42
BIẾN ĐỔI WAVELET VÀ ỨNG DỤNG TRONG THÔNG TIN DI ĐỘNG.......................................................42


3.1 Biến đổi wavelet.........................................................................................................................42
3.2 Giới thiệu một số họ Wavelet.....................................................................................................45
3.2.1 Biến đổi Wavelet Haar........................................................................................................45
3.2.2. Biến đổi Wavelet Meyer....................................................................................................46
3.2.3. Biến đổi Wavelet Daubechies.............................................................................................46
3.3 Một số ứng dụng nổi bật của Wavelet........................................................................................47
3.3.1. Nén tín hiệu.......................................................................................................................47
3.3.2 Khử nhiễu............................................................................................................................47
3.3.3 Mã hoá nguồn và mã hoá kênh...........................................................................................48
3.4 Chuẩn nén ảnh tĩnh dựa trên biến đổi Wavelet-JPEG2000.........................................................48
3.4.1 Lịch sử ra đời và phát triển chuẩn JPEG2000......................................................................48
3.4.2. Các tính năng của JPEG2000..............................................................................................48
3.4.3. Các bước thực hiện nén ảnh theo chuẩn JPEG2000...........................................................49
3.4.4. So sánh chuẩn JPEG2000 với JPEG và các chuẩn nén ảnh tĩnh khác..................................55
3.4.5 Ứng dụng Wavelet trong thông tin di động........................................................................58


LỜI NÓI ĐẦU
Ngày nay, cùng với sự phát triển không ngừng của khoa học và công nghệ thì
máy tính đóng vai trò ngày càng quan trọng và không thể thiếu trong cuộc sống xã hội
loài người. Việc trao đổi thông tin của con người trong tất cả các ngành, các lĩnh vực
của đời sống ngày càng trở nên cần thiết cùng với sự ra đời và phát triển của mạng
Internet.
Xử lý ảnh là một ngành khoa học còn tương đối mới mẻ so với nhiều ngành

khoa học khác nhưng nó đang được tập trung nghiên cứu và phát triển vì những ứng
dụng thực tiễn của nó trong nhiều ngành, lĩnh vực khác nhau. Trong đó “Nén ảnh” là
một phần của xử lý ảnh có ứng dụng to lớn trong truyền thông và trong lưu trữ, đã có
rất nhiều phương pháp nén ảnh được ra đời và không ngừng được cải tiến để ngày
càng hoàn thiện đem lại hiệu quả nén cao và cho chất lượng ảnh tốt nhất. Trong đồ án
tốt nghiệp “Tìm Hiểu Các

Phương Pháp Nén Ảnh Và Ứng Dụng Biến Đổi

Wavelet Trong Thông Tin Di Động” được sự hướng dẫn của cô giáo NGÔ THÚY
NGÂN em đã nghiên cứu một số phương pháp nén ảnh phổ biến như: mã loạt dài
RLE, HUFFMAN, LZW, JPEG và phương pháp nén ảnh JPEG2000 dựa trên biến đổi
Wavelet với những đặc tính vượt trội so với các chuẩn nén trước đó đem lại hiệu quả
nén cao, cho ảnh nén chất lượng tốt và nhiều những ưu điểm khác mà các chuẩn nén
trước đó không thể có.
Nội dung bài đồ án bao gồm các chương như sau:
- Chương 1: Tổng quan về nén ảnh
- Chương 2: Các phương pháp nén ảnh
- Chương 3: Biến đổi Wavelet và ứng dụng trong thông tin di động


THUẬT NGỮ TIẾNG ANH
CWT

Biến đổi Wavelet liên tục (Continuous Wavelet Transform)

DCT

Biến đổi Cosine rời rạc (Discrete Cosine Transform)


DFT

Biến đổi Fourier rời rạc (Discrete Fourier Transform)

DPCM

Điều xung mã vi sai (Differized Pulse Code Modulation)

DWT

Biến đổi Wavelet rời rạc (Discrete Wavelet Transform)

EZW

Wavelet cây zero (Embedded Zerotree Wavelet)

HVS

Hệ thống cảm nhận hình ảnh của mắt người
(Human Visual System)

IDWT

Biến đổi Wavelet rời rạc ngược

JPEG

Chuẩn nén ảnh của ủy ban JPEG quốc tế
(Joint Photographic Experts Group)


JPEG2000

Chuẩn nén ảnh JPEG2000

MRA

Phân tích đa phân giải (Multi Resolution Analysis)

MSE

Sai số bình phương trung bình (Mean Square Error)

PCM

Điều xung mã(Pulse Code Modulation)

PSNR

Tỷ số tín hiệu đỉnh trên nhiễu (Peak Signal to Noise Ratio)

QMF

Lọc gương cầu tứ phương (Quardrature Mirror Filters)

RLC

Mã hoá loạt dài (Run Length Coding)

ROI


Kỹ thuật mã hóa ảnh theo vùng (Region Of Interest) – Một
tính năng mới nổi bật của JPEG2000

SPIHT

Phương pháp mã hoá phân cấp theo vùng
(Set partitioning in hierarchical trees)

STFT

Biếnđổi Fourier thời gian ngắn (Short Time Fourier Transform)

Wavelet

Biến đổi băng con Wavelet


DANH MỤC CÁC HÌNH


DANH MỤC CÁC BẢNG
Bảng 1: Cấu trúc từ điển.......................................................................................................................24
Bảng 2: So sánh JPEG và JPEG2000.......................................................................................................56
Bảng 3: So sánh tính năng của JPEG2000 với các chuẩn nén ảnh tĩnh khác..........................................58


CHƯƠNG 1
TỔNG QUAN VỀ NÉN ẢNH
1.1 Giới thiệu về ảnh số và xử lý ảnh số:
1.1.1 Ảnh số:

Ảnh có thể biểu diễn dưới dạng tín hiệu tương tự hoặc tín hiệu số. Trong biểu
diễn số của các ảnh đa mức xám, một ảnh được biểu diễn dưới dạng một ma trận hai
chiều. Mỗi phần tử của ma trận biểu diễn cho mức xám hay cường độ của ảnh tại vị trí
đó. Mỗi phần tử trong ma trận được gọi là một phần tử ảnh, thông thường kí hiệu là
PEL (Picture Element) hoặc là điểm ảnh (Pixel).
- Với ảnh đa cấp xám: Nếu dùng 8 bit (1 byte) để biểu diễn mức xám, thì
số các mức xám có thể biểu diễn được là 28 hay 256. Mỗi mức xám được biểu diễn
dưới dạng là một số nguyên nằm trong khoảng từ 0 đến 255, với mức 0 biểu diễn cho
mức cường

độ đen nhất và 255 biểu diễn cho mức cường độ sáng nhất.

- Với ảnh màu: Cách biểu diễn cũng tương tự như với ảnh đen trắng, chỉ khác
là các số tại mỗi phần tử của ma trận biểu diễn cho ba màu riêng rẽ gồm: đỏ (red), lục
(green) và lam (blue). Để biểu diễn cho một điểm ảnh màu cần 24 bit, 24 bit này được
chia thành ba khoảng 8 bit. Mỗi khoảng này biểu diễn cho cường độ sáng của một
trong các màu chính.

Hình 1.1 Biểu diễn của một mức xám của ảnh số.
1.1.2 Xử lý ảnh số:
Xử lý ảnh là một khoa học mặc dù còn tương đối mới so với nhiều ngành khoa
học khác, nhất là trên quy mô công nghiệp. Xử lý ảnh số có rất nhiều ứng dụng như
làm nổi các ảnh trong y học, khôi phục lại ảnh do tác động của khí quyển trong thiên


văn học, tăng cường độ phân giải của ảnh truyền hình mà không cần thay đổi cấu trúc
bên trong của hệ thống chuyển tải, nén ảnh trong khi truyền đi xa hoặc lưu trữ.
Các giai đoạn chính trong xử lý ảnh có thể được mô tả trong hình sau:

LƯU


CAMERA

SỐ

THU NHẬN
ẢNH

PHÂN TÍCH
ẢNH

NHẬN
DẠNG

SENSOR
LƯU
TRỮ

HỆ QUYẾT
ĐỊNH

Hình 1. 2: Các giai đoạn chính trong xử lý ảnh

1.2 Mục đích và sự cần thiết của nén ảnh:
Nén ảnh là một kỹ thuật mã hoá các ảnh số hoá nhằm giảm số lượng các bit dữ
liệu cần thiết để biểu diễn ảnh. Mục đích là giảm đi những chi phí trong việc lưu trữ
ảnh và chi phí thời gian để truyền ảnh đi xa trong truyền thông nhưng vẫn đảm bảo
được chất lượng của ảnh. Nén ảnh thực hiện được là do một thực tế: thông tin trong
bức ảnh không phải là ngẫu nhiên mà có trật tự, tổ chức.Vì thế nếu bóc tách được tính
trật tự, cấu trúc đó thì sẽ biết phần thông tin nào quan trọng nhất trong bức ảnh để biểu

diễn và truyền đi với số lượng ít bit hơn so với ảnh gốc mà vẫn đảm bảo tính đầy đủ
của thông tin. Ở bên nhận quá trình giải mã sẽ tổ chức, sắp xếp lại được bức ảnh xấp xỉ
gần chính xác so với ảnh gốc nhưng vẫn thỏa mãn chất lượng yêu cầu. Dưới đây là ví
dụ về lưu trữ ảnh số và truyền đi xa với đường truyền 9600 baud (9600 bps) để thấy rõ
sự cần thiết của việc nén ảnh:
• Ảnh đa cấp xám hay ảnh 256 màu có kích thước 800 x 600, 8 bit/điểm ảnh,
cần 3.840.000 bit lưu trữ và mất 6.67 phút để truyền.
• Ảnh màu RGB (24 bit/điểm ảnh ) cùng độ phân giải như vậy cần hơn 10 triệu
bit để lưu trữ và 20 phút để truyền.


• Một phim âm bản có kích thước 24×36 mm (35mm) chia bằng các khoảng
cách nhau 12 mm, vào khoảng 3000×2000 điểm, 8 bit/pixel, yêu cầu 48 triệu bit cho
lưu giữ ảnh và 83 phút để truyền.
Qua ví dụ trên ta thấy nhiều vấn đề trong việc lưu trữ và truyền tải ảnh số hoá.
Nén ảnh có nhiều ứng dụng trong thực tế như: truyền các văn bản đồ hoạ qua đường
điện thoại (Fax), nén ảnh trong y tế và truyền hình cáp. Chính sự ứng dụng trong nhiều
lĩnh vực của nén ảnh cùng với sự tiến bộ trong lĩnh vực vi điện tử dẫn đến sự ra đời
các chuẩn nén ảnh.
Nén ảnh đạt được bằng cách loại bỏ các phần dư thừa trong ảnh đã được số hoá.
Dư thừa có thể là dư thừa thông tin về không gian, dư thừa về cấp xám hay dư thừa về
thời gian:
• Dư thừa thông tin về không gian: trong một bức ảnh luôn tồn tại sự tương
quan giữa các điểm ảnh cạnh nhau.
• Dư thừa thông tin về cấp xám: là dư thừa dựa vào sự tương quan giữa các màu
sắc cạnh nhau.
• Dư thừa thông tin về thời gian: Trong một chuỗi ảnh video, tồn tại sự tương
quan giữa các điểm ảnh của các frame khác nhau .

1.3 Các khái niệm cơ bản:

• Pixel (picture element): phần tử ảnh
Ảnh trong thực tế là một ảnh liên tục về không gian và về giá trị độ sáng. Để có
thể xử lý ảnh bằng máy tính cần thiết phải tiến hành số hoá ảnh. Như vậy một ảnh là
một tập hợp các pixel. Mỗi pixel là gồm một cặp toạ độ x, y và màu. Cặp toạ độ x,y
tạo nên độ phân giải (resolution). Màn hình máy tính có nhiều loại với độ phân giải
khác nhau: 320 x 200, 640x350, 800x600, 1024x768,…
• Mức xám (Graylevel)
Mức xám là kết quả sự mã hoá tương ứng của mỗi cường độ sáng của mỗi điểm
ảnh với một giá trị số – kết quả của quá trình lượng hoá .
• Dữ liệu
Trong một bài toán, dữ liệu bao gồm một tập các phần tử cơ sở mà ta gọi là dữ
liệu nguyên tử. Nó có thể là một chữ số, một ký tự,..nhưng cũng có thể là một con số,
một từ,...điều đó phụ thuộc vào từng bài toán.
• Nén dữ liệu


Nén dữ liệu là quả trình giảm dung lượng thông tin “dư thừa” trong dữ liệu gốc
và làm cho lượng thông tin thu được sau nén thường nhỏ hơn dữ liệu gốc rất nhiều. Do
vậy, tiết kiệm được bộ nhớ và giảm thời gian trao đổi dữ liệu trên mạng thông tin mà
lại cho phép chúng ta khôi phục lại dữ liệu ban đầu.
• Tỷ lệ nén
Tỷ lệ nén là một trong các đặc trưng quan trọng của mọi phương pháp nén. Tỷ
lệ nén được định nghĩa như sau:
Tỷ lệ nén = 1/r*%
với r là tỷ số nén được định nghĩa:
r = kích thước dữ liệu gốc / kích thước dữ liệu nén.
Như vậy hiệu suất nén = (1- tỷ lệ nén)*100%.
Đối vơi ảnh tĩnh, kích thước chính là số bit biểu diễn toàn bộ bức ảnh.
Đối với ảnh video, kích thước chính là số bit để biểu diễn một khung hình video
(video frame).


1.4 Cách phân loại các phương pháp nén ảnh:
1.4.1 Cách phân loại dựa vào nguyên lý nén:
Nén bảo toàn thông tin (losses compression): bao gồm các phương pháp nén mà
sau khi giải nén sẽ thu đựơc chính xác dữ liệu gốc. Tuy nhiên nén bảo toàn thông tin
chỉ đạt hiệu quả nhỏ so với phương pháp nén không bảo toàn thông tin.
Nén không bảo toàn thông tin (lossy compression): bao gồm các phương pháp
nén sau khi giải nén sẽ không thu được dữ liệu như bản gốc. Các phương pháp này
được gọi là “tâm lý thị giác” đó là lợi dụng tính chất của mắt người chấp nhận một số
vặn xoắn trong ảnh khi khôi phục lại. Phương pháp này luôn đem lại hiệu quả cao do
loại bỏ đi những thông tin dư thừa không cần thiết.
1.4.2 Cách phân loại dựa vào cách thức thực hiện nén:
Phương pháp không gian (Spatial Data Compression): các phương pháp này
thực hiện nén bằng cách tác động trực tiếp lên việc lấy mẫu của ảnh trong miền không
gian.
Phương pháp sử dụng biến đổi (Transform Coding): gồm các phương pháp tác
động lên sự biến đổi của ảnh gốc chứ không tác động trực tiếp.


1.4.3 Cách phân loại dựa vào lý thuyết mã hoá:
Các phương pháp nén thế hệ thứ nhất: gồm các phương pháp có mức độ tính
toán đơn giản như lấy mẫu, gán từ mã,...
Các phương pháp nén thế hệ thứ hai: gồm các phương pháp dựa vào mức độ
bão hoà của tỷ lệ nén bằng cách sử dụng các phép toán tổ hợp đầu ra một cách hợp lý
hoặc sử dụng biểu diễn ảnh như: phương pháp kim tự tháp Laplace, phương pháp dựa
vào vùng gia tăng, phương pháp tách hợp.
1.4.4 Quá trình nén và giải nén:
Gồm 2 công đoạn:
Nén: dữ liệu gốc qua bộ mã hoá dữ liệu, bộ mã hoá này thực hiện nén dữ liệu
đến một mức thích hợp cho việc lưu trữ và truyền dẫn thông tin. Quá trình này sẽ thực

hiện việc loại bỏ hay cắt bớt những dư thừa của ảnh để thu được thông tin cần thiết
nhưng vẫn đảm bảo được chất lượng ảnh.
Giải nén: dữ liệu nén đi qua bộ giải mã dữ liệu, bộ giải mã sẽ thực hiện giải
nén để thu được dữ liệu gốc ban đầu.Việc giải nén này thường phải dựa vào các thông
tin đi kém theo dữ liệu nén, tuỳ thuộc vào kiểu nén hay phương pháp nén mà dữ liệu
giải nén được có hoàn toàn giống với dữ liệu gốc ban đầu hay không.
Tóm lại quá trình nén và giải nén dữ liệu có thể mô tả một cách tóm tắt theo sơ
đồ dưới đây

DỮ LIỆU

QUÁ TRÌNH NÉN

DỮ LIỆU

QUÁ TRÌNH GIẢI
Hình 1.3: Quá
NÉNtrình nén và giải nén


Chương 2
CÁC PHƯƠNG PHÁP NÉN ẢNH

2.1 Phương pháp mã hoá độ dài loạt RLE:
Mã hoá theo độ dài loạt RLE (Run Length Encoding) là một phương pháp nén
ảnh dựa trên sự cắt bớt các dư thừa về không gian (một vài hình ảnh có vùng màu lớn
không đổi đặc biệt đối với ảnh nhị phân). Loạt được định nghĩa là dãy các phần tử
điểm ảnh (pixel) liên tiếp có cùng chung một giá trị.
2.1.1 Nguyên tắc:
Nguyên tắc của phương pháp này là phát hiện một loạt các điểm ảnh lặp lại liên

tiếp, ví dụ: 110000000000000011. Ta thấy điểm ảnh có giá trị 0 xuất hiện nhiều lần
liên tiếp thay vì phải lưu trữ toàn bộ các điểm ảnh có giá trị 0 ta chỉ cần lưu trữ chúng
bằng cách sử dụng các cặp (độ dài loạt, giá trị).
Ví dụ:
Cho một chuỗi nguồn d:
d =5 5 5 5 5 5 5 5 5 5 19 19 19 19 19 0 0 0 0 0 0 0 23 23 23 23 23 23 23 23
Ta sẽ có chuỗi mới:
(10 5) (5 19) (7 0) (8 23)
Tỷ số nén = 20/ 8 = 2.5
Đối với ảnh đen trắng chỉ sử dụng 1 bit để biểu diễn 1 điểm ảnh thì phương
pháp này tỏ ra rất hiệu quả, ta thấy điều đó qua ví dụ sau:


Cho một chuỗi nguồn d:
000000000000000111111111100000000001111111111000000000000000
Ta có chuỗi mới:
(15, 10, 10, 10, 15)
Tỷ số nén = 60 bit / (5*4 bit) = 3 ( chỉ sử dụng 4 bit để thể hiện độ dài loạt và không
thể hiện giá trị loạt vì ảnh đen trắng chỉ có 2 giá trị bit là 0 hoặc là 1)

Chú ý:

• Đối với ảnh chiều dài của một dãy lặp có thể lớn hơn 255, nếu ta dùng 1 byte
để lưu trữ chiều dài thì sẽ không đủ. Giải pháp được dùng là tách chuỗi đó thành 2
chuỗi: một chuỗi có chiều dài là 255, chuỗi kia có chiều dài còn lại.

• Phương pháp nén RLE chỉ đạt hiệu quả khi chuỗi lặp lớn hơn 1 ngưỡng nhất
định nào đó hay nói các khác trong ảnh cần nén phải có nhiều điểm ảnh kề nhau có
cùng giá trị màu. Do đó phương pháp này không đem lại cho ta kết quả một cách ổn
định vì nó phụ thuộc hoàn toàn vào ảnh nén chỉ thích hợp cho những ảnh đen trắng

hay ảnh đa cấp xám.
Ví dụ:
Ta có một chuỗi nguồn: d=5 7 9 11 13 18 28 38 48 58 30 35 40 45
Chuỗi kết quả sau khi mã hoá:
1 5 1 7 1 9 1 11 1 3 1 18 1 28 1 38 1 48 1 58 1 30 1 35 1 40 1 45
Tỷ số nén = 14 / 28 = 0.2
Như vậy chuỗi sau khi mã hoá đã lớn hơn nhiều chuỗi nguồn ban đầu. Do đó
cần phương pháp cải tiến để xử lý những trường hợp như trên tránh làm mở rộng chuỗi
dữ liệu nguồn nghĩa là chỉ mã hoá độ dài loạt dữ liệu lặp lại. Người ta đã đưa ra cách
đó là thêm kí tự tiền tố vào trước độ dài loạt, việc giải mã được thực hiện nếu gặp kí tự
tiền tố với độ dài loạt và giá trị điểm ảnh theo sau.
Ví dụ:
Ta có chuỗi nguồn:
d = 5 8 4 8 8 8 8 8 8 8 8 10 10 10 10 10 10 10 10 10
Giả sử kí tự tiền tố là “+” ta có : 5 8 4 +7 8 + 9 10


Tỷ số nén = 19 / 9 = 2.1
Tuy nhiên trong một số trường hợp các điểm ảnh có độ tương quan với nhau vể
giá trị mức xám như trong ví dụ dưới đây ta có thể tiến hành xử lý như sau.
Ví dụ:
Ta có một chuỗi nguồn:
d = 5 7 9 11 13 18 28 38 48 58 55 60 65 70 75 80 85 90 95 100
Ta có dựa vào độ tương quan này để có được hiệu quả nén cao, bằng việc áp dụng e(i)
= d(i) –d(i-1) sẽ thu được:
5 2 2 2 2 5 10 10 10 10 -3 5 5 5 5 5 5 5 5 5
Áp dụng phương pháp nén loạt dài ta dễ dàng thu được:
(5 1)( 2 4)(5 1)(10 5)(-3 1)(5 9)

2.1.2 Thuật toán:

Thuật toán như sau:
• Tiến hành duyệt trên từng hàng cho đến khi kết thúc vùng dữ liệu ảnh, trong
quá trình duyệt tiến hành kiểm tra để tìm ra những loạt có cùng giá trị đồng thời chú ý
những kí hiệu xuống dòng (hay kết thúc dòng), kết thúc ảnh Bitmap.
• Khi gặp loạt có độ dài > 3 thì nhảy đến chế độ nén ngược lại nhảy đến chế độ
không nén tuy nhiên nếu loạt > 255 thì sẽ tách ra chỉ mã < 255 sau đó mã tiếp phần
còn lại. Ngoài ra còn các chế độ khác như: bắt đầu, kết thúc 1 dòng.
• Kết thúc khi gặp kí hiệu kết thúc bitmap (end – o f- bitmap)

2.1.3 Một số thủ tục chương trình:
• Chương trình nén theo phương pháp RLE:
void
CRLE::CompressInRLE8(BYTE*pSrcBits,CByteArray&
pRLEBits, int&
RLE_size)
{
int line;
int src_index = 0, dst_index = 0, counter, i;
for ( line = 0; line < m_dib.dsBmih.biHeight; line++)
{
state_start:
if ( EndOfLine(src_index))
{
pRLEBits[dst_index++] = 1;
pRLEBits[dst_index++] = pSrcBits[src_index];
src_index++;
goto end_of_line;


}

if(pSrcBits[src_index]==pSrcBits[src_index+1])
goto

tate_compress;
if ( EndOfLine(src_index+1))
{
pRLEBits[dst_index++] = 1;
pRLEBits[dst_index++] = pSrcBits[src_index+
+];
pRLEBits[dst_index++] = 1;
pRLEBits[dst_index++] = pSrcBits[src_index+
+];
goto end_of_line;
}
if
(pSrcBits[src_index+1]
==
pSrcBits[src_index+2])
{
pRLEBits[dst_index++] = 1;
pRLEBits[dst_index++] = pSrcBits[src_index+
+];
goto state_compress;
}
else
goto state_no_compress;
state_compress:
for ( counter = 1; counter <= 254; counter++)
{
if

(
pSrcBits[src_index+counter]
!=
pSrcBits[src_index] )
break;
if ( EndOfLine(src_index+counter) )
{
pRLEBits[dst_index++] = counter+1;
pRLEBits[dst_index++] = pSrcBits[src_index];
src_index += counter +1;
goto end_of_line;
}
}
pRLEBits[dst_index++] = counter;
pRLEBits[dst_index++] = pSrcBits[src_index];
src_index += counter;
goto state_start;
state_no_compress:
for (counter = 2; counter <= 254; counter++)
{
if ( EndOfLine(src_index+counter) ) {
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = counter + 1;
for (i = counter + 1; i > 0; i--)


pRLEBits[dst_index++]=pSrcBits[src_index++];
if
(
0

!=
((counter+1)
%
2)
)
pRLEBits[dst_index++];
goto end_of_line;
}
if(EndOfLine(src_index+counter+1) ||
pSrcBits[src_index+counter]
!=
pSrcBits[src_index+counter+1] )
continue;
if(EndOfLine(src_index+counter+2) ||
SrcBits[src_index+counter+1]
!=
pSrcBits[src_index+counter+2]
)
continue;
else
{
if ( counter > 2) counter--;
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = counter+1;
for (i = counter+1; i > 0; i--)
pRLEBits[dst_index++] = pSrcBits[src_index++];
if
(
0
!=

((counter+1)
%
2)
)
pRLEBits[dst_index++];
goto state_compress;
}
}
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = counter;
for (i = counter; i > 0; i--)
pRLEBits[dst_index++] = pSrcBits[src_index++];
if ( 0 != ((counter) % 2) )
pRLEBits[dst_index++];
goto state_start;
end_of_line:
if ( 0 != (src_index % 4 ))
{
int pad = 4 - (src_index%4);
src_index += pad;
}
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = 0;
}
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = 1;
RLE_size = dst_index;
}
• Chương trình giải nén phương pháp RLE:
BOOL CRLE::DecRLE8(ifstream &fil, BYTE *pDest)

{


DWORD x, y, paddedwidth;
paddedwidth =BMPWIDTHBYTES(pInfo->biWidth*pInfo->
biBitCount);
BYTE FirstByte, SecondByte;
WORD data;
x = y = 0;
while (!fil.eof())
{
if (!fil.read((char*)&data, 2)) return FALSE;
FirstByte = LOBYTE(data);
SecondByte = HIBYTE(data);
if (FirstByte == 0)
{
switch (SecondByte)
{
case 0:
x = 0;
y++;
break;
case 1:
return TRUE;
case 2:
if (!fil.read((char*)&data, 2)) return
FALSE;
x += LOBYTE(data);
y += HIBYTE(data);
break;

default:
char ch;
for (BYTE i = 0; i < SecondByte; i++)
{
if (!fil.get(ch)) return FALSE;
pDest[paddedwidth
*
y
+
x++]
=
(BYTE)ch;
}
if ((SecondByte % 2) == 1)
if (!fil.get(ch)) return FALSE;
}
}
else
{
for (BYTE i = 0; i < FirstByte; i++)
pDest[paddedwidth * y + x++] = SecondByte;
}
}
return FALSE;
}


2.2 Phương pháp mã hoá Huffman:
2.2.1 Nguyên tắc:
Phương pháp mã hoá Huffman là phương pháp dựa vào mô hình thống kê.

Người ta tính tần suất xuất hiện của các ký tự bằng cách duyệt tuần tự từ đầu tệp gốc
đến cuối tệp. Việc xử lý ở đây tính theo bit. Trong phương pháp này các ký tự có tần
suất cao một từ mã ngắn, các ký tự có tần suất thấp một từ mã dài. Như vậy với cách
thức này ta đã làm giảm chiều dài trung bình của từ mã hoá bằng cách dùng chiều dài
biến đổi tuy nhiên cũng có trường hợp bị thiệt 1 ít bit khi tần suất là rất thấp.
2.2.2 Thuật toán:
• Thuật toán mã hoá Huffman gồm 2 bước chính:
• Bước một:
Tính tần suất của các ký tự trong dữ liệu gốc bằng cách duyệt tệp gốc một cách
tuần tự từ đầu đến cuối để xây dựng bảng mã và tính toán tần suất. Tiếp theo sau là sắp
xếp lại bảng mã theo thứ tự tần suất giảm dần.
• Bước hai:
Duyệt bảng tấn suất từ cuối lên đầu để thực hiện ghép hai phần tử có tần suất
thấp thành một phần tử duy nhất có tần suất bằng tổng hai tần suất thành phần. Cập
nhật phần tử này vào vị trí phù hợp trong bảng và loại bỏ hai phần tử đã xét. Thực hiện
cho đến khi bảng chỉ có một phần tử. Đây là quá trình tạo cây nhị phân Huffman ,phần
tử có tần suất thấp ở bên phải, phần tử kia ở bên trái. Sau khi cây đã tạo xong người ta
tiến hành gán mã cho các nút lá. Việc mã hoá thực hiện theo quy định: mỗi lần xuống
bên phải ta thêm một bit ‘1’ vào từ mã, mỗi lần xuống bên trái ta thêm một bit‘0’ vào
từ mã.
Quá trình giải nén cũng khá đơn giản được tiến hành theo chiều ngược lại.
Người ta cũng phải dựa vào bảng mã tạo ra trong giai đoạn nén (bảng này được lưu trữ
trong cấu trúc đầu của tệp nén cùng với dữ liệu nén).
Ví dụ: Một tệp bất kỳ có tần suất xuất hiện của các kí tự số như bảng sau


Ký tự

Tần suất


0

1532

1

152

2

323

3

412

4

226

5

385

6

602

7


92

8

112

9

87

Bảng tần suất sắp xếp giảm dần

Ký tự

Xác suất(%)

0

0.3906

6

0.1535

3

0.1051

5


0.0982

2

0.0824

4

0.0577

1

0.0388

8

0.0286

7

0.0235

9

0.0222


Mô tả: Ta tiến hành hợp nhất hay cộng 2 tần suất nhỏ nhất ở cuối bảng để thu
được giá trị tần suất mới sau đó đưa giá trị này trở lại bảng tần suất ban đầu đã bỏ đi 2
tần suất thành phần tạo thành nó. Sau khi đưa giá trị mới vào bảng ta phải tiến hành

sắp xếp lại toàn bộ bảng, lúc này số lượng tần suất chỉ còn là n-1 nếu ban đầu số lượng
tần suất là n. Tiếp tục thực hiện lần lượt theo thứ tự như trên cho đến khi nào số lượng
tần suất chỉ còn lại duy nhất 1 giá trị.
Việc tạo cây nhị phân có thể được thực hiện theo một thuật toán sau:
1. Tất cả những ký tự ban đầu được xem như là những ký tự giao điểm tự do.
2. Hai nút tự do với tần số xuất hiện thấp nhất được phân công tới một nút gốc
với giá trị bằng với tổng của hai nút con tự do.
3. Hai nút con được chuyển khỏi danh sách nút tự do. Chuyển nút gốc mới tạo
thành công vào danh sách.
4. Bước hai sang bước ba được lặp cho đến khi chỉ có 1 nút tự do về phía trái.
Nút tự do này là gốc của cây.
Bảng từ mã gán cho các kí tự số như sau:

Kí tự




0

1

6

001

3

011


5

0001

2

0100

4

00000

1

01010

8

01011

7

000010

9

000011

Như vậy với ví dụ sau đây ta có thể tiến hành mã hoá như sau:
Chuỗi nguồn: 00000000006666693333


kích thước = 20*8=160 bit

Sử dụng mã Huffman theo bảng trên
kích thước =10*1+5*3+1*6+4*3= 43 bit
Vì giá trị 0 xuất hiện 10 lần nhưng chỉ dùng 1 bit để thể hiện, giá trị 6 xuất hiện
5 lần dùng 3 bit để thể hiện, giá trị 9 dùng 6 bit và giá trị 3 xuất hiện 4 lần dùng 3 bit
để thể hiện.
Tỷ số nén = 160 / 43 = 3.7
Trong phương pháp mã Huffman mã của ký tự là duy nhất và không mã nào là
phần bắt đầu của mã trước.Vì vậy khi đọc theo từng bit từ đầu đến cuối tệp nén ta có
thể duyệt cây mã cho đến một lá, tức là ký tự đã được giải mã. Việc giải mã chắc chắn
phải sử dụng cây nhị phân giống như trong mã hoá. Để đọc, giải mã được yêu cầu phải
sử dụng theo đúng tiêu chuẩn nhất định .
`2.2.3 Một số thủ tục chương trình:
• Chương trình nén phương pháp HUFFMAN:
bool CompressHuffman(BYTE*pSrc, int nSrcLen, BYTE *&pDes,
int
&nDesLen)
{
CHuffmanNode nodes[511];
for(int nCount = 0; nCount < 256; nCount++)
nodes[nCount].byAscii = nCount;
for(nCount = 0; nCount < nSrcLen; nCount++)


nodes[pSrc[nCount]].nFrequency++;
qsort(nodes,
256,
sizeof(CHuffmanNode),

frequencyCompare);
int nNodeCount = GetHuffmanTree(nodes);
int nNodeSize = sizeof(DWORD)+sizeof(BYTE);
nDesLen = nSrcLen+nNodeCount*nNodeSize;
pDes = (BYTE*)malloc(nDesLen);
BYTE *pDesPtr = pDes;
memset(pDesPtr, 0, nDesLen);
*(DWORD*)pDesPtr = nSrcLen;
pDesPtr += sizeof(DWORD);
*pDesPtr = nNodeCount-1;
pDesPtr += sizeof(BYTE);
for(nCount = 0; nCount < nNodeCount; nCount++)
{
memcpy(pDesPtr, &nodes[nCount], nNodeSize);
pDesPtr += nNodeSize;
}
qsort(nodes, 256, sizeof(CHuffmanNode), asciiCompare);
int nDesIndex = 0;
for(nCount = 0; nCount < nSrcLen; nCount++)
{
*(DWORD*)(pDesPtr+(nDesIndex>>3))|
=nodes[pSrc[nCount]].dwCode<<
(nDesIndex&7);
nDesIndex += nodes[pSrc[nCount]].nCodeLength;
}
nDesLen = (pDesPtr-pDes)+(nDesIndex+7)/8;
pDes = (BYTE*)realloc(pDes, nDesLen);
return true;
}
•Chương trình giải nén phương pháp HUFFMAN :

bool DecompressHuffman(BYTE*pSrc,int nSrcLen,BYTE*&pDes,
int
&nDesLen)
{
nDesLen = *(DWORD*)pSrc;
pDes = (BYTE*)malloc(nDesLen+1);
int nNodeCount = *(pSrc+sizeof(DWORD))+1;
CHuffmanNode nodes[511], *pNode;
int nNodeSize = sizeof(DWORD)+sizeof(BYTE), nSrcIndex
= nNodeSize;
for(int nCount = 0; nCount < nNodeCount; nCount++)
{
memcpy(&nodes[nCount],
pSrc+nSrcIndex,
nNodeSize);
nSrcIndex += nNodeSize;
}
GetHuffmanTree(nodes, false);
CHuffmanNode *pRoot = &nodes[0];


while(pRoot->pParent)
pRoot = pRoot->pParent;
int nDesIndex = 0;
DWORD nCode;
nSrcIndex <<= 3;
while(nDesIndex < nDesLen)
{
nCode
=

(*(DWORD*)(pSrc+
(nSrcIndex>>3)))>>(nSrcIndex&7);
pNode = pRoot;
while(pNode->pLeft)
{
pNode = (nCode&1) ? pNode->pRight : pNode>pLeft;
nCode >>= 1;
nSrcIndex++;
}
pDes[nDesIndex++] = pNode->byAscii;
}
return true;
}

2.3 Phương pháp mã hoá LZW:
Khái niệm nén từ điển được Jocob Lempe và Abraham Ziv đưa ra lần đầu tiên
năm 1977 sau đó phát triển thành một họ giải thuật nén từ điển LZ. Năm 1984 Welch
đã cải tiến giải thuật LZ thành giải thuật mới hiệu quả hơn và được đặt tên là LZW
( Lempe – Ziv - Welch). Phương pháp này xây dựng từ điển lưu các chuỗi ký tự có tần
suất lặp lại cao và thay thế bằng từ mã tương ứng mỗi khi gặp lại chúng, nó hay hơn
các phương pháp trước đó ở kỹ thuật tổ chức từ điển cho phép nâng cao tỷ lệ nén.
Giải thuật LZW được dùng cho tất cả các loại file nhị phân, thườngđược dùng
để nén các loại dữ liệu như: văn bản, ảnh đen trắng, ảnh màu, ảnh đa cấp sám…và là
chuẩn nén cho các dạng ảnh GIF và TIFF. Số bit/pixel không ảnh hưởng đến hiệu quả
của LZW.
2.3.1 Nguyên tắc:
Giải thuật nén LZW xây dựng một từ điển lưu các mẫu có tần suất xuất hiện
cao trong ảnh. Từ điển là tập hợp những cặp (từ vựng và nghĩa của từ vựng). Trong đó
từ vựng sẽ là các từ mã được sắp xếp theo thứ tự nhất định. Nghĩa là một chuỗi con
trong dữ liệu ảnh. Từ điển được xây dựng song song với quá trình đọc dữ liệu. Sự xuất

hiện của chuỗi con trong từ điển khẳng định rằng chuỗi đó đã từng xuất hiện trong
phần dữ liệu đã đựoc đọc qua. Thuật toán liên tục tra cứu và sau mỗi lần đọc một ký tự
ở dữ liệu đầu vào thì tiến hành cập nhật lại từ điển.


Do giới hạn của bộ nhớ và để đảm bảo tốc độ tìm kiếm nhanh, từ điển chỉ giới
hạn 4096 phần tử dùng để lưu trữ giá trị của các từ mã. Như vậy độ dài lớn nhất của từ
mã là 12 bit (4096=212). Cấu trúc từ điển như sau:
Bảng 1: Cấu trúc từ điển

0
1


255
256
257
Chuỗi
Chuỗi


Chuỗi
• 256 từ mã đầu tiên theo thứ tự từ 0…255 chứa các số nguyên từ 0…255. Đây
là mã của 256 kí tự cơ bản trong bảng mã ASCII.
• Từ mã thứ 256 chứa một mã đặc biệt là mã xoá (CC - Clear Code). Khi số
mẫu lặp lớn hơn 4096 thì người ta sẽ coi ảnh gồm nhiều mảnh ảnh và từ điển sẽ gồm
nhiều từ điển con. Khi hết một mảnh ảnh sẽ gửi 1 mã xoá (CC)để báo hiệu kết thúc
mảnh ảnh cũ và bắt đầu mảnh ảnh mới đồng thời sẽ khởi tạo lại từ điển.
• Từ mã thứ 257 chứa mã kết thúc thông tin (EOI - End Of Information). Thông
thường một file ảnh GIF có thể chứa nhiều mảnh ảnh, mỗi mảnh ảnh này sẽ được mã

hoá riêng. Chương trình giải mã sẽ lặp đi lặp lại thao tác giải mã từng ảnh cho đến khi
gặp mã kết thúc thông tin thì dừng lại.
• Các từ mã còn lại (từ 258 đến 4095) chứa các mẫu thường lặp lại trong ảnh. 512 phần
tử đầu tiên của từ điển biểu diễn bằng 9 bit. Các từ mã từ 512 đến 1023 biểu diễn bởi
10 bit, từ 1024 đến 2047 biểu diễn bởi 11 bit, và từ 2048 đến 4095 biểu diễn bởi 12 bit.
Ví dụ: Cho chuỗi đầu vào “HELLOHELLOHELL”
Từ điền ban đầu đã gồm 256 kí tự cơ bản.
Kích thước đầu vào: 14 x 8 = 112 bit.
ĐẦU VÀO

ĐẦU RA

THỰC HIỆN


H(72)
E(69)
L(76)
L
O(79)
H
E
L

258

H đã có trong từ điển
đọc tiếp
Thêm vào từ điển mã 258 đại diện cho chuỗi HE
Thêm vào từ điển mã 259 đại diện cho chuỗi EL

Thêm vào từ điển mã 260 đại diện cho chuỗi LL
Thêm vào từ điển mã 261 đại diện cho chuỗi LO
Thêm vào từ điển mã 262 đại diện cho chuỗi OH
HE đã có trong từ điển
đọc tiếp
Thêm vào từ điển mã 263 đại diện cho chuỗi

260

HEL
LL đã có trong từ điển
đọc tiếp
Thêm vào từ điển mã 264 đại diện cho chuỗi

262

LLO
OH đã có trong từ điển
đọc tiếp
Thêm vào từ điển mã 265 đại diện cho chuỗi

259

OHE
EL đã có trong từ điển
đọc tiếp
Thêm vào từ điển mã 266 đại diện cho chuỗi

72
69

76
76
79

L
O
H
E
L
L

ELL
Input = FALSE

76
EOI

Chuỗi đầu ra là: 72 69 76 76 79 258 260 262 259 76
Kích thước đầu ra: 6 x 8 + 4 x 9 = 84 bit
Tỷ số nén: 112 / 84 = 1.3
Quá trình giải nén thực hiện như sau:
Code

OutBuff()

AddToDictionary()
CodeWord

72
69

76
76
79
258
260
262
259
76
EOI

H
E
L
L
O
HE
LL
OH
EL
L

258
259
260
261
262
263
264
265
266


String
HE
EL
LL
LO
OHE
HEL
LLO
OHE
ELL

Chuỗi thu được sau giải nén: ”HELLOHELLOHELL”


×