利用TMS320C6201芯片进行图像压缩
摘要:介绍了利用TMS320C6201 DSP芯片进行实时图像压缩的软件设计。结合该芯片的编程特点介绍了压缩算法,并给出了部分关键程序,具有一定的参考价值。
关键词:图像压缩 C6201 FDCT变换 霍夫曼编码
图像中含有丰富的信息,在现代科技中将图像作为一种探测手段,正受到越来越广泛的青睐。有很多探测设备,采用扫描成像仪器作为前端探测器。作为一种很常见的情况,成像仪器采集到的图像要通过无线信道进行发送。但是,图像数据通常都是海量数据,无线信道的传输带宽无法满足要求,必须对图像进行压缩处理,才能通过无线信道进行传输。
javascript:window.open(this.src);" style="cursor:pointer;"/>
实现图像实时无线传输必须研制专门的图像压缩,该压缩器须满足如下要求:(1)图像实时压缩?鸦(2)能够较好地保存图像质量。笔者以TI公司的高速DSP芯片TMS320C6201为核心的数字信号处理板作为图像压缩器的硬件平台,通过自行开发的压缩程序,实现了图像的实时压缩。
javascript:window.open(this.src);" style="cursor:pointer;"/>
1 数字信号处理板的硬件功能框图
数字信号处理板的硬件功能框图如图1所示。TMS320C6201是一种高性能的定点数字信号处理器。工作频率为200MHz时,每个指令周期为5ns,运算速度可达1600MIPS;具有VLIW(甚长指令集)体系结构,每周期8个32bit的指令并行执行;8个独立的功能单元,有两个16bit乘法器和6个算术逻辑单元;采用加载存储体系结构,数据在多处理单元之间的传输依靠32个32bit的通用寄存器。C6000的存储器寻址空间为32bit,片内有1Mbit的SRAM。片内RAM被分为两块:一是内部程序/cache存储器,二是内部数据存储器。32bit外部存储器接口(EMIF)可与不同存储器接口,可方便地配置不同速度、不同容量、不同复杂程度的存储器。此外,C6000还有两通道Boot-loading DMA处理器、16bit的主机接口HPI、两个多通道缓冲串口(McBSP),并且其片内锁相环(PLL)时钟发生器,可以对输入时钟进行不同的倍频处理。这种芯片用来处理图像压缩这种运算密集型的工作是非常合适的。功能框图的其它部分不再做介绍。
图3 图像压缩器的工作过程方框图
2 图像压缩算法
图像压缩中的图像有彩色和灰度之分。考虑到彩色图像和灰度图像的压缩类似,且大多数的扫描成象设备扫的是灰度图像,所以仅以灰度图像的压缩为例介绍DSP上的图像压缩。图像压缩算法原理图如图2所示。
图中,首先将原始灰度图像分为8×8的图块,然后对每一图像块进行FDCT变换,再将变换得到的DCT系数使用量化表进行量化。量化后可得到如下形式的数据:
(x)是不为零的数据)
x x x x 0 0 0 0
x x x 0 0 0 0 0
x x 0 0 0 0 0 0
x 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
该数据在存储器中存放的顺序如下:
z[0] z[1] z[2] z[3] z[4] x[5] z[6] z[7]
z[8] z[9] z[10] z[11] z[12] z[13] z[14] z[15]
z[16] z[17] z[18] z[19] z[10] z[21] z[22] z[23]
z[24] z[25] z[26] z[27] z[28] z[29] z[30] z[31]
z[32] z[33] z[34] z[35] z[36] z[37] z[38] z[39]
z[40] z[41] z[42] z[43] z[44] z[45] z[46] z[47]
z[48] z[49] z[50] z[51] z[52] z[53] z[54] z[55]
z[56] z[57] z[58] z[59] z[60] z[61] z[62] z[63]
在存储器中,非零数据和零数据交替存放,不便于压缩,所以要对数据进行重排列,数据的重排列形式如下:
z[0] z[1] z[5] z[6] z[14] z[15] z[27] z[28]
z[2] z[4] z[7] z[13] z[16] z[26] z[29] z[42]
z[3] z[8] z[12] z[17] z[25] z[30] z[41] z[43]
z[9] z[11] z[18] z[24] z[31] z[40] z[44] z[53]
z[10] z[19] z[23] z[32] x[39] z[45] z[52] z[54]
z[20] z[22] z[33] z[38] z[46] z[51] z[55] z[60]
z[21] z[34] z[37] z[47] z[50] z[56] z[59] z[61]
z[35] z[36] z[48] z[49] z[57] z[58] z[62] z[63]
变换完成后再根据编码表对DC系数和AC系数分别进行编码,就完成了图像的压缩。
图4 量化表
3 利用DSP芯片进行图像压缩
3.1 图像压缩器的工作过程
图像压缩器工作过程方框图如图3所示。
图像数据通过I/O接口送入数字信号处理板,由DSP芯片中的DMA控制器负责将数据放入输入缓冲区中,DSP对缓冲的图像数据进行压缩后,通过HPI接口将压缩数据送出。
3.2 编程介绍
这里主要介绍压缩参数初始化和压缩程序。
3.2.1 压缩参数初始化
由图2所示的图像压缩算法可知,图像压缩过程中需要量化表和编码表,量化表如图4(a)所示。
javascript:window.open(this.src);" style="cursor:pointer;"/>
量化操作就是把8×8图块进行FDCT变换,将变换后的的DCT系数用量化表元素来除。由于DSP中有硬件乘法器和移位指令,为了充分提高程序的执行速度,应该将除法运算转化为乘法运算和移位运算,对上面的量化表元素逐个求倒数并用16进制表示,如图4(b)所示。
编码表有两个,一个是直流差值编码表,另一个是交流系数编码表,如图5所示。
编码表中的最左端的一列代表中间码字,具体编码时要根据8x8图块的DCT系数产生中间码字,再由中间码字查编码表,将中间码字转换为霍夫曼码,完成编码。在DSP程序初始化阶段要生成量化表和编码表,量化表可直接将图4(b)所示的量化表元素代入来得到,编码表就要按照霍夫曼码的编码方法生成霍夫曼码来得到。由于在压缩过程中要频繁地查找编码表,因此,编码表的组织形式对程序的执行效率影响很大。
3.2.2 压缩程序
图像压缩包括FDCT变换、标量量化、Zigzag扫描和编码等几个步骤,下面分别介绍。
3.2.2.1FDCT变换
DCT变换公式如下:
javascript:window.open(this.src);" style="cursor:pointer;"/>
javascript:window.open(this.src);" style="cursor:pointer;"/>
式中,Cu,Cv=
javascript:window.open(this.src);" style="cursor:pointer;"/>
具体压缩的时候要采用DCT变换的快速算法来加快程序的运行速度,将二维的DCT变换分解为两个一维的DCT变换,可以有效地降低计算量。CCS2.0(Code Composer Studio)中提供了一个成熟的C语言函数库,里面包含了进行FDCT变换的函数。函数原型如下:
void fdct_8×8(short *dct_data, unsigned num_fdcts);
函数中dct_data指针指向待变换的图像数据,javascript:window.open(this.src);" style="cursor:pointer;"/>num_fdcts是进行DCT变换的图像块的数目。该函数可以对一大块连续存放的图像块进行DCT变换,特别针对TMS320C6201 DSP芯片的特点进行了优化。考虑到存储器的等待时间和指令的并行等问题,执行效率非常高,具体的程序开销可以通过如下公式计算:
时钟周期数=48+160*num_fdcts;
要在自己的工程中使用这个函数,必须把img62x.lib函数库添加到工程中,并且在主程序文件中包含fdct_8×8.h头文件。
3.2.2.2 标量量化
所谓标量量化就是对8×8图像块的DCT变换系数使用量化表逐个相除并四舍五入。CCS2.0提供了一个量化函数,其原型如下:
void quantize
(
short *data, /* Data to be quantized. */
int num_blks, /*Number of 64-element blocks.?*/
int blk_size, /*Block size (multiple of 8). */
const short *recip_tbl, /*Quant. values (reciprocals). */
int q_pt /*Q-point of Quant values.*/
);
将图4(b)所示的量化表元素代入程序,blk_size为64,q_pt为16,data指向量化数据,即可进行快速的量化。该程序同样经过了优化,具体的程序开销可按如下公式计算:
时钟周期数= 25+(blk_size/16)*4+num_blks*12)
该函数同样包含在img62x.lib库中,javascript:window.open(this.src);" style="cursor:pointer;"/>程序中应包含quantize.h头文件。
3.2.2.3 ZigZag扫描
ZigZag扫描就是对数据进行重排列。该部分功能简单、运算量也不大,但是对存储器的访问非常频繁,而且影响处理器执行速度的主要是对存储器的访问速度。一般情况下,CPU访问内部存储器需要4个时钟周期,访问外部存储器的速度要比内部存储器的速度慢得多,具体情况应根据实际使用的外部存储器的类型而定。由于TMS3206201 DSP芯片每秒钟最多可以执行8条指令,如果让DSP芯片经常处于等待状态是非常大的浪费。解决该问题的最有效的办法是充分利用数据总线的宽度并让软件进行流水线执行。TMS320C6201的数据总线宽度是32位,一般情况下DCT系数使用一个短整型数,只有16位宽度,如果每次同时从存储器中读写两个数,则可以减少一半访问存储器的次数。由于TMS320C6201有8个功能单元,CPU可以在处理当前数据的同时去存储器取下一个数据。通过流水线,CPU可以做到每周期访问一次存储器,这样可以使程序的执行效率大大提高。一般情况下软件的流水线安排是由编译优化系统完成的,程序员所要做的是让自己的程序符合流水线执行的要求,并且让优化后的流水线周期尽量短。流水线的要求主要有以下几点:
(1)程序所使用的寄存器数目不能超过32个;
(2)程序所使用的条件寄存器数目不能超过5个;
(3)程序中不能含有分支语句,可能的话尽量使用条件指令;
(4)一个寄存器中的变量值不能存放太长时间,实在不行就换个寄存器存放;
(5)程序所使用的CPU左右两边的资源尽量平衡,一般情况下,平衡的资源使用换来的是比较短的流水线周期;
(6)程序中包含的指令不能太多。
对于用线性汇编语言编写的程序,应该在程序编写时注意这些问题。对一个用C语言编写的程序,可以通过观察编译系统产生的优化后的汇编语言文件来获得相关的信息。具体程序略。
3.2.2.4 编码
编码部分主要是对量化后的DCT系数进行处理,主要利用了相邻图像块之间的相关性、量化后的DCT系数矩阵的连零特性和霍夫曼编码应进行压缩编码。该部分主要涉及了查表、移位运算和存储器读写。DC差值/AC系数等级表如图6所示。
javascript:window.open(this.src);" style="cursor:pointer;"/>