二维DCT变换
DCT(Discrete Consine Transform),又叫离散余弦变换,它的第二种类型,经常用于信号和图像数据的压缩。经过DCT变换后的数据能量非常集中,一般只有左上角的数值是非零的,也就是能量都集中在离散余弦变换后的直流和低频部分。
1. 一维DCT变换
一维DCT变换共有8中,其中最实用的是第二种形式,公式如下:
\]
\]
其中\(c(u)\)就是加上去一个系数,为了能使DCT变换变成正交矩阵。\(N\)是\(f(x)\)的总数。
2. 二维DCT变换
二维DCT变换是在一维的基础上再进行一次DCT变换,公式如下:
\]
这里只讨论了两个\(N\)相等的情况,也就是数据是方阵的形式,在实际应用中对不是方阵的数据都是先补齐再进行变换的。
写成矩阵形式:
\]
\]
用MATLAB进行验证:
clear;
clc;
X = round(rand(4) * 100); % 生成随机数据
A = zeros(4); % 变换矩阵
for i = 0 : 3
if i == 0
c = sqrt(1/4);
else
c = sqrt(2/4);
end
for j = 0 : 3
A(i + 1, j + 1) = c * cos(pi * (j + 0.5) * i / 4);
end
end
Y = A * X * A'; % DCT变换
YY = dct2(X); % 使用MATALAB函数进行DCT变换
disp('使用公式进行DCT变换:')
disp(Y)
disp('使用MATLAB函数DCT变换:')
disp(YY)
输入结果:
使用公式进行DCT变换:
204.7500 -2.5322 27.2500 24.5909
32.1461 3.7448 -20.9667 24.5450
54.2500 -1.9287 -2.2500 -24.9079
12.9327 -40.4550 -25.1401 9.7552
使用MATLAB函数DCT变换:
204.7500 -2.5322 27.2500 24.5909
32.1461 3.7448 -20.9667 24.5450
54.2500 -1.9287 -2.2500 -24.9079
12.9327 -40.4550 -25.1401 9.7552
3. 二维DCT逆变换
DCT逆变换的公式如下:
\]
\]
矩阵形式的变换公式推到如下:
\]
用MATALAB进行验证:
clear;
clc;
X = round(rand(4) * 100); % 生成随机数据
A = zeros(4); % 变换矩阵
for i = 0 : 3
if i == 0
c = sqrt(1/4);
else
c = sqrt(2/4);
end
for j = 0 : 3
A(i + 1, j + 1) = c * cos(pi * (j + 0.5) * i / 4);
end
end
Y = A * X * A'; % DCT变换
XX = A'* Y* A; % DCT逆变换
disp('原始矩阵:')
disp(X)
disp('使用公式进行DCT逆变换:')
disp(XX)
disp('使用MATLAB函数DCT逆变换:')
disp(idct2(Y))
输出结果:
原始矩阵:
28 69 44 19
5 32 38 49
10 95 77 45
82 3 80 65
使用公式进行DCT逆变换:
28.0000 69.0000 44.0000 19.0000
5.0000 32.0000 38.0000 49.0000
10.0000 95.0000 77.0000 45.0000
82.0000 3.0000 80.0000 65.0000
使用MATLAB函数DCT逆变换:
28.0000 69.0000 44.0000 19.0000
5.0000 32.0000 38.0000 49.0000
10.0000 95.0000 77.0000 45.0000
82.0000 3.0000 80.0000 65.0000
4. DCT变换的可分离性
DCT变换是可分离的变换。通常根据可分离性,二维DCT可用两次一维DCT变换来完成,即
\]
先进行行变换,再进行列变换和先进行列变换,再进行行变换的结果是一样的。
Python scipy模块中的fftpack.dct()函数提供了一维DCT变换功能(默认是沿着矩阵的最后一个axis进行变换),下面使用Python代码进行验证。
import numpy as np
from scipy import fftpack
def dct(mat2x2):
return fftpack.dct(fftpack.dct(mat2x2, norm='ortho').T, norm='ortho').T
def dct2(mat2x2):
return fftpack.dct(fftpack.dct(mat2x2.T, norm='ortho').T, norm='ortho')
if __name__ == '__main__':
sample = np.random.rand(3, 3)
print('先进行行变换,再进行列变换:')
print(dct(sample))
print('先进行列变换,再进行行变换:')
print(dct2(sample))
输出结果:
先进行行变换,再进行列变换:
[[ 1.3763706 -0.42355794 0.03903157]
[-0.18270004 0.06454257 -0.05273778]
[ 0.16962548 0.22247218 -0.06953193]]
先进行列变换,再进行行变换:
[[ 1.3763706 -0.42355794 0.03903157]
[-0.18270004 0.06454257 -0.05273778]
[ 0.16962548 0.22247218 -0.06953193]]
5. DCT用于图像压缩
对于二维灰度图像进行DCT变换,就能得到图像的频谱图:低阶(变化幅度小)的部分反映在DCT的左上方,高阶(变化幅度大)的部分反映在DCT的右下方。由于人眼对高阶部分不敏感,依靠低阶部分就能基本识别出图像内容,所以JPEG进行压缩的时候,基本上只存储DCT变换后的左上部分,而右下部分则直接丢弃。
MATALAB代码验证:
clear;
clc;
im = imread('https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png'); % 读入图像
figure(),
subplot(221),
imshow(im);
title('原始彩色图像');
grayim = rgb2gray(im);
dctim = dct2(grayim);
subplot(222),
% imshow(I,[]) displays the grayscale image I scaling the display based on the range of pixel values in I.
imshow(log(abs(dctim)), []),
title('DCT变换图像');
idctim = idct2(dctim);
subplot(223),
imshow(idctim, [])
title('DCT逆变换图像');
subplot(224),
imshow(grayim)
title('原始灰度图像');
运行结果:

参考文献
[1] 二维DCT变换:https://wuyuans.com/2012/11/dct2
[2] 余弦离散变换原理及应用:http://blog.csdn.net/shenziheng1/article/details/52965104
[3] MATLAB分析图像的离散余弦变换(DCT):http://blog.csdn.net/u013354805/article/details/52259471
[4] 图像DCT变换:https://feichashao.com/image_dct/
二维DCT变换的更多相关文章
- 二维DCT变换 | Python实现
引言 最近专业课在学信息隐藏与数字水印,上到了变换域隐藏技术,提到了其中的DCT变换,遂布置了一个巨烦人的作业,让手动给两个\(8\times8\)的矩阵做二维DCT变换,在苦逼的算了一小时后,我决定 ...
- DCT变换、DCT反变换、分块DCT变换
一.引言 DCT变换的全称是离散余弦变换(Discrete Cosine Transform),主要用于将数据或图像的压缩,能够将空域的信号转换到频域上,具有良好的去相关性的性能.DCT变换本身是无损 ...
- UWP开发-二维变换以及三维变换
在开发中,由于某些需求,我们可能需要做一些平移,缩放,旋转甚至三维变换,所以我来讲讲在UWP中这些变换的实现方法. 一. 二维变换: UIElement.RenderTransform a.Trans ...
- 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程
转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...
- SSE图像算法优化系列二十一:基于DCT变换图像去噪算法的进一步优化(100W像素30ms)。
在优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码) 一文中,我们曾经优化过基于DCT变换的图像去噪算法,在那文所提供的Demo中,处理一副1000*1000左右的灰度噪音图像耗时 ...
- C++实现离散余弦变换(参数为二维指针)
C++实现离散余弦变换(参数为二维指针) 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现.在实现论文 ...
- 二维离散余弦变换(2D-DCT)
图像处理中常用的正交变换除了傅里叶变换以外,还有一些其它常用的正交变换,其中离散余弦变换DCT就是一种,这是JPEG图像压缩算法里的核心算法,这里我们也主要讲解JPEG压缩算法里所使用8*8矩阵的二维 ...
- 通过Matrix进行二维图形仿射变换
Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的"平直性"和"平行性".仿射变换可以通过一系列的原子变换的复合来 ...
- openGL实现二维图形和三维图形
openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是ope ...
随机推荐
- SSM项目引入文件失败
<mvc:resources mapping="/styles/**" location="/css/"/> <mvc:resources m ...
- Annotation原理
为什么使用注解: 1.通过注解,可保存源数据在Java源代码中:并且注解不同于注释,注解享有编译期的类型检查保护. 2.可在描述符性质的类或接口中抽取重复性的工作,通过注解来简化与自动化这些工作. 注 ...
- iOS 根据url生成二维码贴到底图上
根据url 生成指定尺寸的二维码图片 UIImage * createBinaryCodeImg(const char * url ,CGFloat size) { //create binary c ...
- Java中的集合和常用类
Java中的常用类: ▪ Object类 ▪ Math类 ▪ String类和StringBuffer类(字符串) ▪ 8种基本类型所对应的包装类 ▪ java.util包中的类——Date类 Obj ...
- Java并发编程(三)什么是线程池
什么是线程池 学习编程的小伙伴们会经常听到“线程池”.“连接池”这类的词语,可是到底“池”是什么意思呢?我讲个故事大家就理解了:在很久很久以前有一家银行,一年之中只有一个客户来办理业务,随着时间的推移 ...
- [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序
近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...
- 九九乘法表,全js编写,放入table表格带入页面渲染出来
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 数据立方体(Cube)
如上图所示,这是由三个维度构成的一个OLAP立方体,立方体中包含了满足条件的cell(子立方块)值,这些cell里面包含了要分析的数据,称之为度量值.显而易见,一组三维坐标唯一确定了一个子立方. 多位 ...
- 树莓派3B+学习笔记:11、查看硬件信息
1.查看CPU信息 cat /proc/cpuinfo 查看最后三行 如果只想查看最后三行,也可使用这个命令 /proc/cpuinfo lscpu 2.查看树莓派型号 cat /proc/devic ...
- helpera64开发板下制作ubuntu rootfs镜像(二)
上一篇路径:https://www.cnblogs.com/jizizh/p/10380513.html Helpera64开发板ubuntu剩于工作: 1.背光调节 答:/sys/class/bac ...