离散余弦变换实现不同于库函数

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