# 2D Fourier downsampling

How can one correctly downsample a Fourier 2D matrix of complex numbers ? More precisely, if I have a 2D DFT of an image:

x=phantom
X=fft2(x)


How should I do to in the frequency domain to obtain:

XHalf=fft2(imresize(x,0.5))


(And imshow(ifft2(XHalf)) shows the downsampled image of course).

Of course, doing imresize() in the frequency domain does not work.

If you do an imresize(X,0.5), after doing an ifft2(imresize(X,0.5)) the result is nonesense.

I tried simply cropping the Fourier "image": it does give something recognizable but it is clearly not simply that.

• I feel like I answered this one before, a couple of years ago... So, there are cases where the answer to "how do I do this very time-domainy thing in frequency domain?" is "well, you transform to time-domain, then do the thing, then transform back; that's the computationally easiest way". Mar 24, 2020 at 17:30
• The magnitude response of an image gives the distribution of various frequencies across image i.e high frequency representing edges. So cropping the Frequency response will get of these frequency components and wont reconstruct the image. It is better to do the downsampling in the spatial domain. Mar 25, 2020 at 9:21

For a 2D FFT (fft2), first do an "fftshift" to center the low frequency portion of the 2D FFT in the center of the matrix. Select this inner region and then do an inverse 2D FFT (ifft2) of the fftshifted result.

The format of the result also needs to be 8-bit unsigned.

The image below depicts the low frequency portion of the frequency domain of the image in green centered on the origin after using the fftshift command (my apologies to our B/G color blind users!). After executing fft2, the pixel corresponding with the lowest frequency will be in the upper left hand corner. fftshift will swap quadrant 2 and quadrant 4, and swap quadrant 1 with quadrant 3 resulting in the lowest frequency pixel to be at the origin. This simplifies the selection of the lowest frequency quartile of the image and after processing the ifft2 of the ifftshifted result will provide the half dimensioned image as desired.

The devil is in the details to properly shift and select the image properly, so see the MATLAB/ Octave code below that properly does the proper selection as well as the scaling.

d = 2;   # decimation rate
dim = size(image);
m = floor(dim/2)+1;
n = floor(m/d);
fimage = fftshift(fft2(image));
# select middle
fimageh = fimage(m(1)-n(1):m(1)+n(1),m(2)-n(2):m(2)+n(2),:);
# ifft
image2 = uint8(real(ifft2(ifftshift(fimageh/d^2))));
imshow(image2);


Note that the code includes taking the real part, but if done correctly all the imaginary terms should be insignificant. However uint8 will not operate on a complex numbers.

Test image before (800x1200):

Test image after for d=2 (401x601):

• Why fimageh is divided by d^2 ? Mar 3, 2022 at 11:29
• It's to scale the values back (normalization) from the gain difference in the fft and ifft. You can work it out from the DFT formula directly or a simple example: fft([1 1 1 1]) = [4 0 0 0]. ifft([4 0 0 0] = [1 1 1 1] but ifft([4 0])= [2 2]. So in the latter case where D=2, we had to divide by 2 to scale back. It is d^2 above since it is a 2D fft. Mar 3, 2022 at 13:49