编写一个matlab程序,对输入的图像进行哈夫曼编码,显示原图像的熵、编码后的平均码字长度以及编码效率
时间: 2023-07-19 16:39:41 浏览: 129
好的,以下是基于MATLAB的哈夫曼编码程序,您可以输入图像并进行编码。程序使用MATLAB内置函数`imread`和`imwrite`读取和写入图像,使用MATLAB的`entropy`函数计算熵,使用自定义函数`huffman_encode`计算编码和统计信息。
```matlab
function huffman_image_encoding(image_path)
% 读取图像
image = imread(image_path);
[height, width, channels] = size(image);
% 转换为灰度图像
if channels > 1
image = rgb2gray(image);
end
% 将图像像素值存储为一维数组
pixels = reshape(image, 1, []);
% 计算像素值出现的频率
freq_dict = histcounts(pixels, 0:255);
% 构建哈夫曼树并获取编码映射表
root = build_tree(freq_dict);
codes = get_codes(root);
% 对原图像进行编码
encoded_data = "";
for i = 1:length(pixels)
encoded_data = strcat(encoded_data, codes{pixels(i)+1});
end
% 计算熵和平均码字长度
entropy = entropy(pixels);
avg_code_len = mean(cellfun('length', codes));
% 计算编码效率
original_size = dir(image_path).bytes;
compressed_size = length(encoded_data) / 8;
compression_ratio = original_size / compressed_size;
efficiency = 1 / compression_ratio;
% 输出统计信息
fprintf("Entropy: %.2f\n", entropy);
fprintf("Average Code Length: %.2f\n", avg_code_len);
fprintf("Efficiency: %.2f\n", efficiency);
% 将编码后的数据写入文件
[filepath, name, ext] = fileparts(image_path);
encoded_image_path = fullfile(filepath, strcat(name, "_encoded", ext));
write_encoded_image(encoded_data, height, width, encoded_image_path);
end
% 构建哈夫曼树
function root = build_tree(freq_dict)
heap = [];
for i = 1:256
if freq_dict(i) > 0
node = Node(freq_dict(i), i-1);
heap = [heap node];
end
end
while length(heap) > 1
node1 = heap(1);
heap(1) = [];
node2 = heap(1);
heap(1) = [];
merged = Node(node1.freq + node2.freq, [], node1, node2);
heap = [heap merged];
heap = heapify(heap);
end
root = heap(1);
end
% 获取编码映射表
function codes = get_codes(node, prefix, codes)
if nargin < 3
codes = cell(1, 256);
end
if node.is_leaf
codes{node.symbol+1} = prefix;
else
codes = get_codes(node.left, strcat(prefix, "0"), codes);
codes = get_codes(node.right, strcat(prefix, "1"), codes);
end
end
% 堆排序
function heap = heapify(heap)
for i = floor(length(heap)/2):-1:1
heap = sift_down(heap, i);
end
end
% 下滤
function heap = sift_down(heap, i)
while i*2 <= length(heap)
child = i*2;
if child+1 <= length(heap) && heap(child+1).freq < heap(child).freq
child = child + 1;
end
if heap(child).freq < heap(i).freq
heap([child i]) = heap([i child]);
i = child;
else
break;
end
end
end
% 写入编码后的图像
function write_encoded_image(encoded_data, height, width, encoded_image_path)
num_zeros = mod(-length(encoded_data), 8);
encoded_data = strcat(encoded_data, repmat('0', 1, num_zeros));
encoded_data = reshape(encoded_data, 8, [])';
encoded_data = bin2dec(encoded_data);
encoded_data = reshape(encoded_data, height, width);
imwrite(uint8(encoded_data), encoded_image_path);
end
% 定义节点类
classdef Node
properties
freq
symbol
left
right
end
methods
function obj = Node(freq, symbol, left, right)
obj.freq = freq;
obj.symbol = symbol;
obj.left = left;
obj.right = right;
end
function is_leaf = get.is_leaf(obj)
is_leaf = isempty(obj.left) && isempty(obj.right);
end
end
end
```
请确保您已经将图像路径传递给huffman_image_encoding函数。程序将输出原图像的熵、编码后的平均码字长度和编码效率,并将编码后的图像写入与原图像相同的文件夹中(文件名中添加了“_encoded”后缀)。
阅读全文