我想使用 scipy 的 DCT-II,因为它已经编码并且速度很快。查看文档,它似乎是一维实现。是否可以以将其用作 3D 实现的方式使用它?我不确定数学。2D 和 3D 实现是否相当于在计算中使用不同维度将 1D 乘以 2 或 3 倍?
问问题
3392 次
2 回答
7
基本上,以下方法可以解决问题:
import numpy as np
from scipy.fftpack import dct, idct
# Lets create a 3D array and fill it with some values
a = np.random.rand(3,3,3)
b = dct(dct(dct(a).transpose(0,2,1)).transpose(1,2,0)).transpose(1,2,0).transpose(0,2,1)
于 2012-12-19T06:32:55.110 回答
0
这是一个更通用的功能:
import numpy as np
from scipy.fftpack import dct, idct
def dctn(x, norm="ortho"):
for i in range(x.ndim):
x = dct(x, axis=i, norm=norm)
return x
def idctn(x, norm="ortho"):
for i in range(x.ndim):
x = idct(x, axis=i, norm=norm)
return x
然后:
>>> x = np.random.rand(2, 2, 2)
>>> x
array([[[0.316, 0.927],
[0.197, 0.936]],
[[0.832, 0.982],
[0.768, 0.564]]])
>>> dctn(x)
array([[[ 1.952, -0.459],
[ 0.209, -0.08 ]],
[[-0.272, -0.496],
[-0.132, 0.171]]])
>>> np.all(np.isclose(x, idctn(dctn(x))))
True
要使输出与@macrocosme 完全相同,norm=None
请在末尾设置并运行它dctn
:
np.moveaxis(x, range(x.ndim), (-1, range(x.ndim - 1)))
再举一个例子,我们可以通过Wikipedia 的计算来验证它是否与 JPEG 的 8x8 DCT-II 相同:
>>> x = np.array([
... [52, 55, 61, 66, 70, 61, 64, 73],
... [63, 59, 55, 90, 109, 85, 69, 72],
... [62, 59, 68, 113, 144, 104, 66, 73],
... [63, 58, 71, 122, 154, 106, 70, 69],
... [67, 61, 68, 104, 126, 88, 68, 70],
... [79, 65, 60, 70, 77, 68, 58, 75],
... [85, 71, 64, 59, 55, 61, 65, 83],
... [87, 79, 69, 68, 65, 76, 78, 94],
... ]) - 128
>>> np.set_printoptions(precision=2, floatmode="fixed", suppress=True)
>>> print(dctn(x))
[[-415.38 -30.19 -61.20 27.24 56.12 -20.10 -2.39 0.46]
[ 4.47 -21.86 -60.76 10.25 13.15 -7.09 -8.54 4.88]
[ -46.83 7.37 77.13 -24.56 -28.91 9.93 5.42 -5.65]
[ -48.53 12.07 34.10 -14.76 -10.24 6.30 1.83 1.95]
[ 12.12 -6.55 -13.20 -3.95 -1.88 1.75 -2.79 3.14]
[ -7.73 2.91 2.38 -5.94 -2.38 0.94 4.30 1.85]
[ -1.03 0.18 0.42 -2.42 -0.88 -3.02 4.12 -0.66]
[ -0.17 0.14 -1.07 -4.19 -1.17 -0.10 0.50 1.68]]
于 2020-05-15T06:03:59.797 回答