不使用ArithmeticCoder类,运用算术编码原理,使用matlab实现算术编码处理二维灰度图像,加上解码和计算压缩比
时间: 2024-03-28 14:38:24 浏览: 44
以下是一个使用算术编码原理对二维灰度图像进行压缩和解压的Matlab程序。程序中没有使用ArithmeticCoder类,而是手动实现了算术编码和解码的过程。
```matlab
% 读取图像
img = imread('lena_gray.png');
% 显示原始图像
imshow(img);
title('Original Image');
% 将图像转换为一维向量
symbols = img(:);
% 计算符号概率分布
counts = histcounts(symbols, 0:255);
prob = counts / sum(counts);
% 初始化编码器和解码器
lower = 0;
upper = 1;
range = 1;
encoded_bits = '';
decoded_symbols = [];
% 对每个符号进行编码
for i = 1:length(symbols)
symbol = symbols(i);
symbol_prob = prob(symbol+1);
% 计算新的上下限和编码位
new_lower = lower + range * sum(prob(1:symbol));
new_upper = lower + range * sum(prob(1:symbol+1));
new_range = new_upper - new_lower;
while true
% 确认编码位
if new_lower < 0.5 && new_upper < 0.5
encoded_bit = '0';
elseif new_lower >= 0.5 && new_upper >= 0.5
encoded_bit = '1';
new_lower = new_lower - 0.5;
new_upper = new_upper - 0.5;
else
break;
end
encoded_bits = strcat(encoded_bits, encoded_bit);
% 移位
while length(encoded_bits) >= 8
byte = bin2dec(encoded_bits(1:8));
encoded_bits = encoded_bits(9:end);
compressed = [compressed, byte];
end
end
% 更新上下限和范围
lower = new_lower;
upper = new_upper;
range = new_range;
end
% 处理余下的编码位
if lower < 0.5 && upper < 0.5
encoded_bits = strcat(encoded_bits, repmat('0', 1, 8-length(encoded_bits)));
else
encoded_bits = strcat(encoded_bits, repmat('1', 1, 8-length(encoded_bits)));
end
while length(encoded_bits) >= 8
byte = bin2dec(encoded_bits(1:8));
encoded_bits = encoded_bits(9:end);
compressed = [compressed, byte];
end
% 输出压缩后的数据
fprintf('Compressed size: %d bytes\n', length(compressed));
% 解码压缩数据
lower = 0;
upper = 1;
range = 1;
decoded_bits = '';
for i = 1:length(symbols)
% 解码位
while true
if lower < 0.5 && upper < 0.5
decoded_bit = '0';
elseif lower >= 0.5 && upper >= 0.5
decoded_bit = '1';
lower = lower - 0.5;
upper = upper - 0.5;
else
break;
end
decoded_bits = strcat(decoded_bits, decoded_bit);
% 移位
while length(decoded_bits) >= 8
byte = bin2dec(decoded_bits(1:8));
decoded_bits = decoded_bits(9:end);
decoded_symbols = [decoded_symbols, byte];
end
end
% 更新上下限和范围
symbol_prob = prob(decoded_symbols(i)+1);
symbol_range = range * symbol_prob;
symbol_lower = lower + symbol_range * sum(prob(1:decoded_symbols(i)));
lower = symbol_lower;
upper = symbol_lower + symbol_range;
range = symbol_range;
end
% 显示解码后的图像
decoded_img = reshape(decoded_symbols, size(img));
figure;
imshow(decoded_img);
title('Decoded Image');
% 计算压缩比
original_size = numel(img);
compressed_size = length(compressed);
compression_ratio = original_size / compressed_size;
fprintf('Compression ratio: %f\n', compression_ratio);
```
程序中首先读取了一个灰度图像,并将其转换为一维向量。然后计算了符号概率分布,并手动实现了算术编码和解码的过程。接下来对每个符号进行编码,最后输出压缩后的数据和解码后的图像。程序最后计算了压缩比,并输出到控制台。
需要注意的是,由于算术编码是一种无损压缩方法,因此解码后的图像与原始图像应该是完全一致的,但压缩比可能会有所不同。
阅读全文