JPEG 的 DCT-II 表中的余弦函数是什么?

信息处理 dct 图像压缩 JPEG 余弦
2022-01-26 09:18:07

正如我从这个视频中了解到的那样,在 JPEG 图像中,一个 8x8 像素块由加权余弦波组成,使用 DCT-II 计算。这些波有很多可视化,例如来自维基百科关于 JPEG 压缩的文章:

DCTII 余弦波的可视化

我想可视化图像中给定 8x8 像素块的每个波浪,并使用 DCT-II 计算的值加权。

在哪里可以找到(或如何计算)JPEG 压缩中使用的 64 个余弦函数?

1个回答

这些 2D 余弦函数与您的输入图像无关。它们只是“余弦波”,或在转换“ ”块时产生 64 个系数的 64 个基函数。给定 DCT-II 的矩阵和图像块,您将通过以下方式获得系数8×8D 8×88×8I64C

C=DIDT

[编辑] 如果您只想显示 2D DCT-II 函数,则必须为每个创建 2D 数组)一对水平/垂直整数索引,其中,其中经典的 JPEG,一个公式是(直到一个转置,可能还有一个比例因子):Dh,v(m,n)0m<M0n<N(h,v)0h<H0v<VH=MV=NM=N=8

Dh,v(m,n)=2m=0M1n=0N11M1Nηhηvcos(πh2M(2m+1))cos(πv2N(2n+1))

with ηx=12 if x=0, ηx=1 if x0. There are a lot of clever implementations, I'll provide the most straightforward. The goal is to get a picture like the following:

8x8 DCT-II bases

A pseudo-code version (from Matlab) could be (with the issue of 0-based or 1-based indices):

nRow = 8;nCol = 8;
nFreqHoriz = 8;
nFreqVerti = 8;
for iFreqH = 1:nFreqHoriz
    for iFreqV = 1:nFreqVerti
        iFreqHoriz = iFreqH-1;
        iFreqVerti = iFreqV-1;
        normFreqDC = 1/sqrt(2);
        matFreq2D = zeros(nRow,nCol);
        for iRow = 1:nRow
            for iCol = 1:nCol
                iRow0 = iRow-1;
                iCol0 = iCol-1;
                matFreq2D(iRow,iCol) = 2/(sqrt(nFreqHoriz)*sqrt(nFreqVerti))*cos(pi*iFreqHoriz*(2*iRow0+1)/(2*nRow))*cos(pi*iFreqVerti*(2*iCol0+1)/(2*nCol));
                if ~iFreqHoriz ,  matFreq2D(iRow,iCol) =  matFreq2D(iRow,iCol)*normFreqDC;end
                if ~iFreqVerti ,  matFreq2D(iRow,iCol) =  matFreq2D(iRow,iCol)*normFreqDC;end
            end
        end
        sum(matFreq2D(:).^2)
        subplot(nFreqHoriz,nFreqVerti,8*(iFreqV-1)+iFreqH)
        imagesc(matFreq2D);axis off;axis square;colormap gray
    end
end