如何提取scipy.fft.dct用于二维的余弦变换公式?
How can I extract the cosine transform formula used for 2D by scipy.fft.dct?
对于 1D 余弦变换,文档在 here 中很清楚,我可以轻松地重现它:
公式为:
这里是手动复制的,例如三次谐波:
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()
的输出与我尝试的手动计算吗?
我猜公式不是...
但如果我可以手动为上面示例矩阵中的系数之一获得相同的输出,那么纠正起来真的很容易。
您找不到多维模式的公式,因为该函数不进行多维余弦变换。 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)
对于 1D 余弦变换,文档在 here 中很清楚,我可以轻松地重现它:
公式为:
这里是手动复制的,例如三次谐波:
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()
的输出与我尝试的手动计算吗?
我猜公式不是...
但如果我可以手动为上面示例矩阵中的系数之一获得相同的输出,那么纠正起来真的很容易。
您找不到多维模式的公式,因为该函数不进行多维余弦变换。 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)