Я реализовал свою собственную функцию 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)
данные:
ИКС:
Х2:
scipy.fftpack.dct
выполняет преобразование 1D dct, тогда как вы реализовали преобразование 2d dct. Чтобы выполнить 2D dct с помощью scipy, используйте:
X2 = fftpack.dct(fftpack.dct(data, axis=0), axis=1)
Это должно решить вашу проблему, поскольку результирующая матрица на вашем примере будет:
Что похоже на вашу реализацию с постоянным коэффициентом. Постоянный коэффициент можно контролировать с помощью аргумента norm
в dct, подробнее здесь