Scipy:生成NxN离散余弦矩阵
Scipy: generate NxN discrete cosine matrix
使用 scipy,是否有一种简单的方法可以模拟 MATLAB 的 dctmtx
函数的行为,该函数 returns 某个给定 N 的 NxN DCT 矩阵?有 scipy.fftpack.dctn
但这只适用于 DCT。
如果我不想使用 scipy 之外的其他依赖项,我是否必须从头开始实现它?
DCT 是一种线性变换,因此获取变换矩阵的一种方法是将其应用于单位矩阵。这是一个示例,其中我找到长度为 8 的序列的矩阵(对于一般情况,将 8 更改为 N
):
In [124]: import numpy as np
In [125]: from scipy.fft import dct
In [126]: D = dct(np.eye(8), axis=0)
D
是矩阵:
In [127]: D
Out[127]:
array([[ 2. , 2. , 2. , 2. , 2. , 2. , 2. , 2. ],
[ 1.96157056, 1.66293922, 1.11114047, 0.39018064, -0.39018064, -1.11114047, -1.66293922, -1.96157056],
[ 1.84775907, 0.76536686, -0.76536686, -1.84775907, -1.84775907, -0.76536686, 0.76536686, 1.84775907],
[ 1.66293922, -0.39018064, -1.96157056, -1.11114047, 1.11114047, 1.96157056, 0.39018064, -1.66293922],
[ 1.41421356, -1.41421356, -1.41421356, 1.41421356, 1.41421356, -1.41421356, -1.41421356, 1.41421356],
[ 1.11114047, -1.96157056, 0.39018064, 1.66293922, -1.66293922, -0.39018064, 1.96157056, -1.11114047],
[ 0.76536686, -1.84775907, 1.84775907, -0.76536686, -0.76536686, 1.84775907, -1.84775907, 0.76536686],
[ 0.39018064, -1.11114047, 1.66293922, -1.96157056, 1.96157056, -1.66293922, 1.11114047, -0.39018064]])
验证 D @ x
等同于 dct(x)
:
In [128]: x = np.array([1, 2, 0, -1, 3, 0, 1, -1])
In [129]: dct(x)
Out[129]: array([10. , 4.02535777, -1.39941754, 7.38025967, -1.41421356, -6.39104653, -7.07401092, 7.51550307])
In [130]: D @ x
Out[130]: array([10. , 4.02535777, -1.39941754, 7.38025967, -1.41421356, -6.39104653, -7.07401092, 7.51550307])
请注意 D @ x
通常会比 dct(x)
慢很多。
要与 Matlab 的 dctmtx
完全一致,请添加参数 norm='ortho'
。例如,这里是 Octave 中的 dctmtx
(returns 与 Matlab 中的数组相同):
octave:1> pkg load image
octave:2> dctmtx(4)
ans =
0.50000 0.50000 0.50000 0.50000
0.65328 0.27060 -0.27060 -0.65328
0.50000 -0.50000 -0.50000 0.50000
0.27060 -0.65328 0.65328 -0.27060
这里是使用scipy.fft.dct
的计算:
In [56]: from scipy.fft import dct
In [57]: dct(np.eye(4), axis=0, norm='ortho')
Out[57]:
array([[ 0.5 , 0.5 , 0.5 , 0.5 ],
[ 0.65328148, 0.27059805, -0.27059805, -0.65328148],
[ 0.5 , -0.5 , -0.5 , 0.5 ],
[ 0.27059805, -0.65328148, 0.65328148, -0.27059805]])
使用 scipy,是否有一种简单的方法可以模拟 MATLAB 的 dctmtx
函数的行为,该函数 returns 某个给定 N 的 NxN DCT 矩阵?有 scipy.fftpack.dctn
但这只适用于 DCT。
如果我不想使用 scipy 之外的其他依赖项,我是否必须从头开始实现它?
DCT 是一种线性变换,因此获取变换矩阵的一种方法是将其应用于单位矩阵。这是一个示例,其中我找到长度为 8 的序列的矩阵(对于一般情况,将 8 更改为 N
):
In [124]: import numpy as np
In [125]: from scipy.fft import dct
In [126]: D = dct(np.eye(8), axis=0)
D
是矩阵:
In [127]: D
Out[127]:
array([[ 2. , 2. , 2. , 2. , 2. , 2. , 2. , 2. ],
[ 1.96157056, 1.66293922, 1.11114047, 0.39018064, -0.39018064, -1.11114047, -1.66293922, -1.96157056],
[ 1.84775907, 0.76536686, -0.76536686, -1.84775907, -1.84775907, -0.76536686, 0.76536686, 1.84775907],
[ 1.66293922, -0.39018064, -1.96157056, -1.11114047, 1.11114047, 1.96157056, 0.39018064, -1.66293922],
[ 1.41421356, -1.41421356, -1.41421356, 1.41421356, 1.41421356, -1.41421356, -1.41421356, 1.41421356],
[ 1.11114047, -1.96157056, 0.39018064, 1.66293922, -1.66293922, -0.39018064, 1.96157056, -1.11114047],
[ 0.76536686, -1.84775907, 1.84775907, -0.76536686, -0.76536686, 1.84775907, -1.84775907, 0.76536686],
[ 0.39018064, -1.11114047, 1.66293922, -1.96157056, 1.96157056, -1.66293922, 1.11114047, -0.39018064]])
验证 D @ x
等同于 dct(x)
:
In [128]: x = np.array([1, 2, 0, -1, 3, 0, 1, -1])
In [129]: dct(x)
Out[129]: array([10. , 4.02535777, -1.39941754, 7.38025967, -1.41421356, -6.39104653, -7.07401092, 7.51550307])
In [130]: D @ x
Out[130]: array([10. , 4.02535777, -1.39941754, 7.38025967, -1.41421356, -6.39104653, -7.07401092, 7.51550307])
请注意 D @ x
通常会比 dct(x)
慢很多。
要与 Matlab 的 dctmtx
完全一致,请添加参数 norm='ortho'
。例如,这里是 Octave 中的 dctmtx
(returns 与 Matlab 中的数组相同):
octave:1> pkg load image
octave:2> dctmtx(4)
ans =
0.50000 0.50000 0.50000 0.50000
0.65328 0.27060 -0.27060 -0.65328
0.50000 -0.50000 -0.50000 0.50000
0.27060 -0.65328 0.65328 -0.27060
这里是使用scipy.fft.dct
的计算:
In [56]: from scipy.fft import dct
In [57]: dct(np.eye(4), axis=0, norm='ortho')
Out[57]:
array([[ 0.5 , 0.5 , 0.5 , 0.5 ],
[ 0.65328148, 0.27059805, -0.27059805, -0.65328148],
[ 0.5 , -0.5 , -0.5 , 0.5 ],
[ 0.27059805, -0.65328148, 0.65328148, -0.27059805]])