算术编码压缩比计算问询:是否仅基于二进制码或需包含其他数据?
算术编码是最知名的熵编码技术之一,我正用它对图像编码,采用Matlab内置函数实现,自定义的编码函数除输出二进制码code外,还会返回seq、counts、source等数据。理论上压缩基于数据概率分布完成,算术编码器依序列概率编码。我核心想了解:压缩比是否仅通过二进制code计算?还是需包含其他部分?若是后者,能否告知如何计算相关大小及所需参数?这些数据精度高或数值较大。
算术编码实现代码
function [code,seq,counts,source] = arithmetic_coding(message) %strfind: finds the string within another string. source=unique(message); counts=zeros(1,length(source)); for i=1:length(source) counts(i)=length(strfind(message,source(i))); end %counts seq=zeros(1,length(message)); for i=1:length(message) seq(i)=strfind(source,message(i)); end %seq code = arithenco(seq, counts); end
算术解码实现代码
function dec_message = arithmetic_decoding(code,counts,seq,source) dseq = arithdeco(code,counts,length(seq)); dec_message=zeros(1,length(dseq)); for i=1:length(dseq) a=dseq(i); dec_message(i)=source(a); end end
压缩比计算说明
压缩比的计算必须包含所有需要传输/存储的辅助数据,因为解码端必须依赖这些数据才能正确还原原始信息,只算code的大小是不完整的。具体说明如下:
1. 需包含的必要辅助数据
source:原始数据的符号集合(即图像中出现的所有唯一像素值),解码时用于将解码出的索引序列映射回原始像素。counts:每个符号的出现次数,用于重建算术编码所需的概率分布,是Matlab内置解码函数arithdeco的必填参数。code:算术编码生成的二进制码流,这是压缩后的核心数据。
注:seq是原始消息到符号索引的中间映射,解码时不需要用到(当前解码函数参数中的seq仅用来获取原始消息长度,实际可以用length(dec_message)替代,因此seq无需存储或传输)。
2. 各部分大小计算方式
二进制码code的大小
Matlab中code是二进制数组,总大小为length(code)比特,每个元素占1比特。
source的大小
假设图像像素为N位(如8位灰度图,每个像素占8比特),source中有M个唯一符号,则总大小为 M * N 比特。
counts的大小
counts存储每个符号的出现次数,最大值不超过原始消息总长度L(即图像总像素数)。每个计数可用ceil(log2(L))比特存储,总大小为 M * ceil(log2(L)) 比特。
3. 总压缩大小与压缩比计算
- 总压缩大小 =
code大小 +source大小 +counts大小(单位:比特) - 原始数据大小 = 图像总像素数 × 单像素比特数(如8位灰度图为
L * 8比特) - 压缩比 = 原始数据大小 / 总压缩大小
优化建议
针对图像编码场景,可通过分块编码提升效率:将图像分割为小块,对每块单独执行算术编码,这样每块的source和counts规模更小,降低辅助数据的开销。另外,也可对counts采用变长编码(如霍夫曼编码)进一步压缩这部分数据的体积。
内容的提问来源于stack exchange,提问作者Sahil Sharma

