Dict.CN 在线词典, 英语学习, 在线翻译

学海苦作舟,书山勤为径

留下点回忆

常用链接

统计

积分与排名

Denoise

English study

Web技术

数据压缩

一些连接

最新评论

JPEG2000如何进行码率和失真分配的?

JPEG2000 的实现 kakadu 中是用一个 16 位数来表示失真长度曲线的斜率;在整个编码过程中,使用斜率值的右移四位的标量量化值。

编码的分配表面是按照块进行的,实际并是整个压缩过程考虑的。

JPEG2000 使用一个 4096 元素的量化斜率值数组来存储压缩过程中遇到的斜率值( quant_slope_rates )。

当第一次编码的时候,从 4096 个元素找满足码率的斜率下限,实际上这个时候没有任何压缩,数组的所有元素都为 0 ;所以开始的时候得到的斜率值是 1 。第一个 block 使用斜率值 1 作为块编码的依据。

码块编码需要两个关于度量失真的参数: wmse 和失真斜率。编码为每个编码过程定义了一个 pass_wmse_change ;这里面保存了码块每个编码过程中对斜率的贡献。如果使第一个 block 的第一个编码过程,那么采用 -1 的估计失真长度曲线斜率;否则采用一个斜率的对数值。

1.  首先将 wmse 分成 2 32 次方等份,这个作为每个过程的 pass_wmse_scale 。这里分成这些等份的原因在于编码的时候使用的 32bit 的整数;当然最高位为符号位。每个编码过程的 wmse scale 都不一样,当前过程的 pass_wmse_scale 是上个过程的四分之一。由于位平面编码并非从第 30 位开始,所以对于丢弃的 msb ,需要乘以指定数个 1/4

注,这里不知道为什么要乘 1/4

2.  进行一次过程编码后,根据当前过程的信息查表计算得到该过程对整个图像失真的改变值 distortion_change 。这个值于当前过程的 pass_wmse_scale 的乘积作为当前过程的 wmse 改进值存放到每个过程对应的 pass_wmse_change 数组中。

3.  如果不是第一个 block 的第一个编码过程;那么预测的斜率门限值应该是大于 0 ,那么检查并判断当前过程是否已经满足该斜率值了。基本按照如下方式计算:

a)         每个过程由一个编码长度值 pass_lengths wmse 的改进值: pass_wmse_changes ;第一个作为长度的改进量,第二个作为失真的改进量。

b)        如果斜率与上面长度改进量的乘积比失真改进量大,说明这个过程以后的斜率都要比预测的斜率值小了;那么这个时候可以停止该 block 的编码过程了。

注,这一步实际上也算是比较耗时间的过程。

4.  完成需要的编码过程后,对应编码过程应该已经由了失真信息和长度信息。这个时候需要来检查上面编码过程中那些过程结束是优化的,同时找出每个编码过程对应的斜率。这里以实际编码的过程作为参数。

5.  开始的时候设置斜率位- 1 ;然后累计第一个过程的长度和失真值(分别在 pass_lengths pass_wmse_change 中),得到 D L 的比值,这个作为当前过程的斜率;对于第二个过程需要累计第一个、第二个两个过程的值,得到一个斜率值;最终得到的值如果小于等于 0 ;那么设置该过程的斜率为 0 ;否则取上面值的对数作为当前过程的斜率值。

6.  完成上面操作后,再检查保留的过程中,按照编码顺序后面的过程斜率是否比前一个过程的斜率大,如果大保留后面那个过程的斜率,小的值修改为 0 。因此在完成 5 6 之后,被保存下来的点值都大于 0 ,二其他被抛弃的点斜率变为 0

7.  在完成 block 编码后需要更新全局状态(其在 kd_compressed_stats 中。

8.  首先我们将当前 block 的大小,也就是多少个样本添加到被编码过程的样本数中( num_coded_samples ),第一个 block 时,这个值时 0 。这里需要这个值作为 trim 的依据和下个 block 编码时使用的值。

9.  统计每个编码过程的斜率和长度值,并将斜率值量化为 1/16 作为数组 quant_slope_rates (这是 1 4096 元素的数组,里面保存在该斜率下总共编码的长度,也就是说如果不同的 block 具有相同的斜率的过程长度值被累加到一起)入口;当然,如果那些斜率为 0 的点需要被跳过,其长度被累加到下个在曲线上的编码过程。同时更新一下当前可以使用的最大和最小斜率值。

10.              8 中提到的 num_coded_samples 用来检查是否需要考虑 trim 多于的数据。多余数据被 trim 的检查点为总体样本的: 2/16 3/16 4/16… 处,后面都是按照、 /16 增加。

11.              一旦需要 trim 的时候,首先按照总样本数量(注意这里不是已经编码的样本数量)和目标码率计算目标码流的长度,然后在 quant_slope_rates 中找到斜率,在这个斜率点所有 block 的所有过程长度的累加值比上面的总目标长度刚好大。而 trim 操作按照这个斜率值检查所有已经编码的 block trim 掉所有比这个效率小的过程。可以看到在整个编码过程中,这样的 trim 操作最多需要进行 15 次,每次都一可能从所有块中将小于指定斜率的编码过程 trim 掉。上面的 trim 操作不会影响 quant_slope_rates 的值。

12.              上面已经完成了一个 block 的编码;下面开始第二个 block 的时候稍微与第一个有点不同;主要的不同在于现在 quant_slope_rates 中已经包含斜率长度值了。根据 num_coded_samples (这里保守增加了额外长度)和目标码率计算期望的编码长度;然后从 quant_slope_rates 中发现到这个长度的斜率值,这个值作为当前 block 编码的最低的斜率门限。

posted on 2007-01-31 21:46 笨笨 阅读(1899) 评论(2)  编辑 收藏 引用 所属分类: 压缩算法

评论

# re: JPEG2000如何进行码率和失真分配的? 2007-09-08 19:58 wilth

这篇文章写的太好了,我现在也在看kakadu的率失真这一块,能否留下联系方式?想向你学习一下!我的联系方式:yihwen@cse.buaa.edu.cn,或者13611094514  回复  更多评论   

# re: JPEG2000如何进行码率和失真分配的?[未登录] 2009-04-15 15:45

请问,JPEG2000是如何组包的?它是根据什么原则将哪些编码通道包含到一个包中的?  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理