this questions is asked fairly often. If you don't have a grasp of fft in 1d, higher dimensions may be difficult to grasph. But logically it makes a lot of sense once you see it What does frequency domain denote in case of images?
basically sharp changes (high contast noise) usually has high frequencies. and smoother gradients have low frequencies. just as a quick crash course
edit
sorry i thought the other post had code, its just code agnostic conceptual stuff. anyway ill tell you matlab (since your tag says matlab in it) and it is more familiar to me than openCV
function fft_im = createFFTIm(grayscale_im)
fft_im = fft2(grayscale_im);
figure()
subplot(2,2,1:2);imshow(grayscale_im); title('original');
%fftshift puts the 0 frequency in the middle of the plotting area, normally
%it would be split, part of it in the 4 corners of the image
%we add 1 because log(0) is -inf, which we dont want
%we scale it jsut to show the colors better
subplot(2,2,3);imagesc(log(1+abs(fftshift(fft_im)))); colormap(gray);
title('magnitude spectrum');
subplot(2,2,4);imagesc(angle(fft_im)); colormap(gray);
title('phase spectrum');
end
edit #2 i slightly modified the code
and here are two examples

notice with the chess example, there are visible peaks in the magnitude spectrum. Just like the regular fft, these peaks correspond to a sing wave of a specific frequency. Since out image is periodic there is are strong sines at the corresponding frequencies. You also notice since the image is near symmetric, the phase is also periodic.
The phase is responsible for modeling the fact that an image is not symmetric
edit #3
this decomposes the figure into individual elements. In the code I limited it to a 4x4 subblock of pixels (the upper left portion of the figure) but you can change this all the way up to the size of the image (though for any large image this would be incredibly slow)
As in my comment, I processed the image one pixel at a time, and did an FFT2 on each of those 1 pixel images. The images themselves are still the same size as the original, it just has only one pixel value populated
function fft_im = decomposedcreateFFTIm(grayscale_im)
%i only did a small 16 pixel sub block of the image, 4x4 pixels from
%the upper left corner of the image
max_rows_to_process = 4;
max_cols_to_process = 4;
[m,n] = size(grayscale_im);
%this is used to isolate pixels, for individual analysis
zer_array = zeros(m,n);
figure(1);title('magnitude')
figure(2);title('phase')
%i only did a small 16 pixel sub block of the image, 4x4 pixels from
%the upper right corner of the image
m=4;n=4;
%for all rows
for ii=1:1:max_rows_to_process
%for all columns
for jj=1:1:max_cols_to_process
curr_idx = (ii-1)*max_cols_to_process + jj;
%creates an image with only one pixel
indiv_pix_pic = zer_array;
indiv_pix_pic(ii,jj) = grayscale_im(ii,jj);
%does fft
fft_im = fft2(indiv_pix_pic);
%fftshift puts the 0 frequency in the middle of the plotting area, normally
%it would be split, part of it in the 4 corners of the image
%we add 1 because log(0) is -inf, which we dont want
%we scale it jsut to show the colors better
figure(2)
subplot(max_rows_to_process,max_cols_to_process,curr_idx);
imagesc(angle(fft_im)); colormap(gray);
figure(1)
subplot(max_rows_to_process,max_cols_to_process,curr_idx);
imagesc(log(1+abs(fftshift(fft_im)))); colormap(gray);
end
end
end
magnitude

phase
