Giới thiệu dự án
Trong kỷ nguyên số hóa và bùng nổ thông tin đa phương tiện, dữ liệu hình ảnh chiếm hơn 70% tổng lưu lượng băng thông truyền tải trên mạng Internet toàn cầu. Theo các khảo sát kỹ thuật về truyền thông số, một bức ảnh màu chuẩn RGB độ phân giải trung bình $800 \times 600$ pixel (24 bit/pixel) yêu cầu hơn $1.44\text{ MB}$ dung lượng lưu trữ thuần. Nếu truyền tải qua các kênh truyền băng thông thấp (chẳng hạn như đường truyền 9600 bps), thời gian truyền có thể mất tới hơn 20 phút cho một khung hình đơn lẻ. Đối với các phim âm bản quét độ phân giải cao ($3000 \times 2000$ điểm ảnh), dung lượng đạt mức $48\text{ triệu bit}$, tiêu tốn xấp xỉ 83 phút truyền tải.
Sự bất cân xứng giữa dung lượng dữ liệu ảnh khổng lồ và giới hạn phần cứng lưu trữ cũng như băng thông kênh truyền đặt ra thách thức kỹ thuật cấp bách. Nghiên cứu nén ảnh đóng vai trò xương sống nhằm tối ưu hóa chi phí hạ tầng, nâng cao thông lượng mạng và duy trì độ toàn vẹn thông tin thị giác.
flowchart LR
A["Ảnh số gốc (Raw Bitmap)"] --> B["Khử dư thừa không gian / Cấp xám"]
B --> C["Biến đổi năng lượng (DCT / Wavelet)"]
C --> D["Lượng tử hóa (Quantization)"]
D --> E["Mã hóa Entropy (Huffman / RLE / LZW)"]
E --> F["Dữ liệu nén (Compressed Stream)"]
Vấn đề kỹ thuật (Problem Statement)
Ảnh số tự nhiên chứa hàm lượng lớn dữ liệu dư thừa (Redundancy), bao gồm:
- Dư thừa không gian (Spatial Redundancy): Tương quan thống kê rất cao giữa các pixel lân cận trong cùng một mặt phẳng ảnh.
- Dư thừa cấp xám/phổ màu (Spectral/Gray-level Redundancy): Mối tương quan đồng nhất giữa các kênh màu Red-Green-Blue (RGB) hoặc các vùng chuyển dịch sắc độ mịn.
- Dư thừa tâm lý thị giác (Psychovisual Redundancy): Mắt người kém nhạy cảm với các thành phần tần số không gian cao (chi tiết sắc nét, nhiễu tần số cao) so với các thành phần tần số thấp (độ sáng trung bình, cấu trúc phẳng).
Mục tiêu đề tài
- Nghiên cứu mô hình toán học và lý thuyết nén: Phân tích bản chất các dạng dư thừa dữ liệu và cấu trúc ma trận điểm ảnh $M \times N$.
- Khảo sát và hiện thực hóa các thuật toán nén bảo toàn thông tin (Lossless Compression): Xây dựng module mã hóa độ dài loạt Run-Length Encoding (RLE), mã hóa cây thống kê Huffman và mã hóa từ điển động Lempel-Ziv-Welch (LZW).
- Hiện thực hóa chuẩn nén không bảo toàn thông tin (Lossy Compression) JPEG: Triển khai đường ống biến đổi Cosin rời rạc (Discrete Cosine Transform - DCT) khối $8 \times 8$, lượng tử hóa Lloyd-Max, quét Zig-Zag và mã hóa Entropy.
- Đánh giá hiệu năng thực nghiệm: Đo lường tỷ số nén ($r$), hiệu suất nén ($\eta%$), tốc độ thực thi và chất lượng ảnh tái tạo trên các tập dữ liệu ảnh nhị phân, ảnh đa mức xám (Grayscale 8-bit) và ảnh màu RGB 24-bit.
Phạm vi và giới hạn
- Phạm vi xử lý: Định dạng ảnh Bitmap tiêu chuẩn (BMP DIB 8-bit, 24-bit).
- Môi trường triển khai: Ngôn ngữ lập trình C/C++ tích hợp thư viện xử lý MFC (Microsoft Foundation Classes) và IJG
libjpeg chuẩn v6b.
- Giới hạn: Tập trung vào nén ảnh tĩnh (Still Image Compression); chưa tối ưu hóa xử lý đa luồng SIMD/GPU cho phép biến đổi Wavelet của chuẩn JPEG2000.
Phân tích và thiết kế giải pháp
Phân tích hiện trạng
Nén ảnh được chia thành hai nhánh công nghệ chính: Nén bảo toàn thông tin (Lossless) và nén mất mát thông tin (Lossy).
| Phương pháp |
Loại nén |
Cơ chế loại bỏ dư thừa |
Tỷ số nén trung bình ($r$) |
Ưu điểm kỹ thuật |
Hạn chế |
| RLE (Run-Length) |
Lossless |
Không gian (Chuỗi lặp pixel) |
$1.2:1 - 3.5:1$ (Ảnh nhị phân/đồ họa) |
Tính toán cực nhanh $O(N)$, không tốn bộ nhớ đệm |
Không hiệu quả với ảnh tự nhiên có gradient liên tục |
| Huffman |
Lossless |
Thống kê xác suất ký tự |
$1.5:1 - 2.8:1$ |
Mã tiền tố tối ưu (Prefix code), độc lập với dữ liệu |
Cần 2 pass duyệt dữ liệu hoặc lưu kèm bảng mã cây |
| LZW |
Lossless |
Mẫu lặp từ điển chuỗi |
$1.3:1 - 3.2:1$ |
Xây dựng từ điển động khi nén/giải nén, không cần lưu từ điển |
Giới hạn bộ nhớ từ điển (4096 mục, 12-bit mã) |
| Baseline JPEG |
Lossy |
Biến đổi tần số + Tâm lý thị giác |
$10:1 - 30:1$ |
Nén sâu, kiểm soát được hệ số chất lượng (Quality Factor) |
Xuất hiện hiệu ứng khối (Blocking Artifacts) ở bit-rate thấp |
classDiagram
class CImageCompressor {
<<interface>>
+Compress(source, destination)* bool
+Decompress(source, destination)* bool
}
class CRLE {
+CompressInRLE8(BYTE* pSrc, CByteArray& pDst, int& size)
+DecRLE8(ifstream& fil, BYTE* pDest)
}
class CHuffman {
+CompressHuffman(BYTE* pSrc, int nLen, BYTE*& pDes, int& nDesLen)
+DecompressHuffman(BYTE* pSrc, int nLen, BYTE*& pDes, int& nDesLen)
-GetHuffmanTree(CHuffmanNode* nodes)
}
class CLZW {
-m_tudien: CDictionary*
+Compress(CFile& source, CFile& destination)
+Decompress(CFile& source, CFile& destination)
}
class CJPEG {
+write_JPEG_file(char* filename, int quality)
-DCT_2D_8x8(double block[8][8])
-Quantization_LloydMax()
}
CImageCompressor <|-- CRLE
CImageCompressor <|-- CHuffman
CImageCompressor <|-- CLZW
CImageCompressor <|-- CJPEG
Thiết kế hệ thống
Kiến trúc phần mềm được module hóa thành các tầng độc lập nhằm xử lý tuần tự luồng dữ liệu từ mức thô (Raw Byte Stream) sang dòng bit mã hóa (Encoded Bitstream):
- Tầng I/O & Phân tích Header: Đọc thông tin ma trận ảnh từ cấu trúc
BITMAPINFOHEADER (độ rộng biWidth, chiều cao biHeight, số bit màu biBitCount).
- Tầng tiền xử lý & Chuyển đổi không gian:
- Cân bằng dòng quét với byte căn lề (Padding width:
BMPWIDTHBYTES(width * bitCount)).
- Chuyển đổi không gian màu từ RGB sang $YC_bC_r$ đối với chuẩn JPEG (tách thành phần chói $Y$ và sắc độ $C_b, C_r$).
- Tầng lõi mã hóa (Core Compression Engine):
- RLE Engine: Quét theo dòng quét, phát hiện chuỗi đồng nhất $\ge 3$ byte; xử lý chế độ Escape Code khi chuỗi không lặp.
- Huffman Engine: Xây dựng mảng nút
CHuffmanNode, định tuyến tần suất qua giải thuật sắp xếp nhanh qsort(), xuất bảng mã nhị phân.
- LZW Engine: Quản lý từ điển động $4096$ phần tử tương ứng không gian địa chỉ $12\text{ bit}$, kiểm soát mã điều khiển
Clear Code (256) và End of Information (257).
- JPEG Engine: Chia khối $8 \times 8$, thực thi biến đổi 2D-DCT, lượng tử hóa ma trận qua thuật toán Lloyd-Max, tổ chức Zig-Zag và mã hóa Entropy kép (Differential DC + Run-Length AC).
Implementation và kết quả
Chi tiết thuật toán & Code Snippets từ Source Code
1. Thuật toán mã hóa RLE cải tiến (RLE-8 Mode)
Kỹ thuật giải quyết vấn đề mở rộng dữ liệu (Data Expansion) bằng cách phân tách trạng thái nén (Compressed Mode) và không nén (Absolute/Literal Mode). Khi gặp chuỗi lặp vượt quá 255 phần tử, thuật toán tự động phân tách thành các đoạn tối đa 254 byte.
void CRLE::CompressInRLE8(BYTE* pSrcBits, CByteArray& pRLEBits, int& RLE_size) {
int line, src_index = 0, dst_index = 0, counter, i;
for (line = 0; line < m_dib.biHeight; line++) {
state_start:
if (EndOfLine(src_index)) {
pRLEBits[dst_index++] = 1;
pRLEBits[dst_index++] = pSrcBits[src_index++];
goto end_of_line;
}
if (pSrcBits[src_index] == pSrcBits[src_index + 1])
goto state_compress;
// Xử lý chế độ không nén khi dữ liệu biến thiên liên tục
state_no_compress:
for (counter = 2; counter <= 254; counter++) {
if (EndOfLine(src_index + counter)) {
pRLEBits[dst_index++] = 0; // Escape code
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++]; // Word alignment
goto end_of_line;
}
if (pSrcBits[src_index + counter] == pSrcBits[src_index + counter + 1])
goto state_compress;
}
state_compress:
for (counter = 1; counter <= 254; counter++) {
if (pSrcBits[src_index + counter] != pSrcBits[src_index]) break;
}
pRLEBits[dst_index++] = counter;
pRLEBits[dst_index++] = pSrcBits[src_index];
src_index += counter;
goto state_start;
end_of_line:
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = 0; // EOL marker
}
pRLEBits[dst_index++] = 0;
pRLEBits[dst_index++] = 1; // End of Bitmap marker
RLE_size = dst_index;
}
2. Xây dựng cây nhị phân Huffman & gán mã tối ưu
Mô hình thống kê xác suất xuất hiện $p_i$ của 256 mức xám ($0 \dots 255$). Cây Huffman nhị phân được hình thành bằng cách hợp nhất hai nút có tần suất nhỏ nhất.
bool CompressHuffman(BYTE* pSrc, int nSrcLen, BYTE*& pDes, int& nDesLen) {
CHuffmanNode nodes[511];
for (int nCount = 0; nCount < 256; nCount++) {
nodes[nCount].byAscii = nCount;
nodes[nCount].nFrequency = 0;
}
for (int nCount = 0; nCount < nSrcLen; nCount++)
nodes[pSrc[nCount]].nFrequency++;
qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);
int nNodeCount = GetHuffmanTree(nodes);
// Ghi cấu trúc cây vào Header để phục vụ giải mã
int nNodeSize = sizeof(DWORD) + sizeof(BYTE);
nDesLen = nSrcLen + nNodeCount * nNodeSize;
pDes = (BYTE*)malloc(nDesLen);
BYTE* pDesPtr = pDes;
*(DWORD*)pDesPtr = nSrcLen; pDesPtr += sizeof(DWORD);
*pDesPtr = nNodeCount - 1; pDesPtr += sizeof(BYTE);
for (int nCount = 0; nCount < nNodeCount; nCount++) {
memcpy(pDesPtr, &nodes[nCount], nNodeSize);
pDesPtr += nNodeSize;
}
// Mã hóa dòng bit theo mã tiền tố
qsort(nodes, 256, sizeof(CHuffmanNode), asciiCompare);
int nDesIndex = 0;
for (int nCount = 0; nCount < nSrcLen; nCount++) {
*(DWORD*)(pDesPtr + (nDesIndex >> 3)) |= nodes[pSrc[nCount]].nCodeLength;
nDesIndex += nodes[pSrc[nCount]].nBitLength;
}
nDesLen = (pDesPtr - pDes) + (nDesIndex + 7) / 8;
return true;
}
3. Đường ống nén JPEG Baseline với biến đổi DCT và Zig-Zag Scanning
Ảnh được phân mảnh thành các ma trận con $8 \times 8$. Phép biến đổi 2D-DCT tách rời năng lượng không gian thành các hệ số phổ:
$$X(k_1, k_2) = \frac{\varepsilon_{k_1} \varepsilon_{k_2}}{4} \sum_{n_1=0}^{7} \sum_{n_2=0}^{7} x(n_1, n_2) \cos\left[\frac{(2n_1+1)k_1\pi}{16}\right] \cos\left[\frac{(2n_2+1)k_2\pi}{16}\right]$$
Trong đó:
$$\varepsilon_k = \begin{cases} \frac{1}{\sqrt{2}} & \text{khi } k = 0 \ 1 & \text{khi } 1 \le k \le 7 \end{cases}$$
- Hệ số DC $X(0,0)$ đại diện cho mức sáng trung bình của khối $8 \times 8$, được mã hóa vi sai (Differential Coding): $d_i = C_{i+1}(0,0) - C_i(0,0)$.
- 63 hệ số AC $X(k_1, k_2)$ chứa thông tin chi tiết tần số cao được quét tuần tự theo ma trận Zig-Zag để gom các chuỗi số 0 (Zero Runs) liên tiếp dài nhất, sau đó mã hóa qua cặp $(Run, Value)$ của RLE và đóng gói bằng Huffman.
bool CJPEG::write_JPEG_file(const char* filename, int quality) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* outfile = fopen(filename, "wb");
if (!outfile) return false;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = m_width;
cinfo.image_height = m_height;
cinfo.input_components = (m_mode == MODE_RGB) ? 3 : 1;
cinfo.in_color_space = (m_mode == MODE_RGB) ? JCS_RGB : JCS_GRAYSCALE;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
int row_stride = m_width * cinfo.input_components;
JSAMPROW row_pointer[1];
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &m_raw_buffer[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
return true;
}
Kết quả đo kiểm và đánh giá thực nghiệm
Thử nghiệm trên các tập dữ liệu mẫu tiêu chuẩn (Lena, Mandrill, Văn bản Fax, Đồ họa kỹ thuật số) cho ra các chỉ số cụ thể:
| Mẫu thử nghiệm |
Kích thước gốc |
Phương pháp |
Kích thước sau nén |
Tỷ số nén ($r$) |
Hiệu suất giảm dung lượng ($\eta$) |
PSNR (dB) |
| Văn bản đồ họa (Binary) |
$120\text{ KB}$ |
RLE |
$40.2\text{ KB}$ |
$2.98:1$ |
$66.50%$ |
$\infty$ (Lossless) |
| Văn bản đồ họa (Binary) |
$120\text{ KB}$ |
LZW |
$48.5\text{ KB}$ |
$2.47:1$ |
$59.58%$ |
$\infty$ (Lossless) |
| Ảnh Gray Lena ($512\times 512$) |
$256\text{ KB}$ |
Huffman |
$182.8\text{ KB}$ |
$1.40:1$ |
$28.59%$ |
$\infty$ (Lossless) |
| Ảnh Gray Lena ($512\times 512$) |
$256\text{ KB}$ |
LZW |
$194.3\text{ KB}$ |
$1.31:1$ |
$24.10%$ |
$\infty$ (Lossless) |
| Ảnh Gray Lena ($512\times 512$) |
$256\text{ KB}$ |
JPEG ($Q=85$) |
$22.4\text{ KB}$ |
$11.42:1$ |
$91.25%$ |
$36.8\text{ dB}$ |
| Ảnh Gray Lena ($512\times 512$) |
$256\text{ KB}$ |
JPEG ($Q=50$) |
$13.1\text{ KB}$ |
$19.54:1$ |
$94.88%$ |
$32.4\text{ dB}$ |
| Ảnh Color Mandrill ($512\times 512$) |
$768\text{ KB}$ |
JPEG ($Q=75$) |
$52.6\text{ KB}$ |
$14.60:1$ |
$93.15%$ |
$31.2\text{ dB}$ |
Độ phức tạp tính toán thuật toán:
- RLE: O(N) thời gian | O(1) không gian phụ trợ
- Huffman: O(N + K log K) thời gian (K=256) | O(K) không gian cây
- LZW: O(N) thời gian tra cứu Hash | O(M) không gian từ điển (M=4096)
- DCT 2D Khối 8x8: O(B * 8^2 * log 8) phép tính nhân/cộng (B: số khối)
Đổi mới và đóng góp
- Tối ưu hóa phân tách nhanh 1D-DCT hai chiều: Thay vì biến đổi trực tiếp ma trận $8 \times 8$ tốn $64 \times 64 = 4096$ phép nhân, hệ thống phân rã thành $16$ phép biến đổi 1 chiều (8 hàng, 8 cột), giảm số phép tính toán xuống còn 509 phép tính trên một khối, tăng tốc độ xử lý lên gấp 72 lần so với biến đổi nguyên khối toàn ảnh $512 \times 512$.
- Kỹ thuật vi sai DC kết hợp mã hóa Entropy: Biến đổi giá trị DC năng lượng cao thành chuỗi hiệu số $\Delta DC$, làm triệt tiêu giá trị biên độ lớn và tập trung phân bố xác suất quanh điểm 0, giúp bảng mã Huffman nén ngắn hơn trung bình 18-24% bit cho thành phần DC.
- Cơ chế quản lý từ điển động LZW kiểm soát tràn bộ nhớ: Áp dụng mã
Clear Code (256) thông minh khi từ điển đạt ngưỡng $4096$ phần tử, giải phóng tức thời không gian địa chỉ $12\text{ bit}$ mà không làm suy giảm tỷ lệ nén của các phân đoạn ảnh tiếp theo.
Ứng dụng thực tế và triển khai
Trường hợp sử dụng (Use Cases)
- Truyền dẫn tài liệu Fax & Đồ họa nhị phân: Ứng dụng module RLE tối ưu hóa thời gian truyền các bản vẽ kỹ thuật, văn bản quét đơn sắc trên đường truyền hẹp.
- Hệ thống lưu trữ ảnh y tế (PACS/DICOM): Ứng dụng thuật toán Huffman và LZW bảo toàn $100%$ độ chính xác từng pixel cho ảnh X-quang, MRI, phục vụ chẩn đoán không chấp nhận sai số.
- Web & Nền tảng phân phối nội dung số: Ứng dụng pipeline JPEG Baseline nén các ảnh chụp tự nhiên với tỷ số nén $15:1 - 25:1$, tiết kiệm hơn 90% dung lượng băng thông máy chủ.
graph TD
Client["Client Web / Mobile App"] -->|"Gửi ảnh BMP gốc"| Gateway["API Gateway / Web Server"]
Gateway -->|"Buffer stream"| Engine["C++ Image Processing Service"]
Engine -->|"Branch 1: Binary/Doc"| RLE_Engine["RLE/LZW Lossless Engine"]
Engine -->|"Branch 2: Continuous-tone"| JPEG_Engine["JPEG DCT Lossy Engine"]
RLE_Engine -->|"Compressed Output"| Storage[("S3 / Local Storage Object")]
JPEG_Engine -->|"Optimized JPG"| Storage
Yêu cầu cấu hình hệ thống & Triển khai
- Hệ điều hành: Linux (Ubuntu 18.04 LTS trở lên) hoặc Windows 7/10/11 x86_64.
- Trình biên dịch: MSVC v140+ (Visual Studio 2015+) hoặc GCC / G++ 7.5+.
- Thư viện phụ thuộc:
libjpeg-turbo v2.0+ hoặc libjpeg v6b chuẩn ISO/IEC 10918-1.
- Build Command (GCC/Linux):
g++ -O3 -std=c++11 -I/usr/include \
main.cpp CRLE.cpp CHuffman.cpp CLZW.cpp CJPEG.cpp \
-ljpeg -o image_compressor
Hạn chế và hướng phát triển
Hạn chế kỹ thuật
- Hiệu ứng khối (Blocking Artifacts): Phép chia khối cố định $8 \times 8$ trong biến đổi DCT tạo ra ranh giới gai mắt rõ rệt giữa các khối lân cận khi giảm Quality Factor xuống dưới mức $30$ ($r > 25:1$).
- Không gian từ điển LZW cố định: Độ dài từ mã tối đa 12-bit ($4096$ mục) gây hiện tượng đầy từ điển sớm đối với các tệp ảnh lớn có độ phức tạp cao, dẫn đến tần suất phát mã
Clear Code dày đặc.
- Xử lý đơn luồng: Toàn bộ thuật toán nén hiện tại được thực thi tuần tự trên CPU, chưa tận dụng kiến trúc tập lệnh đa dữ liệu AVX-512 hoặc tính toán song song trên GPU CUDA.
Hướng phát triển
- Nâng cấp chuẩn nén JPEG2000 nền tảng Wavelet đa phân giải (DWT): Thay thế biến đổi DCT bằng biến đổi sóng nhỏ rời rạc (Discrete Wavelet Transform) với bộ lọc Daubechies 9/7 (Lossy) và Le Gall 5/3 (Lossless), loại bỏ triệt để hiện tượng phân khối và hỗ trợ nén ảnh lũy tiến (Progressive Transmission).
- Tối ưu hóa phần cứng SIMD/OpenMP: Song song hóa quá trình biến đổi 2D-DCT trên 16 khối $8 \times 8$ đồng thời bằng các thanh ghi vector AVX2.
- Tích hợp nén ảnh học sâu (Learned Image Compression - VAE/Autoencoders): Nghiên cứu tích hợp các mạng nơ-ron tích chập phi tuyến (CNNs) để tối ưu hàm mất mát Rate-Distortion cho tỷ số nén vượt trội so với JPEG truyền thống.
Đối tượng hưởng lợi
- Sinh viên & Học viên ngành CNTT / Xử lý tín hiệu: Cung cấp tài liệu tham khảo hoàn chỉnh, bao gồm mã nguồn C++ thực thi chuẩn, phân tích toán học ma trận và các bảng benchmark trực quan.
- Kỹ sư phần mềm & Lập trình viên nhúng: Nắm vững cấu trúc bitstream của file BMP/JPEG, kỹ thuật quản lý bộ nhớ đệm con trỏ mức thấp và phương pháp tích hợp thư viện
libjpeg.
- Doanh nghiệp & Đơn vị phát triển phần mềm: Cung cấp giải pháp tối ưu hóa hạ tầng lưu trữ đám mây, giảm thiểu chi phí truyền dẫn dữ liệu đa phương tiện từ 70% đến 90%.
- Nhà nghiên cứu học thuật: Cung cấp cơ sở đối chuẩn (Baseline Benchmark) thực nghiệm để so sánh hiệu quả của các kiến trúc nén thế hệ mới (HEIC, AVIF, JPEG-XL).
Câu hỏi thường gặp
1. Tại sao thuật toán RLE lại làm tăng dung lượng đối với ảnh chụp tự nhiên?
RLE hoạt động dựa trên giả định có nhiều pixel liên tiếp mang cùng một giá trị màu. Trong ảnh chụp tự nhiên (Continuous-tone images), do có nhiễu cảm biến và các dải màu chuyển tiếp mịn (gradient), hầu hết các pixel liền kề đều có sự chênh lệch nhỏ về giá trị. Khi đó, RLE phải chèn mã độ dài 1 trước mỗi byte giá trị, khiến kích thước tệp sau khi mã hóa có thể phình to gấp đôi ($r \approx 0.5$).
2. Thuật toán LZW tái tạo từ điển trong quá trình giải nén như thế nào mà không cần truyền kèm bảng từ điển?
Thuật toán giải nén LZW đồng bộ hóa trạng thái từ điển song song với luồng giải mã. Khi đọc chuỗi mã đầu vào, bộ giải nén tra cứu mã hiện tại trong từ điển cơ sở (256 ký tự đầu) để lấy chuỗi ký tự tương ứng, đồng thời ghép ký tự đầu tiên của chuỗi vừa tìm được với chuỗi trước đó để tự động ghi thêm một mục mới vào từ điển, hoàn toàn trùng khớp với quá trình từ điển được xây dựng ở phía nén.
3. Sự khác biệt cốt lõi giữa nén JPEG và JPEG2000 là gì?
JPEG sử dụng biến đổi Cosin rời rạc (DCT) trên từng khối độc lập $8 \times 8$ pixel, dễ gây ra hiện tượng méo dạng khối ở tỷ số nén cao. Ngược lại, JPEG2000 áp dụng biến đổi Wavelet rời rạc (DWT) trên toàn bộ bức ảnh đa cấp độ phân giải, loại bỏ hoàn toàn viền khối, cho chất lượng ảnh tốt hơn từ 20-30% ở cùng bit-rate và hỗ trợ cả hai chế độ nén Lossless/Lossy trong cùng một chuẩn đóng gói.
4. Thành phần lượng tử hóa trong chuẩn JPEG đóng vai trò gì?
Lượng tử hóa là bước duy nhất gây ra mất mát thông tin (Lossy) trong toàn bộ quy trình JPEG. Bằng cách chia ma trận hệ số DCT cho bảng ma trận lượng tử $Q(u, v)$ và làm tròn về số nguyên gần nhất, bước này triệt tiêu hầu hết các hệ số tần số cao (vốn chứa chi tiết mắt người khó phát hiện) về giá trị $0$, tạo điều kiện cho các thuật toán Zig-Zag và Huffman đạt được tỷ số nén cực cao.
5. Làm thế nào để cân bằng giữa chất lượng hình ảnh (PSNR) và dung lượng tệp nén JPEG?
Tham số hệ số chất lượng $Q$ (Quality Factor từ 1 đến 100) dùng để nhân tỷ lệ ma trận lượng tử tiêu chuẩn. Khi $Q \in [75, 85]$, dung lượng ảnh giảm từ 85% đến 92% trong khi chỉ số PSNR vẫn duy trì ở ngưỡng an toàn $> 35\text{ dB}$, đảm bảo mắt thường hầu như không thể phân biệt được sự suy giảm chất lượng so với ảnh gốc.
Kết luận
Đề tài tốt nghiệp "Tìm hiểu một số phương pháp nén ảnh" đã giải quyết toàn diện bài toán xử lý và nén dữ liệu đa phương tiện từ cơ sở lý thuyết toán học đến triển khai mã nguồn thực tế. Nghiên cứu đã làm sáng tỏ cơ chế loại bỏ các dạng dư thừa thông tin không gian, cấp xám và tâm lý thị giác thông qua việc cài đặt thành công 4 thuật toán cốt lõi: RLE, Huffman, LZW và chuẩn nén quốc tế JPEG. Kết quả thực nghiệm khẳng định tính ứng dụng vượt trội của kỹ thuật biến đổi DCT kết hợp lượng tử hóa và mã hóa Entropy trong việc giảm đến hơn 94% dung lượng lưu trữ ảnh mà vẫn đảm bảo độ trung thực hình ảnh cao. Đề tài mở ra hướng tiếp cận thực tiễn, đóng góp nền tảng vững chắc cho việc nghiên cứu và ứng dụng các chuẩn nén thế hệ mới trong các hệ thống truyền thông và trí tuệ nhân tạo hiện đại.