使用SciPy的DCT函数创建2D DCT-II

12

我正在使用LabVIEW创建一个二维DCT-II,但是想要检查输出是否正确。SciPy有一个很好的DCT函数,默认为DCT-II但是是一维的。

我希望将其应用于二维数组。为了达到这个目的,必须先将DCT应用于列,再将其应用于此结果的行。

我不确定要使用哪个函数来实现这一点。我已经尝试过np.rot90,它将numpy数组逆时针旋转90度:

import numpy as np
from scipy.fftpack import dct

a = np.array([[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0],
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0]])

b = dct(np.rot90(dct(a),3))

然而,这将输出以下内容:

array([[ 1152.        ,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [ -412.30867345,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [    0.        ,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [  -43.10110726,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [    0.        ,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [  -12.85778584,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [    0.        ,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ],
       [   -3.24494866,     0.        ,     0.        ,     0.        ,
            0.        ,     0.        ,     0.        ,     0.        ]])

我认为rot90函数不是我想要做的正确操作,也许有更好的函数可以实现我的需求?

3个回答

34

@Jaime的回答很好。我要补充的是dct有一个axis参数,专门用于这个目的。首先沿着比如说轴0应用它,然后沿着结果的轴1应用:

In [30]: from scipy.fftpack import dct

In [31]: a.shape
Out[31]: (8, 8)

In [32]: t1 = dct(dct(a, axis=0), axis=1)

In [33]: t2 = dct(dct(a.T).T)

In [34]: np.abs(t1 - t2).max()
Out[34]: 0.0

方便的可视演示:https://inst.eecs.berkeley.edu/~ee123/sp16/Sections/JPEG_DCT_Demo.html - joe

17

我认为旋转不是您想要的,因为它会将行转换为列,但它也会干扰数据的顺序。请使用np.transpose代替。

要先按列,然后按行应用dct,您可以执行以下操作:

dct(dct(a.T).T)

结尾的.T等同于np.transpose。请注意,您需要在对列进行操作后撤消转置,以便再次通过行对齐返回。

我认为应用离散余弦变换的顺序,即先处理列然后是行与先处理行然后是列,没有任何区别,但您可以按以下方式获取行然后是列:

dct(dct(a).T).T

5

1
这是最好的选择。虽然明确指出 a.shape 是预期的形式,比如一个二维数组,可能是明智的。因为这个函数也可以愉快地处理其他维度,比如一维、三维等等。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接