【DCT笔记】DCT变换、DCT反变换、分块DCT变换

DCT变换、DCT反变换、分块DCT变换



欢迎转载,但请注明出处!

一、引言

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


二、一维DCT变换

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

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


三、二维DCT变换

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

由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。

另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式:

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

 1 clear;
 2 clc;
 3 X=round(rand(4)*100)   %产生随机矩阵
 4 A=zeros(4);
 5 for i=0:3
 6     for j=0:3
 7         if i==0
 8             a=sqrt(1/4);
 9         else
10             a=sqrt(2/4);
11         end
12         A(i+1,j+1)=a*cos(pi*(j+0.5)*i/4);
13     end
14 end
15 Y=A*X*A‘        %DCT变换
16 YY=dct2(X)      %Matlab自带的dct变换

运行结果为:

 1 X =
 2
 3     42    66    68    66
 4     92     4    76    17
 5     79    85    74    71
 6     96    93    39     3
 7
 8
 9 Y =
10
11   242.7500   48.4317   -9.7500   23.5052
12   -12.6428  -54.0659    7.4278   22.7950
13    -6.2500   10.7158  -19.7500  -38.8046
14    40.6852  -38.7050  -11.4653  -45.9341
15
16
17 YY =
18
19   242.7500   48.4317   -9.7500   23.5052
20   -12.6428  -54.0659    7.4278   22.7950
21    -6.2500   10.7158  -19.7500  -38.8046
22    40.6852  -38.7050  -11.4653  -45.9341

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

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

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


四、二维DCT反变换

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

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

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

 1 clear;
 2 clc;
 3 X=[
 4     61    19    50    20
 5     82    26    61    45
 6     89    90    82    43
 7     93    59    53    97] %原始的数据
 8 A=zeros(4);
 9 for i=0:3
10     for j=0:3
11         if i==0
12             a=sqrt(1/4);
13         else
14             a=sqrt(2/4);
15         end
16         A(i+1,j+1)=a*cos(pi*(j+0.5)*i/4); %生成变换矩阵
17     end
18 end
19 Y=A*X*A‘   %DCT变换后的矩阵
20 X1=A‘*Y*A  %DCT反变换恢复的矩阵

运行结果为:

 1 X =
 2
 3     61    19    50    20
 4     82    26    61    45
 5     89    90    82    43
 6     93    59    53    97
 7
 8
 9 Y =
10
11   242.5000   32.1613   22.5000   33.2212
12   -61.8263    7.9246  -10.7344   30.6881
13   -16.5000  -14.7549   22.5000   -6.8770
14     8.8322   16.6881  -35.0610   -6.9246
15
16
17 X1 =
18
19    61.0000   19.0000   50.0000   20.0000
20    82.0000   26.0000   61.0000   45.0000
21    89.0000   90.0000   82.0000   43.0000
22    93.0000   59.0000   53.0000   97.0000

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


五、分块DCT变换

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

Matlab的 blkproc 函数可以帮我们很方便的进行分块处理,下面给出我们的处理过程:

 1 clear;
 2 clc;
 3
 4 X=imread(‘pepper.bmp‘);
 5 X=double(X);
 6 [a,b]=size(X);
 7 Y=blkproc(X,[8 8],‘dct2‘);
 8 X1=blkproc(Y,[8 8],‘idct2‘);
 9
10 figure
11 subplot(1,3,1);
12 imshow(uint8(X));
13 title(‘原始图‘);
14
15 subplot(1,3,2);
16 imshow(uint8(Y));
17 title(‘分块DCT变换图‘);
18
19 subplot(1,3,3);
20 imshow(uint8(X1));
21 title(‘分块DCT恢复图‘);
22
23 Y1=dct2(X);
24 X10=idct2(Y1);
25
26 figure
27 subplot(1,3,1);
28 imshow(uint8(X));
29 title(‘原始图‘);
30
31 subplot(1,3,2);
32 imshow(uint8(Y1));
33 title(‘DCT变换图‘);
34
35 subplot(1,3,3);
36 imshow(uint8(X10));
37 title(‘DCT反变换恢复图‘);

运行结果为:

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


六、小结

DCT、DWT等是图像处理的基础知识,之前一直有用到,但是没怎么好好整理下,今天在做稀疏编码的时候正好有用到,就顺便整了下,希望能够给后来者一些提示。

我的新浪微博:http://weibo.com/3109428257/profile?rightmod=1&wvr=5&mod=personinfo

Reference:http://wuyuans.com/2012/11/dct2/

时间: 2025-01-02 19:36:59

【DCT笔记】DCT变换、DCT反变换、分块DCT变换的相关文章

【python下使用OpenCV实现计算机视觉读书笔记2】图像与字节的变换

import cv2 import numpy import os # Make an array of 120,000 random bytes. randomByteArray = bytearray(os.urandom(120000)) flatNumpyArray = numpy.array(randomByteArray) # Convert the array to make a 400x300 grayscale image. grayImage = flatNumpyArray

Matlab图像处理系列4———图像傅立叶变换与反变换

注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法 1.Fourier变换 (1)频域增强 除了在空间域内可以加工处理图像以外,我们还可以将图像变换到其他空间后进行处理,这些方法称为变换域方法,最常见的变换域是频域. 使用Fourier变换把图像从空间域变换到频域,在频域内做相应增强处理,再从频域变换到空间域得到处理后的图像. 我们这里主要学习Fourier变换和FFT变换的算法,没有学过通信原理,我对信号.时域分析也不是很清楚. 2.FFT算法 (1)离散Fourier变

模式识别(Pattern Recognition)学习笔记(三十五)-- K-L变换与PCA

K-L变换的理论知识 K-L变换是除了PCA外的另一种常用的特征提取方法,它有很多种形式,最基本的形式跟PCA类似,它跟PCA的不同在于,PCA是一种无监督的特征变换,而K-L变换能够考虑到不同的分类信息,实现有监督的特征提取. 根据随机过程中的KL展开理论,将随机过程描述为无数个正交函数的线性组合,而在模式识别问题中,通常可以将一个样本看成是随机向量的某一次实现结果,所以假设有一d维随机向量x,可以写成一组正交基的线性组合,且它们的模为1: 对上式变形得到:                  

OpenGl学习笔记3之模型变换、视图变换、投影变换、视口变换介绍

模型变换.视图变换.投影变换.视口变换介绍 opengl中存在四种变换,分别是模型变换,视图变换,投影变换,视口变换.这四种变换是图形渲染的基本操作,实质上这四种变换都是由矩阵乘法表示(这些操作都是由一个4*4的矩阵来完成的),通过变换,我们可以看到各种通的显示效果,最简单的效果就是让图元沿着某个方向变换(放大,缩小,翻转等)或者对所要显示的图元进行裁剪.接下来我们就详细介绍这四种变换以及相互之间的联系. 我们要在屏幕上显示一个具有三维坐标的物体,大致需要以下步骤: 1.     进行模型,视图

数字信号处理--Z变换,傅里叶变换,拉普拉斯变换

傅立叶变换.拉普拉斯变换.Z变换最全攻略 作者:时间:2015-07-19来源:网络 傅立叶变换.拉普拉斯变换.Z变换的联系?他们的本质和区别是什么?为什么要进行这些变换.研究的都是什么?从几方面讨论下. 本文引用地址:http://www.eepw.com.cn/article/277444.htm 这三种变换都非常重要!任何理工学科都不可避免需要这些变换. 傅立叶变换,拉普拉斯变换,Z变换的意义 [傅里叶变换]在物理学.数论.组合数学.信号处理.概率论.统计学.密码学.声学.光学.海洋学.结

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&&bzoj1692[Usaco2007 Dec]队列变换*

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换 bzoj1692[Usaco2007 Dec]队列变换 题意: 有一个奶牛队列.每次可以在原来队列的首端或是尾端牵出一头奶牛,把她安排到新队列的尾部,然后对剩余的奶牛队列重复以上的操作,直到所有奶牛都被插到了新的队列里.这样得到的队列,就是FJ拉去登记的最终的奶牛队列. 求对于给定的奶牛们的初始位置,计算出可能得到的字典序最小的队列.队列大小≤30000. 题解: 有一个结论:如果当前队列中的队首元素不等于队尾元

射影变换、仿射变换、欧式变换、相似变换、等距变换

射影变换组成了一个群,这个群被称为射影变换群.仿射变换是射影变换的子群.欧式变换(旋转+平移+等比缩放)是仿射变换的子群.相似变换和等距变换则是欧式变换的子群. 0.射影变换 定义 由有限次中心射影的积定义的两条直线间的一一对应变换称为一维射影变换.由有限次中心射影的积定义的两个平面之间的一一对应变换称为二维射影变换. 性质--交比不变性 如果平面上点场的点建立了一个一一对应,并且满足: (1)任何共线三点的象仍是共线三点: (2)共线四点的交比不变. 则这个一一对应叫做点场的射影变换,简称射影

Unity3D之空间转换学习笔记(一):场景物体变换

该系列笔记基于Unity3D 5.x的版本学习,部分API使用和4.x不一致. 目前在Unity3D中,除了新的UGUI部分控件外,所有的物体(GameObject)都必带有Transform组件,而Transform组件主要是控制物体在3D空间中的位置.旋转以及缩放. 学习和掌握物体的变换是Unity3D开发者必备的基础知识. 基础变换 最基础的变换就是通过脚本直接对物体的位置旋转缩放等进行变换. 匀速移动 我们下面实现一个匀速移动物体的效果,我们在场景中添加一个Cube物体,把下面的脚本绑定

OpenCV笔记(九)——更多的形态学变换

Erode和Dilate是基本的形态学运算,根据这两种运算,我们能够组成更多形态学运算. 一.开运算 Openning dst = open(src, element) = dilate(erode(src, element)) 开运算就是将一幅图像先腐蚀再膨胀,主要作用是移除白色的小区域. 二.闭运算 Closing dst = close(src, element) = erode(dilate(src, element)) 闭运算就是将一幅图像先膨胀再腐蚀,主要作用是移除黑色的小区域. 三