# What are the cosine functions in JPEG's DCTII 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 DCTII. There are lots of visualizations of these waves, such as this one from the Wikipedia article on JPEG compression:

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

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

• Any more needed? – Laurent Duval Dec 8 '19 at 15:09

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 – Laurent Duval Jun 1 '19 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. – JeffThompson Jun 6 '19 at 14:35
• So, OK, let's do it – Laurent Duval Jun 6 '19 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 – Laurent Duval Jun 7 '19 at 15:08
• Code is much easier to understand for me than a formula :) – JeffThompson Jun 7 '19 at 15:17