龙空技术网

JPEG编码详解之离散余弦变换

踏穿世路觉山平 119

前言:

而今同学们对“dct变换的原理及算法”可能比较着重,看官们都想要了解一些“dct变换的原理及算法”的相关资讯。那么小编在网上搜集了一些有关“dct变换的原理及算法””的相关文章,希望兄弟们能喜欢,咱们一起来学习一下吧!

JPEG编码过程主要为变换、量化、编码三个阶段。其中变化阶段主要是将空域转为频域信息,因为一般图像中大部分信息是低频信号,人眼对高频信号相对不灵敏,转化为频率信号后更容易去冗余。

一、DCT简介

DCT变换的全称是离散余弦变换(Discrete Cosine Transform),主要用于将数据或图像的压缩,能够将空域的信号转换到频域上,具有良好的去相关性的性能。DCT变换本身是无损的,但是在图像编码等领域给接下来的量化、哈弗曼编码等创造了很好的条件,同时,由于DCT变换时对称的,所以,我们可以在量化编码后利用DCT反变换,在接收端恢复原始的图像信息。DCT变换在当前的图像分析已经压缩领域有着极为广大的用途,我们常见的JPEG静态图像编码以及MJPEG、MPEG动态编码等标准中都使用了DCT变换。

二、一维DCT变换

一维DCT变换是二维DCT变换的基础,所以我们先来讨论下一维DCT变换。一维DCT变换共有8种形式,其中最常用的是第二种形式,由于其运算简单、适用范围广。我们在这里只讨论这种形式,其表达式如下:

一维dct

其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。对应的逆DCT变换公式为:

一维dct逆变换

三、二维DCT变换

二维DCT变换其实是在一维DCT变换的基础上再做了一次DCT变换,其公式如下:

二维DCT变换

由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式:

matlab简化

接下来利用Matlab对这个过程进行仿真处理:

matlab做DCT

运行结果为:

运行结果

由上面的结果我们可以看出,我们采用的公式的方法和Matlab自带的dct变化方法结果是一致的,所以验证了我们方法的正确性。

如果原始信号是图像等相关性较大的数据的时候,我们可以发现在变换之后,系数较大的集中在左上角,而右下角的几乎都是0,其中左上角的是低频分量,右下角的是高频分量,低频系数体现的是图像中目标的轮廓和灰度分布特性,高频系数体现的是目标形状的细节信息。DCT变换之后,能量主要集中在低频分量处,这也是DCT变换去相关性的一个体现。

之后在量化和编码阶段,我们可以采用“Z”字形编码,这样就可以得到大量的连续的0,这大大简化了编码的过程。

四、DCT反变换

在图像的接收端,根据DCT变化的可逆性,我们可以通过DCT反变换恢复出原始的图像信息,其公式如下:

DCT逆变换

同样的道理,我们利用之前的矩阵运算公式可以推导出DCT反变换相应的矩阵形式:

matlab简化

下面我们用Matlab对这个过程进行仿真:

matlab运行

运行结果为:

运行结果

我们可以看到反变换后无损的恢复了原始信息,所以证明了方法的正确性。但是在实际过程中,需要量化编码或者直接舍弃高频分量等处理,所以会出现一定程度的误差,这个是不可避免的。

五、分块DCT变换

在实际的图像处理中,DCT变换的复杂度其实是比较高的,所以通常的做法是,将图像进行分块,然后在每一块中对图像进行DCT变换和反变换,在合并分块,从而提升变换的效率。具体的分块过程中,随着子块的变大,算法复杂度急速上升,但是采用较大的分块会明显减少图像分块效应,所以,这里面需要做一个折中,在通常使用时,大都采用的是8*8的分块。

Matlab的 blkproc 函数可以帮我们很方便地进行分块处理,下面使用matlab对读取的图片做dct。给出我们的处理过程:

分块DCT

运行结果:

全局dct

分块dct

从图中,我们可以明显看出DCT变换与分块DCT变换在使用时的区别。

标签: #dct变换的原理及算法 #jpeg编码原理主要分为几个部分 #dct数字水印提取算法matlab