# What are the cosine functions in JPEG's DCT-II table?

As I understand it from this video, in a JPEG image an 8x8-pixel block is made up of weighted cosine waves, calculated using DCT-II. There are lots of visualizations of these waves, such as this one from the Wikipedia article on JPEG compression:

I'd like to visualize each of the waves for a given 8x8-pixel block in an image, weighted with values calculated by DCT-II.

Where can I find (or how can I calculate) the 64 cosine functions used in JPEG compression?

• Any more needed? Commented Dec 8, 2019 at 15:09
• @LaurentDuval Either the OP should accept your answer, or point out what more is required for a good answer.
– Peter K.
Commented Nov 26, 2021 at 16:35

Those 2D cosine functions are independent of your input image. They are just "cosine waves", or the 64 basis functions that yield 64 coefficients when transforming "$$8\times 8$$" blocks. Given a $$D$$ $$8\times 8$$ matrix for the DCT-II, and a $$8\times 8$$ image patch $$I$$, you'll get $$64$$ coefficients $$C$$ by:

$$C=DID^T$$

[EDIT] If you want to display the 2D DCT-II functions only, you have to create 2D arrays $$D_{h,v}(m,n)$$ ($$0\le m< M$$ and $$0\le n< N$$) for each couple of horizontal/vertical integer indices $$(h,v)$$, with $$0\le h< H$$ and $$0\le v< V$$, with $$H=M$$ and $$V=N$$. Classically for JPEG, $$M=N=8$$. A formula is (up to a transposition, and possibly a scale factor):

$$D_{h,v}(m,n) = 2\sum_{m=0}^{M-1}\sum_{n=0}^{N-1} \frac{1}{\sqrt{M}}\frac{1}{\sqrt{N}}\eta_h \eta_v \cos\left(\frac{\pi h}{2M}(2m+1)\right)\cos\left(\frac{\pi v}{2N}(2n+1)\right)$$

with $$\eta_x = \frac{1}{\sqrt{2}}$$ if $$x=0$$, $$\eta_x = 1$$ if $$x\neq0$$. There are a lot of clever implementations, I'll provide the most straightforward. The goal is to get a picture like the following:

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

• Maybe the SE format is not the most evident ; k is an index for each frequency component (see dsp.stackexchange.com/a/58599/15892). You can more or less iuse the formula after "The general equation for a 2D (N by M image) DCT is defined by the following equation:" in users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node231.html Commented Jun 1, 2019 at 14:24
• PS maybe I didn't explain my question well: I just want the functions used to create the visualization above, not calculating the weights for a particular 8x8-pixel block. Commented Jun 6, 2019 at 14:35
• So, OK, let's do it Commented Jun 6, 2019 at 20:28
• Of course, I just wanted to share the code used to run the picture, and in some case, it can help to understand how to implement the formula in another language Commented Jun 7, 2019 at 15:08
• Code is much easier to understand for me than a formula :) Commented Jun 7, 2019 at 15:17