二维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 ...
随机推荐
- nodejs运行的时候报错:Error: write EIO以及乱码解决方式
在运行node.js的过程中报如下错误: events.js:72 throw er; // Unhandled 'error' event ^ Error: write EIO at errnoEx ...
- SQL Server 数据收缩
1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小(如下图:数据库和日志两个文件),随着数据库的使用文件会逐渐增大.数据库文件大小的增加有两种方式: 自动增长:在自动增长中可以设置每 ...
- oracle与infomix异同点
之前是做oracle数据库应用开发的,现在工作用的是informix,特别不习惯.用了一段时间后才慢慢适应,最近做系统升级,把informix换成oracle数据库.顺便整理了一下informix与o ...
- [Oracle]Oracle良性SQL建议
(1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处 ...
- Web | Webpack快速上手
概述 Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 一般我们在开发中都是使用终端去进行安装,使用npm,关于npm ...
- 一次“Error Domain=AVFoundationErrorDomain Code=-11841”的调试
一次"Error Domain=AVFoundationErrorDomain Code=-11841"的调试 起因 最近在重构视频输出模块的时候,调试碰到AVAssetReade ...
- 获取Linux下的IP地址 java代码
/** * 获取Linux下的IP地址 * * @return IP地址 * @throws SocketException */ public static String getLinuxLocal ...
- #leetcode刷题之路41-缺失的第一个正数
给定一个未排序的整数数组,找出其中没有出现的最小的正整数.示例 1:输入: [1,2,0]输出: 3示例 2:输入: [3,4,-1,1]输出: 2示例 3:输入: [7,8,9,11,12]输出: ...
- 《Redis设计与实现》- 数据库
1. 服务器中数据库结构 Redis 服务器将所有数据库都保存在服务器状态 redisServer 结构的 db 数组中,由 redisDb 结构代表一个数据库 struct redisServer ...
- SQL注入科普
技术交流,安全交友联系渔夫”小白“,微信号(xz116035) SQL注入介绍 SQL注入攻击是最为常见的Web应用安全漏洞之一,国外知名安全组织OWASP针对web应用安全漏洞进行了一个排名,SQL ...