使用 DCT 或 IFFT 计算逆 DCT (IDCT)

信息处理 matlab fft 频域 IFFT dct
2022-01-15 08:02:18

有没有办法通过利用 DCT、FFT 或 IFFT 算法来计算逆离散余弦变换(类型 2)?我见过使用 FFT 计算 DCT的方法,也见过使用 FFT 计算IFFT 的方法我找不到一个带有描述的简单示例。

1个回答

看看快速 DCT 算法PDF 版本)。

它同时具有使用 DFT (FFT) 的 DCT 和逆 DCT。
他们展示了如何在没有反射技巧的情况下进行 DCT 和 Inverse。

这样做的标准(效率低于上述)方法是:

numElements = 10;

vX = randn(1, numElements);

disp(vX); %<! Diusplay the input signal

vDctRef = dct(vX);

% Forward DCR using FFT
vXX     = [fliplr(vX), vX]; %<! Mirroring
vXDft   = fft(vXX);

vGrid = [0:((2 * numElements) - 1)];

vShiftGrid = exp(-1j * 2 * pi * (numElements - 0.5) * vGrid / (2 * numElements));

vXDft2 = real(vXDft ./ vShiftGrid);

vDct    = vXDft2(1:numElements) / sqrt(2 * numElements);
vDct(1) = vDct(1) / sqrt(2);

disp(vDctRef)
disp(vDct)

% Inverse DCT Using FFT
vDct(1) = vDct(1) * sqrt(2);
vDct    = vDct * sqrt(2 * numElements);

vXDft = [vDct, 0, -fliplr(vDct(2:numElements))] .* vShiftGrid;
vXX = ifft(vXDft);

vX = real(fliplr(vXX(1:numElements)));
disp(vX);

更有效方法的 IDCT 参考代码(如参考):

numElements = 10;

% Signal (DCT Coefficients)
vXDct = randn(1, numElements);

% Reference Inverse IDCT
vXRef = idct(vXDct);

% Inverse IDCT Using FFT
vGrid = [0:(numElements - 1)];

vShiftGrid      = exp((1j * pi * vGrid) / (2 * numElements));
vShiftGrid      = vShiftGrid * sqrt(2 * numElements);
vShiftGrid(1)   = vShiftGrid(1) / sqrt(2);


vTmp = vShiftGrid .* vXDct ;
vTmp = real(ifft(vTmp));

vX = zeros(1, numElements);

for ii = 0:((numElements / 2) - 1)
    vX((2 * ii) + 1) = vTmp(ii + 1) ;
    vX((2 * ii) + 2) = vTmp(numElements - ii) ;
end

disp(vXRef);
disp(vX);

MAT-INF2360 - Fourier Theory, Wavelet Analysis and Non Linear Optimization 课程的讲义提供了另一个参考
查看第 115 页的 4.2 DCT 的有效实现。

享受...

备注
上面写为 DCT 时是指 DCT Type II。