文章目录
主要讲解了如何在 MATLAB 中进行图像压缩,包括离散余弦变换(DCT)的应用和行程编码(RLE)的实现。以下是每个部分的概述和 MATLAB 代码示例:
MATLAB实现图像压缩
目的
- 理解图像压缩的相关概念及图像压缩的主要原则和目的;
- 掌握霍夫曼编码
- 掌握几种常见的图像压缩编码方法
- 利用 MATLAB 程序进行图像压缩
原理
图像压缩原理
图像压缩主要是通过减少图像数据中的冗余信息来节省存储空间。压缩可分为无损压缩和有损压缩。
- 无损压缩:解压后的图像与原图完全一致,常见方法包括哈夫曼编码、行程编码(RLE)。
- 有损压缩:解压后的图像与原图存在一定差异,常见方法包括离散余弦变换(DCT)、JPEG等。
图像压缩的核心思想是通过各种编码方法减少冗余信息,达到节省空间的目的。
离散余弦变换(DCT)图像压缩原理
DCT 是一种将图像从空间域转换到频率域的变换方法。DCT 压缩的核心是将图像数据进行频域转换,然后对不重要的高频信息进行去除,从而达到压缩的目的。
在 JPEG 压缩中,DCT 作为一种标准变换方法,通常将图像分成 8×8 的块,对每块进行 DCT 变换,量化后进行编码。通过这种方式,图像的低频信息保留, 高频信息舍弃,最终减少图像的存储需求。
行程编码(RLE)原理
行程编码(RLE)是一种非常简单且高效的无损压缩方法,特别适用于像素值相同且连续的图像区域。其基本原理是对相邻的相同像素值进行压缩,例如表示为“数值+重复次数”。在图像中,长时间连续相同的像素值可以被有效压缩。
例如,二值图像中多个相邻的“1”或“0”可以通过“1 5”或者“0 3”的形式进行编码。
步骤
MATLAB 中的变长码映射
clear all
clc
% 输入图像数据
f2 = uint8([2 3 4 2; 3 2 4 4; 2 2 1 2; 1 1 2 2]);
whos('f2')
% 进行哈夫曼编码
c = huffman(hist(double(f2(:)), 4));
h1f2 = c(f2(:))';
% 输出编码后的数据
whos('h1f2')
% 将编码结果转换为字符表示
h2f2 = ['1 0 1 0 0 1 1 0 0 0 0 1 1 0 1 1';...
'1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 1';...
'0 0 1 1 0 1 0 1 1 1 0 1 0 1 1 0'];
whos('h2f2')
% 转换为空格字符
h2f2 = h2f2(:);
h2f2(h2f2 == ' ') = [];
% 计算矩阵哈夫曼编码
h3f2 = mat2huff(f2);
whos('h3f2')
% 输出编码后的哈夫曼码
hcode = h3f2.code;
whos('hcode')
dec2bin(double(hcode))
% 哈夫曼编码实现
function CODE = huffman(p)
error(nargchk(1, 1, nargin));
if (ndims(p) ~= 2) | (min(size(p)) > 1) | ~isreal(p) | ~isnumeric(p)
error('p must be a real numeric vector');
end
global CODE
CODE = cell(length(p), 1); % 初始化哈夫曼编码单元
if (length(p) > 1)
p = p / sum(p); % 归一化概率
s = reduce(p); % 执行哈夫曼源符号合并
makecode(s, []); % 递归生成编码
else
CODE = {'1'}; % 简单单一符号情况
end;
end
% 子函数:合并概率
function s = reduce(p)
s = cell(length(p), 1);
for i = 1:length(p)
s{i} = i;
end
while size(s) > 2
[p, i] = sort(p);
p(2) = p(1) + p(2); % 合并概率
p(1) = []; % 剪去最小概率
s = s(i);
s{2} = {s{1}, s{2}};
s(1) = [];
end
end
% 子函数:递归生成哈夫曼编码
function makecode(sc, codeword)
global CODE
if isa(sc, 'cell')
makecode(sc{1}, [codeword 0]);
makecode(sc{2}, [codeword 1]);
else
CODE{sc} = char('0' + codeword);
end
end
% 子函数:将矩阵转换为哈夫曼编码
function y = mat2huff(x)
if ndims(x) ~= 2 | ~isreal(x) | (~isnumeric(x) & ~islogical(x))
error('x must be a 2-D real numeric or logical matrix');
end
y.size = uint32(size(x));
x = round(double(x));
xmin = min(x(:));
xmax = max(x(:));
pmin = double(int16(xmin));
pmin = uint16(pmin + 32768);
y.min = pmin;
x = x(:)';
h = histc(x, xmin:xmax);
if max(h) > 65535
h = 65535 * h / max(h);
end
h = uint16(h);
y.hist = h;
% 执行哈夫曼编码
map = huffman(double(h));
hx = map(x(:) - xmin + 1);
hx = ['1' ' ' '1' '0' ' ' '1' '1' '0' ' ' ' '...
'0' '1' '1' ' ' '1' '1']';
hx = hx(:)';
hx(hx == ' ') = [];
ysize = ceil(length(hx) / 16);
hx16 = repmat('0', 1, ysize * 16);
hx16(1:length(hx)) = hx;
hx16 = reshape(hx16, 16, ysize);
hx16 = hx16' - '0';
twos = pow2(15:-1:0);
y.code = uint16(sum(hx16 .* twos(ones(ysize, 1), :), 2))';
end
离散余弦变换(DCT)图像压缩
DCT 是图像压缩中常用的变换方法,主要将图像从空间域转为频率域,通过丢弃高频信息(对图像影响较小的部分)来实现压缩。以下代码展示了如何使用 DCT 来压缩图像。
clear all
clc
% 读取图像
I = imread('D:\pic\DIP3E_CH11_Original_Images\Fig1137(b)(painting_translated_padded).tif', 'tif');
I = im2double(I);
% 生成8x8的DCT矩阵
T = dctmtx(8);
% 对图像进行块处理,计算二维DCT
B = blkproc(I, [8, 8], 'P1*x*P2', T, T');
% 定义掩膜,保留左上角的DCT系数
mask = [1 1 1 1 0 0 0 0; 1 1 1 0 0 0 0 0; 1 1 0 0 0 0 0 0;...
1 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0;...
0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0];
% 应用掩
膜,只保留DCT变换后的部分系数
B2 = blkproc(B, [8, 8], 'P1.*x', mask);
% 对压缩后的图像进行逆DCT变换
I2 = blkproc(B2, [8, 8], 'P1*x*P2', T', T);
% 显示原图像和压缩后的图像
imshow(I), title('原图像');
figure, imshow(I2), title('压缩后的图像');
利用离散余弦变换进行JPEG 图像压缩
clear all
clc
% 读取图像
I = imread('D:\pic\DIP3E_CH11_Original_Images\Fig1137(b)(painting_translated_padded).tif');
I = im2double(I);
% 生成8x8的DCT矩阵
T = dctmtx(8);
% 计算二维DCT变换
B = blkproc(I, [8 8], 'P1*x*P2', T, T');
% 定义掩膜,保留DCT系数中的前几个
mask = [1 1 1 1 0 0 0 0; 1 1 1 0 0 0 0 0; 1 1 0 0 0 0 0 0; 1 0 0 0 0 0 0 0;...
0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0];
B2 = blkproc(B, [8 8], 'P1.*x', mask);
% 逆DCT恢复图像
I2 = blkproc(B2, [8, 8], 'P1*x*P2', T', T');
% 显示原图像和压缩后的图像
subplot(1,2,1);
imshow(I), title('原图像');
subplot(1,2,2);
imshow(I2), title('压缩图像');
这些代码展示了如何通过变换和编码方法对图像进行压缩。在实际应用中,DCT 和其他编码方法能够有效减少图像文件大小,特别是在存储和传输过程中非常有用。
717

被折叠的 条评论
为什么被折叠?



