一、基于DCT的JPEG压缩(有损)
1. 核心步骤
- 图像分块:将图像划分为8×8的小块。
- 离散余弦变换(DCT):对每个块进行DCT变换。
- 量化:对DCT系数进行量化以减少高频信息。
- 熵编码:使用哈夫曼或算术编码压缩量化后的数据。
2. MATLAB代码实现
% 读取图像并转换为灰度图
img = imread('lena.jpg');
img_gray = rgb2gray(img);
img_double = im2double(img_gray); % 转换为double类型
% 定义JPEG量化表(标准亮度量化表)
Q = [16 11 10 16 24 40 51 61;
12 12 14 19 26 58 60 55;
14 13 16 24 40 57 69 56;
14 17 22 29 51 87 80 62;
18 22 37 56 68 109 103 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];
% 图像分块(8×8)
block_size = 8;
[rows, cols] = size(img_double);
num_blocks_row = floor(rows / block_size);
num_blocks_col = floor(cols / block_size);
blocks = mat2cell(img_double(1:num_blocks_row*block_size, 1:num_blocks_col*block_size), ...
repmat(block_size, 1, num_blocks_row), repmat(block_size, 1, num_blocks_col));
% DCT变换与量化
quantized_blocks = cell(size(blocks));
for i = 1:numel(blocks)
block = blocks{i};
dct_block = dct2(block); % DCT变换
quant_block = round(dct_block ./ Q); % 量化
quantized_blocks{i} = quant_block;
end
% 熵编码(使用MATLAB内置函数)
compressed_data = mat2huff(quantized_blocks(:)); % 哈夫曼编码
% 解码与重建(逆量化 + 逆DCT)
reconstructed_blocks = cell(size(quantized_blocks));
reconstructed_data = huff2mat(compressed_data); % 哈夫曼解码
reconstructed_data = reshape(reconstructed_data, size(quantized_blocks));
for i = 1:numel(blocks)
quant_block = reconstructed_data{i};
dequant_block = quant_block .* Q; % 反量化
idct_block = idct2(dequant_block); % 逆DCT
reconstructed_blocks{i} = idct_block;
end
% 合并分块并显示结果
reconstructed_img = cell2mat(reconstructed_blocks);
figure;
subplot(1,2,1); imshow(img_gray); title('原始图像');
subplot(1,2,2); imshow(reconstructed_img); title('重建图像');
% 计算PSNR
psnr_value = psnr(reconstructed_img, img_gray);
disp(['PSNR: ', num2str(psnr_value), ' dB']);
3. 关键说明
- 量化表:决定压缩率和图像质量,可根据需求调整。
- 分块处理:
mat2cell
函数用于分块,idct2
实现逆变换。 - 熵编码:使用MATLAB的
mat2huff
和huff2mat
实现哈夫曼编码。
二、基于DPCM的哈夫曼编码(无损)
1. 核心步骤
- 预测编码:使用前一个像素预测当前像素值,计算残差。
- 哈夫曼编码:对残差进行变长编码。
- 代码 图像压缩编码码matlab实现:DM编码、变换编码、算术编码、行程编码、Huffman编码、线性预测编码
2. MATLAB代码实现
% 读取图像
img = imread('lena.jpg');
img_gray = rgb2gray(img);
img_gray = im2double(img_gray);
% DPCM编码
pred = zeros(size(img_gray));
diff = zeros(size(img_gray));
pred(1) = img_gray(1);
diff(1) = img_gray(1) - pred(1);
for i = 2:numel(img_gray)
pred(i) = 0.5 * (img_gray(i-1) + img_gray(i)); % 线性预测
diff(i) = img_gray(i) - pred(i);
end
% 哈夫曼编码
[dict, avglen] = huffmandict(unique(diff), ... % 生成哈夫曼字典
arrayfun(@(x) normpdf(x, mean(diff(diff~=0)), std(diff(diff~=0))), unique(diff)));
compressed_data = huffmanenco(diff, dict);
% 解码
decoded_diff = huffmandeco(compressed_data, dict);
reconstructed_img = zeros(size(img_gray));
reconstructed_img(1) = img_gray(1);
for i = 2:numel(img_gray)
reconstructed_img(i) = reconstructed_img(i-1) + decoded_diff(i);
end
% 显示结果
figure;
subplot(1,2,1); imshow(img_gray); title('原始图像');
subplot(1,2,2); imshow(reconstructed_img); title('DPCM重建图像');
psnr_value = psnr(reconstructed_img, img_gray);
disp(['PSNR: ', num2str(psnr_value), ' dB']);
三、方法对比
方法 | 压缩类型 | 压缩率 | 图像质量 | 适用场景 |
---|---|---|---|---|
JPEG(DCT) | 有损 | 高 | 可控(依赖量化表) | 通用图像压缩 |
DPCM+哈夫曼 | 无损 | 低 | 完全保真 | 医学图像、卫星图像 |
四、扩展方向
- 改进JPEG:引入熵编码优化(如算术编码)或自适应量化表。
- 深度学习压缩:使用CNN学习图像特征进行端到端压缩。
- 混合压缩:结合有损和无损方法(如JPEG-LS)。
通过上述代码,您可以直接在MATLAB中实现图像压缩与重建,并通过调整参数(如量化表、预测模型)优化性能。