第十三、十四、十五次实验:用Matlab实现一幅灰度图像的压缩(即bmp格式转为jpg格式) 注意: 1.不能直接采用imwrite等函数一句话把图像进行压缩; 2. 代码中能体现DCT、huffman等步骤,步骤中功能函数可以直接调用; 3. 对比显示效果、计算压缩比。
时间: 2024-03-16 13:45:50 浏览: 20
好的,以下是一个更完整的Matlab代码实现,可以将一幅灰度图像进行压缩:
```matlab
% 加载图像并转换为灰度图像
img = imread('lena.bmp');
grayImg = rgb2gray(img);
% 将图像分块
blockSize = 8;
[h, w] = size(grayImg);
numBlocksH = floor(h / blockSize);
numBlocksW = floor(w / blockSize);
blockImg = mat2cell(grayImg, blockSize * ones(1, numBlocksH), blockSize * ones(1, numBlocksW));
% 对每个块进行离散余弦变换(DCT)
dctImg = cellfun(@(block) dct2(block), blockImg, 'UniformOutput', false);
% 量化
quantMatrix = [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];
quantImg = cellfun(@(block) quantize(block, quantMatrix), dctImg, 'UniformOutput', false);
% Zigzag扫描
zigzagImg = cellfun(@(block) zigzag(block), quantImg, 'UniformOutput', false);
% 哈夫曼编码
[huffDict, huffImg] = cellfun(@(block) huffman(block), zigzagImg, 'UniformOutput', false);
% 存储编码
save('huffman.mat', 'huffDict', 'huffImg');
% 解码
load('huffman.mat', 'huffDict', 'huffImg');
dehuffImg = cellfun(@(huff, dict) huffmandeco(huff, dict), huffImg, huffDict, 'UniformOutput', false);
% 逆Zigzag扫描
dezigzagImg = cellfun(@(block) dezigzag(block, blockSize), dehuffImg, 'UniformOutput', false);
% 逆量化和逆DCT变换
dequantImg = cellfun(@(block) dequantize(block, quantMatrix), dezigzagImg, 'UniformOutput', false);
deDctImg = cellfun(@(block) idct2(block), dequantImg, 'UniformOutput', false);
% 合并图像块
degrayImg = cell2mat(deDctImg);
% 显示压缩前后的图像
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('原始图像');
subplot(1, 2, 2);
imshow(degrayImg);
title('压缩后解压图像');
% 计算压缩比
originalSize = h * w;
compressedSize = numel(cat(2, huffImg{:}));
compressionRatio = originalSize / compressedSize;
disp(['压缩比为:', num2str(compressionRatio)]);
%% DCT函数
function dctImg = dct2(img)
dctImg = dct(dct(img)')';
end
%% 量化函数
function quantImg = quantize(dctImg, quantMatrix)
quantImg = round(dctImg ./ quantMatrix);
end
%% 逆量化函数
function dequantImg = dequantize(quantImg, quantMatrix)
dequantImg = quantImg .* quantMatrix;
end
%% Zigzag扫描函数
function zigzagImg = zigzag(block)
zigzagOrder = [1 -1 1 2 1 -1 2 3 2 1 -1 2 3 4 3 2 1 -1 2 3 4 5 4 3 2 1 -1 2 3 4 5 6 5 4 3 2 1 -1 2 3 4 5 6 7 6 5 4 3 2 1 -1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 -1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 -1];
zigzagImg = block(zigzagOrder);
end
%% 逆Zigzag扫描函数
function dezigzagImg = dezigzag(zigzagImg, blockSize)
dezigzagOrder = [1 2 6 7 15 16 28 29;
3 5 8 14 17 27 30 43;
4 9 13 18 26 31 42 44;
10 12 19 25 32 41 45 54;
11 20 24 33 40 46 53 55;
21 23 34 39 47 52 56 61;
22 35 38 48 51 57 60 62;
36 37 49 50 58 59 63 64];
[h, w] = size(zigzagImg);
dezigzagImg = zeros(blockSize);
dezigzagImg(dezigzagOrder) = zigzagImg;
dezigzagImg = dezigzagImg(1:h, 1:w);
end
%% 哈夫曼编码函数
function [huffDict, huffImg] = huffman(zigzagImg)
symbols = unique(zigzagImg);
freqs = histcounts(zigzagImg, [symbols, symbols(end)+1]);
p = freqs / sum(freqs);
[huffDict, ~] = huffmandict(symbols, p);
huffImg = huffmanenco(zigzagImg, huffDict);
end
```
这个代码实现的压缩步骤和上面的代码相同,但是增加了一些额外的函数,使代码更加清晰和易于理解。需要注意的是,这个代码仍然只是一个简单的实现,对于一些复杂的图像,可能需要更高级的压缩算法才能得到较好的压缩效果。