JPEG2000中包括许多既定义的单元,主要有:
1.画布
2.分片(Tile)
3.子带(Subband)
4.分辨率层(Resolution)
5.分区(Precinct)
6.分区分割(Precinctpartition,在kakadu中叫precinctband)
7.码块(codeblock)
8.包(packet
9.层(layer)
10.分量(Component)
11.区域(Region)
12.渐进性(Progressive)
下面来一一解释这些概念。
画布是整个图像的参考网格,可以想象我们的图像就在这张画布上显示的;但必须明确一点就是,图像的原点未必就正好在画布的原点。可以形象的描述画布为许多网格,如下:
这里需要注意的另一个问题是:图像的值并不是正好填充在每个网格上,可能以一定的间隔填充的。
在这里假设所有的分量采样间隔S都是1。
这里的分量与我们通常所说的颜色分量是相同的,例如:对于RGB表示的像素值图像,有三个分量,如果是24bit的RGB,那么每个分量使用8bit来表示。当然整个图像是由三个分量组成,因此每个分量都在画布上,而分量的填充间隔可以不一样。例如:
上图中包含两个分量的图像,但第一个分量(红色)的采样间隔是4,第二个是2。对于我们常用的图像,分量采样的间隔(Subsampling)是一样的。
图像的在画布中使用两对坐标来表示位置:(E1,F1);(E2,F2)
由于分量的采样因子(间隔)不一样,所以每个分量的区域界限是不同的,一般可表示为:
Ec=Ei/Si
JPEG2000引入分片这个概念是为了处理复合文档,因为有些区域包含图形,有些区域包含文字,分片之后对不同的区域采用不同的处理方法。例如:文字区域不需要DWT,直接压缩等。
对于一般压缩自然图像采用一个分片就足够了。
这里的分片与图像并非是坐标对齐的,其用O1和O2来表示原点在画布上的位置,用T1和T2表示每个分片的大小;每个分片必须与图像的区域有重叠。
使用N1和N2来表示分片的Y方向和X的数量,使用t1和t2来表示坐标,
其中0<=t1 每个贴片在都有一个唯一的标示符号,其通过t来表示,计算如下: t=t2+t1N2 注意:非0原点的目的方便于图像的裁剪处理。 每个贴片在画布中对应的区域为: E1_t=max(E1,O1+t1*T1);F1_t=min(F1,O1+t1*T1) E2_t=max(E2,O2+t2*T2)F2_t=min(F2,O2+t2*T2) O=(0,0) 如果E1=100,E2=100,F1=1000,F2=1000 O1=10,O2=10,T1=100,T2=100 因此: N1=(F1-O1)/100=9,N2=9 那么E1_t=max(100,10+t1*100),F1_t=min(1000,10+t2*100) 如果t1=2,t2=3;那么 该贴片的唯一表示为:t=t2+t1*N2=3+2*9=21 E1_t=max(100,10+2*100)=210F1_t=min(1000,10+3*100)=310 E2_t=max(100,10+2*100)=210F2_t=min(1000,10+3*100)=310 当然,如果每个贴片对应到分量上时情况有所不同,因为不同分量的采样间隔不一样导致有的贴片并不包含分量值。 JPEG2000中,DWT变换是针对每个贴片分量的,如果有三个分量,那么每个分量调用DWT变换。 子带是进行DWT子带变换的产物,这里以2D树结构为例来说明子带变换产生的子带。图中的每次DWT变换在LLn子带上进行,最初的图像可以认为是LL0子带,对LL(n-1)子带进行变化得到n级别的子带4个,分别是LLn,HLn,LHn,HHn。 HL子带是水平高通滤波器产生的结果,因此水平方向上高频图像区域被保存了下来。 LH子带是垂直高通滤波器产生的结果,因此垂直方向上高频图像区域被保存下来。 HH是垂直和水平方向上都是高通的结果,因此是对角线方向的图像特性被保存下来。 LL是图像的低频部分,也是图像的低分辨率版本。 LL3 HL3 HL2 HL1 LH3 HH3 LH2 HH2 LH1 HH1 E1_t_b=(E1_t–2d-1b1)/2dE2_t_b=(E2_t–2d-1b2)/2d F1_t_b=(F1_t-2d-1b1)/2dF2_t_b=(F2_t-2d-1b2)/2d 其中d的取值范围是1到D(DWTLEVEL);而b1和b2的取值由子带决定: LL子带中:b1=b2=0 HL子带中:b1=0;b2=1 LH子带中:b1=1;b2=0 HH子带中:b1=1;b2=1 这里按照上面贴片的位置来计算子带在画布中区域。这里假设是DWT的LEVEL2,也就是d等于2。 由于E1_t=E2_t=210,F1_t=F2_t=310,那么对于LL子带: E1_t_b_LL=(210-22-1*0)/22=210/4=53 E2_t_b_LL=53 F1_t_b_LL=(310-22-1*0)/22=78 F2_t_b_LL=78 对于HL子带: E1_t_b_HL=(210-22-1*0/22=210/4=53 E2_t_b_HL=(210-22-1*1)22=208/4=52 F1_t_b_HL=(310-22-1*0)/22=78 F2_t_b_HL=(310-22-1*1)/22=77 对于LH子带: E1_t_b_LH=(210-22-1*1/22=210/4=52 E2_t_b_LH=(210-22-1*0)22=208/4=53 F1_t_b_LH=(310-22-1*1)/22=77 F2_t_b_HL=(310-22-1*0)/22=78 对于HH子带: E1_t_b_HH=(210-22-1*1/22=210/4=52E2_t_b_HH=52 F1_t_b_HH=(310-22-1*1)/22=77F2_t_b_HH=(310-22-1*1)/22=77 上面的数都是取整数的结果,超出的部分取1。 实际上我们可以计算d=1时的LL子带边界就知道了: E1_t_b_LL=(210-21-1*0)/21=210/2=105 E2_t_b_LL=105 F1_t_b_LL=(310-21-1*0)/21=155 F2_t_b_LL=155 可以看到d=2的子带和d=1的各子带之间的关系: W_HL=F2_t_b_HL-E2_t_b_HL=77-52=25 H_HL=F1_t_b_HL–E1_t_b_HL=78-53=25 W_LH=F2_t_b_LH-E2_t_b_LH=78-53=25 H_LH=F1_t_b_LH–E1_t_b_LH=77-52=25 W_HH=F2_t_b_HH–E2_t_b_HH=77-52=25 H_HH=F1_t_b_HH–E1_t_b_HH=77-52=25 W_LL=78-53=25H_LL=78-53=25 我可以看到对于d=1的LL子带宽度与d=2的W_LL+W_HL以及W_LH+W_HH;高度也是同样的。 下面来看d=3的各子带参数: 对于LL子带有: E1_t_b_LL=(210-23-1*0)/23=210/8=27 E2_t_b_LL=27 F1_t_b_LL=(310-23-1*0)/23=39 F2_t_b_LL=39 E1_t_b_HL=(210-23-1*0/23=210/8=27 E2_t_b_HL=(210-23-1*1)23=206/8=26 F1_t_b_HL=(310-23-1*0)/23=39 F2_t_b_HL=(310-23-1*1)/23=39 E1_t_b_LH=(210-23-1*1/23=206/8=26 E2_t_b_LH=(210-23-1*0)23=210/4=27 F1_t_b_LH=(310-23-1*1)/23=39 F2_t_b_LH=(310-23-1*0)/23=39 E1_t_b_HH=(210-23-1*1/23=210/4=26E2_t_b_HH=26 F1_t_b_HH=(310-23-1*1)/23=39F2_t_b_HH=(310-22-1*1)/22=39 从这里我可以看到各子带不在一样大了: LL子带是:12*12,HL子带是12*13,LH是13*12,HH是13*13(高度先)。 他们的宽和高的和与d=2上的LL子带是相等的。 由于LL_2上的宽度和高度是25(奇数),所以导致这种情况,基本的过滤是:如果计算中的贴片坐标Ei_t是偶数,那么最终低通部分比高通部分多一个样本,如果是奇数,那么高通子带比低通子带多1个样本。 另外一个问题必须注意:计算过后的子带边界比原来的贴片小,实际上由于每次子带变换,图像的分辨率都要缩小1/2,所以在d级子带变化后,上得到的边界,必须乘上2d才能与原贴片中的位置对应。那么对于d=2的情况,必须乘上4,因此对于d=2的各子带在原图像中的实际位置为: LL子带的位置为:(212,312)X(212,312) HL子带的位置为:(212,312)X(208,308) LH子带的位置为:(208,308)X(212,312) HH子带的位置为:(208,208)X(208,308) 上面的表示方式是高度优先。 这里可以理解为d级上的子带是由原图中的2d个样本变换得到。 上图显示的子带变换过程由DWTLEVEL来决定,而每个级别都是图像的低分辨率层。分辨率的级别与DWTLevel的值相反,Level最的时候,分辨率级别为0,而原图像对应分辨率的最高级别。 每个分辨率级别包含3个子带,分别是HL,HH和LH;0层包括一个子带LL。 假设分辨率用r表示,总的DWT变换次数用D表示,那么对于每个分辨率的边界可表示为: Ei_R=Ei_t/2D-r Fi_R=Fi_t/2D-r 如果D=3,r=2;那么按照上面的计算(E1_t=E2_t=210,F1_t=F2_t=310),分辨率层2的边界为: E1_R_2=210/23-2=105F1_R_2=310/23-2=155 E2_R_2=105F2_R_2=155 如果r=0,那么该分辨层的边界为: E1_R_2=210/23-0=27F1_R_2=310/23-0=39 E2_R_2=27F2_R_2=39 每个分辨率级别的原点也是贴边的原点乘上:2-(D-r) 为了提供渐进性,JPEG2000提供了分区和分区分割的概念。 分区与贴片不同的地方在于分区不影响DWT变化,甚至不影响编码。另外分区的大小必须是2的POWER,而贴片的大小可以是任意的。 其将某个指定的分辨率层上进行分割,当然要求分区的每个块必须与图像的区域重叠。 一般某个分辨率层上有3个子带,这三个子带都是通过分区网格来划分的,当然每个子带 分区的大小用P1和P2来表示,P1是高度,P2是宽度。 N1_P:表示垂直方向分区的数量。 N2_P:表示水平方向分区的数量。 分区的原点用O1_P,O2_P表示,其可以不用与分辨率层的原点重叠;分区用垂直和水平方向的索引(p1,p2)来表示;并且: 0<=p1 而N1_P和N2_P有下面计算得到: N1_P=(F1_R-O1_P)/P1 N2_P=(F2_R-O1_P)/P2 F1_R和F2_R表示当前分辨率层的右和下边界。如果他们是0,那么N1_P和N2_P必须是0。 分区的区域用下面的表达式计算出来: E1_P=max(E1_R,O1_P+P1*p1) F1_P=min(F1_R,O1_P+P1*(p1+1)) E2_P=max(E2_R,O2_P+P2*p2) F2_P=min(F2_R,O2_P+P2*(p2+1)) 下面计算上面对于D=3,r=2分辨率上的分区(1,3)的边界;这里假设O1_P=90,O2_P=100,并且P1=8,P2=4 前面的计算中有E1_R_2=105F1_R_2=155E2_R_2=105F2_R_2=155 E1_P=max(105,90+1*8)=105 F1_P=min(155,100+1*8)=108 E2_P=max(105,90+3*4)=105 F2_P=min(155,100+3*4)=112 分区分割是将同一个分辨率层上三个子代(LL子带外)上同一个位置的分区合并到一起的总称。实际上可以看出,这三块上的信息合并到一起在加上LL子带当前块,就可以恢复上一个分辨率级别上LL子带该位置的样本。当然映射到上一个分辨率层的时候需要将区域扩展。 对于特定的r分辨率级别上分区,对应到r-1分辨率级别上的的三个子带的区域为: Ei_R-1_b=(Ei_R–bi)/2Sr Fi_R-1_b=(Fi_R–bi)/2Sr 其中i等于1和2,而bi分别是0和1。其组合得到四个子带。 Sr在r=0的时候为0,r大于0的时候为1。如果是0表示最低分辨率层也就是最终的LL子带,那么其没有映射,而对于其他的分辨率层上的映射是其下一级别的三个子带,因此区域标记需要减少1/2。这里的关系同前面子带的映射关系相似,这里不在详细介绍。 另外,新映射的三个子带的原点坐标需要按照下面表达式计算: Oi_R-1=(Oi_R–bi)/2Sr 而分区划分的大小为: P1_R-1=2-Sr*P1_R P2_R-1=2-Sr*P2_R 编码块是对每个子带中分区的进一步划分;编码块划分具有与同一个子带中分区划分同样的原点(O1_P,O2_P)。 每个码块的大小为J-1_BC*J2_BC。默认是64,他们必须是2的POWER,并且不能小于4,大于1024。 默认值J1_BC_D,J2_BC_D从COD参数的CBLK中获得,因此J1_BC,J2_BC可以通过下面的表达式来计算: J1_BC=MIN(J1_BC_D,2-Sr*P1_R) J2_BC=MIN(J2_BC_D,2-Sr*P2_R) P1_R和P2_R表示r分辨率上的分区大小。如果2-Sr*Pi_R比Ji_BC_D要小,说明一个分区只能有一个码块。 每个分区上的垂直和水平方向码块的数目为:N1_BC,N2_BC。 N1_BC=(F1_R-1_b–O1_P)/J1_BC N2_BC=(F2_R-1_b–O2_P)/J2_BC F1_R-1_b和F2_R-1_b表示分区在子带上的下边界和右边界。 如果一个分区有多个码块,需要进行编码,编码的顺序是从左到右,从上到下。HL子带码块先出现,最后是HH子带。 注意:码块是进行编码的基本单元。所有数据在进行DWT之后,然后将对应子带上的系数按照分区来划分,并最终组织成码块,然后将得到的码块数据进行编码。 为了能够是压缩在质量方面采用渐进性,采用包这种结构。包实际上是码块编码的集合;最简单的码块组合方式是顺序的;例如: 每个码块的全部按照长度+内容(长度个字节)连续在一起,叫组合流。但这种方式不能够提供失真的伸缩性,但他们也是嵌入式的编码。 为了达到失真伸缩性,需要将码块的编码分为多次(或多个过程),每次为图象质量贡献一部分字节,如下图描述: 这里的Qi表示质量层,码块为每层提供一定的长度用L表示。这里只描述了两层,因此对于每个码块来说,整体的编码被分配到各质量层上,当然有的码块可能对某些质量层没有任何贡献,也就是空的。另外图中的箭头表示码块组织的方式。在位流中,其需要为每个码块增加一个标志头。 例如:上面图中有两个分区,B0-B3是分区1,B4-B7是分区2,那么B0-B3的Q0层编码流组合就是一个包。 JPEG2000中有一个要求就是,将每个码块的头放在一起,组成包头,然后是码块的系数编码流。 层是一个包的集合;每个分区为层贡献一个包,而分区是按照分辨率层来进行划分的。 但它与分辨率层不同的概率,它的每个层都是全分辨率的,也就是说,如果按照层来查看样本,那么每个层的大小都和原来图像是一样大小的。 层的数量并不固定,主要有采用的应用类型决定。 单一层:如果不需要失真的伸缩性,那么就使用简单的组合流,只需要一层。 按照编码过程进行分层也是一个好办法,每层包含码块样本的一个编码过程,这样有多少个编码过程就有多少层。这也是EBCOT中采用三个编码过程的原因所在。 因此,从上面的理解我们可以知道,层是全分辨率的,每层都与原来图像一样大小;如果层不断累加,那么质量不断改善,最终得到原来的图像样本。 到目前,前面的例子已经足够告诉我们区域(Region)的含义了,这里不再介绍。 最后看一下渐进性。 JPEG2000最诱人的一点在于渐进性,随着数据的增加图像按照某种方式改善。 渐进性的四维是:质量、分辨率、空间和分量。 质量渐进性是通过上面介绍的层来实现的,随着层的增加,图像的质量不断改善。可以发现的是,每层实际上包括图像的某些部分,随着层的增加,图像越来越完整。