离散余弦变换实现不同于库函数
discrete cosine transform implementation differs from library function
我实现了自己的 DCT 函数,但输出与 scipy 的 fftpack dct 函数不同。我想知道是否有人知道 fftpack.dct( ) 是否进行任何其他转换,如果是,它们是什么?
注意:我尝试从数据中减去 128,但这只会改变颜色,而不是频率位置。
import numpy as np
from numpy import empty,arange,exp,real,imag,pi
from numpy.fft import rfft,irfft
import matplotlib.pyplot as plt
from scipy import fftpack
def dct(x):
N = len(x)
x2 = empty(2*N,float)
x2[:N] = x[:]
x2[N:] = x[::-1]
X = rfft(x2)
phi = exp(-1j*pi*arange(N)/(2*N))
return real(phi*X[:N])
def dct2(x):
M = x.shape[0]
N = x.shape[1]
a = empty([M,N],float)
X = empty([M,N],float)
for i in range(M):
a[i,:] = dct(x[i,:])
for j in range(N):
X[:,j] = dct(a[:,j])
return X
if __name__ == "__main__":
data = np.array([
[0,0,0,20,0,0,0],
[0,0,20,50,20,0,0],
[0,7,50,90,50,7,0],
[0,0,20,50,20,0,0],
[0,0,0,20,0,0,0],
])
X = dct2(data)
plt.matshow(X)
X2 = fftpack.dct(data)
plt.matshow(X2)
数据:
X:
X2:
scipy.fftpack.dct
执行的是一维 dct 变换,而您执行的是二维 dct 变换。要使用 scipy 执行 2D dct,请使用:
X2 = fftpack.dct(fftpack.dct(data, axis=0), axis=1)
这应该可以解决您的问题,因为使用您的示例生成的矩阵将是:
这与您的实施相似,但有一个常数因子。可以使用 dct 的 norm
参数控制常数因子,阅读更多 here
我实现了自己的 DCT 函数,但输出与 scipy 的 fftpack dct 函数不同。我想知道是否有人知道 fftpack.dct( ) 是否进行任何其他转换,如果是,它们是什么? 注意:我尝试从数据中减去 128,但这只会改变颜色,而不是频率位置。
import numpy as np
from numpy import empty,arange,exp,real,imag,pi
from numpy.fft import rfft,irfft
import matplotlib.pyplot as plt
from scipy import fftpack
def dct(x):
N = len(x)
x2 = empty(2*N,float)
x2[:N] = x[:]
x2[N:] = x[::-1]
X = rfft(x2)
phi = exp(-1j*pi*arange(N)/(2*N))
return real(phi*X[:N])
def dct2(x):
M = x.shape[0]
N = x.shape[1]
a = empty([M,N],float)
X = empty([M,N],float)
for i in range(M):
a[i,:] = dct(x[i,:])
for j in range(N):
X[:,j] = dct(a[:,j])
return X
if __name__ == "__main__":
data = np.array([
[0,0,0,20,0,0,0],
[0,0,20,50,20,0,0],
[0,7,50,90,50,7,0],
[0,0,20,50,20,0,0],
[0,0,0,20,0,0,0],
])
X = dct2(data)
plt.matshow(X)
X2 = fftpack.dct(data)
plt.matshow(X2)
数据:
X:
X2:
scipy.fftpack.dct
执行的是一维 dct 变换,而您执行的是二维 dct 变换。要使用 scipy 执行 2D dct,请使用:
X2 = fftpack.dct(fftpack.dct(data, axis=0), axis=1)
这应该可以解决您的问题,因为使用您的示例生成的矩阵将是:
这与您的实施相似,但有一个常数因子。可以使用 dct 的 norm
参数控制常数因子,阅读更多 here