关于MQ编码(算术编码、JPEG2000、JBIG2)常见问题的一些思考

本文探讨了MQ编码在JPEG2000标准中的作用,指出MQ编码是实现无损压缩的关键。文章分析了MQ编码为何采用查表法,以及其优势。还介绍了MQ编码的基本原理,包括概率区间、符号概率和寄存器初始化,并讨论了MQ编码中的码字终止算法和概率表的规律。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2009-03-06

12:24:41

by http://blog.youkuaiyun.com/KXY_tech/

 

关于MQ编码(算术编码、JPEG2000JBIG2)常见问题的一些思考

       JPEG2000的官方文件ISE/ISO 15444已经给出了MQ编码的详细流程,开发者如果只是为了实现MQ的功能,其实照着文档的流程图写程序就行了,并不需要理解其内在原理。然而做JPEG2000的朋友大都是硕士研究生以上的学历,仅仅是实现功能更而不理解原理似乎自降身价;更重要的是,像MQ编码这种编码原理,其实跟其他编码有强烈的类似性,理解一种方法就有举一反三的效果。而,只做实现极其容易陷进"代码搬运工"的困境。

 

1、为什么要用MQ编码?

       考虑MQ之前,先看看小波变换和位平面编码。JPEG2000编码的顺序的小波变换→位平面编码→MQ编码。

       小波变换把图片分成了具有统计特性的子带(即知道了哪个子带的数据更重要)。而小波变换本身能实现数据压缩吗?答案是肯定不能的。反而,由于小波变换后的系数有可能超出原来数据的范围,还要加上1~2个保护位(Guard bits),输出数据量甚至比输入还要大。

       位平面编码有什么用?位平面的作用有二:1)把一个平面分成三个通道,方便以后的率控制。2)把每个像素点的每一位都判断(根据子带信息和位本身邻居的信息),输出判决结果和上下文序号提供给MQ用作输入。位平面本身也不可能进行数据压缩(输入1位,却输出1位的判决和一个CX上下文标号,压个P)。

       也就是说,小波变换和位平面编码都是给MQ打下手的。MQ是JPEG2000标准中实现无损压缩的唯一途径。

       从上面也可以看出,JPEG2000中产生的中间数据量巨大,编程时需要大量的malloc分配。

 

2、JPEG2000的MQ编码为什么使用查表法?

       传统的算术编码概率更新时要浮点运算,众所周知,浮点运算要比定点运算慢近30倍,定点DSP弄浮点算法更麻烦。现在我连定点运算都不用了,直接查表来更新概率,谁比我快?

       当然,为了要得到查概率表的索引号,就必须进行位平面编码,为了位平面编码,就必须进行小波变换,加起来到底谁快还不一定。不过既然专家们选择了查表的方法,我想

<think>好的,我现在需要处理用户关于MQ编码器设计方法或实现的查询。首先,我得确认MQ编码器的基本信息。MQ编码器是JPEG 2000JBIG2标准中使用的算术编码器,主要用于图像压缩。用户可能是在开发图像处理系统时需要实现它,或者是在研究相关算法。 接下来,我应该回忆MQ编码器的核心设计要点。首先,MQ编码是基于上下文的自适应二进制算术编码(CABAC)。这意味着编码器需要根据上下文模型调整概率估计,这对实现来说需要有效的上下文建模和管理机制。 然后,考虑概率区间的划分。算术编码的核心是维护一个当前区间,通常用区间长度和下限来表示。在MQ编码器中,这个区间需要动态更新,每次编码一个符号后,区间会被细分。此外,重归一化处理是关键步骤,当区间变得太小时,需要扩展并输出相应的位,这涉及到位操作和缓冲管理。 上下文模型的设计也是重点。不同的上下文对应不同的统计模型,编码器需要根据已编码的邻近像素或符号来确定当前上下文。这可能需要查找表或者状态机来管理各个上下文的概率状态。 另外,MQ编码器的实现还需要考虑计算效率。由于算术编码是计算密集型任务,优化数据结构(如使用整数运算代替浮点数)和避免频繁的内存访问是必要的。可能还需要采用查表法来加速概率更新和区间计算。 用户可能还关心具体的实现步骤。比如,如何初始化上下文模型、如何处理二进制符号的编码、如何管理编码区间和进位问题。此外,代码结构方面,可能需要模块化设计,将上下文管理、区间更新、位输出等功能分开实现。 最后,应该考虑生成相关问题,帮助用户深入理解。例如,MQ编码器与其他算术编码器的区别,在实时系统中的优化策略,或者在不同图像格式中的应用差异。这些问题可以引导用户进一步探索相关主题。</think>### MQ编码器设计实现方法 MQ编码器是JPEG 2000JBIG2标准中的核心熵编码模块,其设计围绕**自适应二进制算术编码**和**上下文建模**展开,以下是关键设计步骤: 1. **概率区间划分与更新** MQ编码器通过维护区间寄存器$[L, L+R)$进行编码,其中$R$为当前区间长度。每次编码二进制符号时,根据符号概率$Q_e$(通过查表获取)更新区间: - 若编码符号为**大概率符号(MPS)**: $$R_{\text{new}} = R - Q_e, \quad L_{\text{new}} = L + Q_e$$ - 若编码符号为**小概率符号(LPS)**: $$R_{\text{new}} = Q_e, \quad L_{\text{new}} = L$$ 通过条件交换确保$R_{\text{new}} > 0$[^1]。 2. **上下文自适应机制** - 定义**19种上下文状态**(如JPEG 2000中),每个上下文包含: - 当前MPS值(0/1) - 概率状态索引$I$(指向$Q_e$表) - 符号编码后,根据结果更新$I$: $$I_{\text{new}} = \text{transit\_I}(I, \text{symbol})$$ 更新规则由预定义的有限状态机决定[^1]。 3. **重归一化与位输出** 当$R < 0x8000$(16进制)时触发重归一化: ```python while R < 0x8000: R <<= 1 L <<= 1 if L溢出: 处理进位并输出位 ``` 需特别处理**进位传播**问题(如0xFF后接进位需合并为0x7F 0x80)。 4. **实现优化技巧** - 使用**查表法**加速概率状态转换 - 采用**位填充策略**防止算术溢出 - 使用整数运算避免浮点性能损耗 ```python # MQ编码器核心伪代码示例 class MQEncoder: def __init__(self): self.L = 0 self.R = 0xFFFF self.byte_buffer = [] self.ct = 0 def encode_bit(self, symbol, cx): # 获取当前上下文概率状态 qe = Qe_Table[cx.index] # 区间划分 if symbol == cx.mps: self.R -= qe if self.R < 0x8000: self.L += qe self.renormalize() else: self.R = qe self.L += (self.R - qe) cx.update(symbol) # 更新上下文 self.renormalize() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值