二维DCT变换
来源:互联网 发布:北京骏溢至信 淘宝 编辑:程序博客网 时间:2024/05/22 14:06
DCT(Discrete Consine Transform),又叫离散余弦变换,它的第二种类型,经常用于信号和图像数据的压缩。经过DCT变换后的数据能量非常集中,一般只有左上角的数值是非零的,也就是能量都集中在离散余弦变换后的直流和低频部分。
1. 一维DCT变换
一维DCT变换共有8中,其中最实用的是第二种形式,公式如下:
其中
2. 二维DCT变换
二维DCT变换是在一维的基础上再进行一次DCT变换,公式如下:
这里只讨论了两个
写成矩阵形式:
用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); endendY = 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); endendY = 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 npfrom scipy import fftpackdef dct(mat2x2): return fftpack.dct(fftpack.dct(mat2x2, norm='ortho').T, norm='ortho').Tdef 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变换
- 二维DCT变换
- 二维DCT变换
- 二维DCT变换
- 二维图像的DCT变换
- 二维DCT变换的实现
- DCT变换
- DCT变换
- DCT变换
- DCT变换
- dct变换
- DCT变换
- DCT变换
- dct变换
- DCT变换
- DCT变换
- DCT变换
- Zuken CADSTAR 16 破解过程
- 【数据结构与算法】拓扑排序
- Kali忘记root密码怎么办
- 【Leetcode】【python】Jump Game/Jump Game II
- 数组组合成最小的数
- 二维DCT变换
- 关于寻址空间的理解
- 一篇翻译eclipse的文章,不建议用翻译版,但是可以参考这样的翻译,以便理解
- [行业调研]区块链技术与行业发展简单调研笔记
- centos7系统下安装php-memcached拓展及简单使用
- 02-ECDF and Histogram
- 倡导无穷小微积分,理论自信来自何方?
- 03-Data Resampling
- MySql (三) 表约束和常用的数据类型