 Image Resize in MATLAB by Cropping DFT - ClubTread Community

Old 02-15-2010, 07:12 PM Thread Starter
High on the Mountain Top

Join Date: Aug 2002
Interest: Too many to list.
Posts: 1,094 Image Resize in MATLAB by Cropping DFT

I'm just putting this out there with the hope that it might be useful to somebody. I know there are at least some people on here with the background to understand how this works, and how to use it. As far as I know this represents the most detail preserving way to downsample an image. It removes all high frequencies as required to prevent aliasing, without removing any low frequencies containing detail.

It works by cropping and windowing the discrete Fourier transform (DFT) of the image, and then taking the inverse DFT to recover the resized image.

I did a few Google searches, and couldn't find many other references to this technique, and this code is (at least in my opinion) superior in clarity and accuracy to the references I could find.
• At present it can only reduce the size of the image. Increasing the size would involve stuffing a bunch of zeros into the DFT.
• A bit of a memory hog, it takes 8 bytes per pixel to store the DFT.
• Computing the DFT and its inverse are somewhat CPU intensive. If any dimensions of the source image or output image end up being prime numbers, you could in theory be waiting a while.

Code:
```function [ output_image ] = image_scale2( source_image, scale_percent )
%Compute the DFT of the source image.
fft_source_image = fft2( source_image );

%Get the dimensions, don't need dummy variable, just a place holder
[ height, width, dummy ] = size( fft_source_image );

%Calclate the parameters for cropping the Fourier transform.
x_trunc_size = int16(width * scale_percent / 200 - 1);
y_trunc_size = int16(height * scale_percent / 200 - 1);

%Perform the actual cropping of the DFT. Cropping the DFT will reduce the
%size of the DFT, so when the inverse DFT is taken the resulting image will
%be smaller.
fft_source_image( (2+y_trunc_size):(height - y_trunc_size - 1), :, : ) = [];
fft_source_image( :,(2+x_trunc_size):(width - x_trunc_size - 1), : ) = [];

[ new_height, new_width, dummy ] = size( fft_source_image );

%Scale amplitude of the DFT to preserve the intensity of the image. See
%MATLAB help for fft(X) and ifft(X) to unstand why this is necessary.
fft_source_image = fft_source_image * new_height * new_width / (height * width);

%Create a triangle function peaking at the midpoint.
y_range = min( transpose([ transpose(0:(new_height-1)) transpose((new_height):-1:1)]) );
x_range = min( transpose([ transpose(0:(new_width-1)) transpose((new_width):-1:1)]) );
%Normalize the spatial frequencies to 1.
y_range = 2 * y_range / (new_height - 1);
x_range = 2 * x_range / (new_width - 1);
[ y_range, x_range ] = meshgrid( x_range, y_range );
%Mask will be a two dimension array in which each element corresponds to
%the spatial frequency of the element of the same index in the DFT.
%Now set the mask to eliminate all higher frequencies:
%mask(i,j) = 1 for frequencies that are less than 1
%mask(i,j) - 0 for frequencies that are greater than 1

%Apply the mask. Three applications are needed, once for each colour
%channel. There may be a more compact way to express the following three
%lines as one.

%Take the inverse DFT to get the image back
output_image = uint8(real(ifft2(fft_source_image)));
end```
Matt is offline

Old 02-15-2010, 07:14 PM
Off the Beaten Path

Join Date: Jun 2005
Location: , , .
Posts: 705 thanks for the great report . Really enjoyed it!
mrultralite is offline