1. 图像的二维离散变换
与一维的有限长离散非周期信号存在傅里叶变换(DFT)一样,图像作为一个二维离散信号同样存在着二维离散变换(注意这里是介绍一个通用的概念,二维离散变换,包括了DFT、DCT等多种变换在内的一种通式写法),其通式可以表达为
1.1 二维变换的可分性与对称性
如果一个二维变换核同时具备可分性与对称性,此时允许用两个一维变换来计算二维变换,即首先沿着输入的行(列)进行一维变换,接着用第一步得到的结果再对列(行)进行一维变换。当变换对的正反变换都满足这个条件时,且
其中
1.2 为什么二维变换可以用矩阵表示
首先回顾一下什么样的图像可以使用
其中的F是图像矩阵,而
1.3 二维离散余弦变换
正变换
反变换
由上可知当
注意矩阵中有一个元素写错了,第3行第1列的元素应该是
2. DCT余弦变换的相关代码
2.1 编写DCT余弦变化矩阵 A 的代码
本代码根据网友“彼岸之音”的CSDN博客改写,如想了解更多细节请浏览 Matlab DCT详解。
clc;clear all;close all;
N = 8; % 这个是一个可以修改的参数,与原始的正方形图像的尺寸相同。
I = rand(N) % 被变换的矩阵,这里是一个随机生成的、元素分布在0到1的N*N的方阵
for i = 0:N-1
for j = 0:N-1
if i == 0
a = sqrt(1/N);
else
a = sqrt(2/N);
end
A(i+1,j+1) = a*cos((j+0.5)*pi*i/N)
end
end
D = A*I*A' % DCT变换
D1 = dct2(I) % matlab DCT函数进行DCT变换
D2 = A'*D*A % DCT逆变换
2.2 用矩阵相乘代替上述的 for 循环
无论是在MATLAB中,还是在puthon中使用numpy都有一个共同的特点,使用向量相乘或者矩阵相乘可以加快计算速度,所以下面的代码是在 2.1 代码的基础上,用矩阵相乘来代替 for 循环的一种形式。如果想了解这种方法的具体原理,可以参考博客《从 DTFT 的角度用矩阵相乘代替 for 循环进行计算》
clc;clear all;close all;
N = 4; % 这个是一个可以修改的参数,与原始的正方形图像的尺寸相同。
I = rand(N) % 被变换的矩阵,这里是一个随机生成的、元素分布在0到1的N*N的方阵
A = sqrt(2 / N)*cos((0:N-1)'*((0:N-1)+0.5)*pi/N);
A(1,:) = A(1,:) / sqrt(2)
D = A*I*A' % DCT变换
D1 = dct2(I) % matlab DCT函数进行DCT变换
D2 = A'*D*A % DCT逆变换
上面通过10行进行的计算在这里通过三行的矩阵相乘就可以代替了,代码精简了,而且会提高运算速度。
2.3 DCT 余弦变换的MATLAB命令
D = dct2(I) % matlab DCT函数对I进行DCT变换
D = dctmtx(N) % 如果矩阵A是N×N方阵,则A的DCT变换可用D×A×D’来计算,注意其中的N是维数,不是矩阵