微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何通过 scipy.fft.dct 提取用于 2D 的余弦变换公式?

如何解决如何通过 scipy.fft.dct 提取用于 2D 的余弦变换公式?

对于一维余弦变换,here 中的文档很清楚,我可以轻松重现:

公式为:

screenshot from scipy.fft.dct documentation detailing Type II DCT

这里是手动复制的,例如三次谐波:

import numpy as np
from scipy.fft import fft,dct

y = np.array([10,3,5])

# dct() call:
print(dct(y,2))

# manual reproduction for k = 2:
N = 3
k = 2
n = np.array([0,1,2])
2 * (
    y[0] * np.cos((np.pi*k*(2*n[0]+1))/(2*N)) + 
    y[1] * np.cos((np.pi*k*(2*n[1]+1))/(2*N)) + 
    y[2] * np.cos((np.pi*k*(2*n[2]+1))/(2*N)))

在这两种情况下我都得到 9。

但是没有关于 2D DCT 的文档,我尝试用玩具矩阵破解公式的尝试没有奏效:

比较:

z = np.array([[ 2,3       ],[ 10,15]])
dct(z,axis=0)  # dct() call

例如:

N = 2
M = 2
k = 0
l = 0
n = np.array([0,1])
m = np.array([0,1])
M*N * (
    z[0,0] * np.cos((np.pi*k*(2*n[0]+1))/(2*N)) * np.cos((np.pi*l*(2*m[0]+1))/(2*M)) + 
    z[0,1] * np.cos((np.pi*k*(2*n[0]+1))/(2*N)) * np.cos((np.pi*l*(2*m[1]+1))/(2*M)) +
    z[1,0] * np.cos((np.pi*k*(2*n[1]+1))/(2*N)) * np.cos((np.pi*l*(2*m[0]+1))/(2*M)) +
    z[1,1] * np.cos((np.pi*k*(2*n[1]+1))/(2*N)) * np.cos((np.pi*l*(2*m[1]+1))/(2*M))
)

对于第一个系数。

谁能帮我将 dct()输出与我尝试的手动计算相协调?

我猜这个公式不是...

screenshot of a generalized 2d DCT formula,crossed out with a red line

但是,如果我可以为上面示例矩阵中的一个系数手动获得相同的输出,那么纠正起来真的很容易。

解决方法

您找不到多维模式的公式,因为该函数不进行多维余弦变换。 axis 关键字应该是可疑的:在 NumPy 和 SciPy 中,它通常决定执行低维操作的方向。

换句话说,dct(z,axis=0) 只是一列一维余弦变换:

import numpy as np
from scipy.fft import dct

z = np.array([[ 2,3],[ 10,15]])
print(dct(z,axis=0))  # dct() call
print(np.array([dct(column) for column in z.T]).T)
# both outputs
# [[ 24.          36.        ]
#  [-11.3137085  -16.97056275]]

注意最后一行的两个转置:它所做的只是首先遍历数组以根据列对其进行切片,然后再次按列连接它们。后者可能更好地说明为

res = np.stack([dct(column) for column in z.T],axis=1)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。