该编码方法的主要目的在于把统计相依的采样值变换成“某种程度上的统计独立”的系数。变换本身并不是压缩,只是将信号映射到另一域内,而在映射域内较容易实现压缩。把变换后的采样值通过比特分配的量化过程进行压缩,存储或传输变换后的压缩系数,从而达到压缩的目的。
常用的变换方法有离散傅里叶变换(DFT)、主分量变换(K-L)、离散余弦变换(DCT)以及近几年发展起来的小波变换。DFT、K-L、DCT等都是正交变换在生物医学数据压缩中的应用。这些正交变换在均方误差意义上性能较好,但从该意义上来比较上述的各种变换编码方法可以得出:主分量变换是最佳的,但无快速算法可循;离散余弦变换的性能几乎与主分量变换相同,且可借助于一些快速算法来实现,如利用循环卷积实现的快速算法;离散傅里叶变换的性能随着变换分量的增加而渐近地接近主分量变换,运算速度也快。特别是DCT运算速度快、质量高,且Ahmed等证明:与离散傅里叶变换、以及其他一些变换如哈尔(Haar)变换等来比较,DCT无论从均方误差还是速率失真等方面来看均是领先的,非常接近于K-L变换,但运算速度却大大高于K-L变换。因此不少学者均推崇利用离散余弦变换进行数据压缩,并且DCT已形成了专用软件。应用小波变换来进行数据压缩,公认有极好效果,但无论从理解和实现上都不太容易,并且在资源有限的微处理器上实现更是不太容易。
正交变换编码的基本思想是将数据信号变换到变换域进行描写,然后再根据变换域中系数的特点进行适当量化编码。采用正交变换编码进行数据压缩的进本思想,如图1所示:
图1正交变换编码压缩流程
正交变换具有能量守恒、能量集中、去相关性和熵保持的特性,无论在是在医疗数据处理中还是在图像处理中正交变换都得到广泛的应用。
DCT也是基于正交变换的一种编码方法,是N.Ahmed等人于1974年提出的。因为它变换矩阵的基向量很近似于Toeplitz矩阵的特征向量,而Toeplitz矩阵又体现了人类语音及图像信号的相关特性,因此DCT常常被认为是对语音和图形信号的准最佳变换,性能接近于K-L变换。
设{x(n)|n=0,1,2,…,N-1}代表一帧离散时间ECG数据序列,那么x(n)的DCT变换定义为
式中C(k)称为k次DCT分量。对应的正变换核为:
取反变换核=正变换核,则对应逆变换为:
代入对应的变换核, 则变换公式又可写为:
k=0,1,2,…,N-1
对应N=8的序列x(n)的变换示意图如图2所示,对应的变换核向量如图3所示。可见序列x(n)可以由N个变换核向量g(n,k)和DCT系数C(k)的线性加权和构成,其中变量k代表了序列x(n)在n方向上的广义变化频率。可以证明,这八个基波中任何两个不同频率的变换核向量乘后的代数和都为零,只有相同频率的变换核向量相乘后代数和不为零,这正是正交变换的特性。
图2 DCT变换示意图
图3 DCT变换核向量
在计算过程可以借助该变换核向量来计算序列x(n)的DCT变换和反变换,例如计算C(0),只要把x(n)与对应的k=0的变换核向量进行点点相乘再相加求和即可得到C(0);计算C(1),只要把x(n)与对应的k=1的变换核向量进行点点相乘再相加求和即可得到C(1);其他的DCT分量可以依次求得。
定义时域数据序列{x(n)|n=0,1,2,…,N-1}在DCT域中的归一化信号能量分布为:
m=0,1,2,…,N-1
由DCT变换示意图可以看出信号能量在变换域中的分布具有低频高幅和高频低幅的特点,当频率越高时DCT分量的值逐渐趋于零,所以信号能量主要集中地分布在前M(M
E (M-1)×100≥Eth
式中Eth为根据实际要求预选设定的门限值。
在压缩过程只存储或传输这前M个分量,其余的N-M个分量被忽略,从而达到压缩的目的。在解压缩过程进行反变换时,首先将被被忽略掉的N-M个分量用零补充(由变换示意图高频分量的幅值趋近于零),让对调整或的N个变换系数进行IDCT,便可具有很好保真度地恢复重现原数据序列。
Blackfin处理器是16位定点DSP,对于DCT变换压缩算法必须使用特定的浮点处理方法。常见的方法有Q0,Q15法表示浮点数。本程序使用Q0法表示,即16位全部表示整数,不含小数。
针对DSP的算法优化主要体现在浮点运算和查表运算上。
比如cos值为0到1之间的小数,用Q0法表示需要对cos值按照预定精度增大一定的比例。
本程序需要使用三个表,一是COS表:
将cos值预先乘上128,并将0~PI/2的范围分成512份,生成COS表。
cos(x), 0
当x>PI/2时,根据cos的周期性将它调整至0~2PI内,再根据cos的对称性调整x和结果的符号。
二是SQR平方根表;
三是除法表:
由于Blackfin处理器进行除法运算很耗时间,在这里采用预乘一个参数再左移m位的办法代替除法运算。这个参数就构成了除法表。
N / I = n * k [I] << m;
其中表项K[I] = 1 / I * 2^m