2

I need to do the following for an image in the matlab:

  1. Load the image.
  2. compute FFT ( Fast Fourier Transform ) of the image.
  3. shift frequency components to the center.
  4. crop the image like follow ( if the image res. is 1000x1000 , the needed part of the image is like the following Coordinates: 100,100,800,800. which is a smaller image. (The idea of applying filter to remove high frequencies).
  5. inverse shift.
  6. inverse fourier transform.

. . .

My code look like this:

I = imread('2.jpg'); %loading

ID = im2double(I);
FID = fft2(ID); %FFT
F = fftshift(FID); %shifting

F = imcrop(F,[100, 100, 800, 800]);

FID = ifftshift(F); %inverse of shifting
IFID = ifft2(FID); %inverse of FFT

I8 = im2uint8(IFID);

The problem is when i want to Crop the image, imcrop function couldn't crop an image of type "complex double" , as i think ..

Error:

Error using imcrop>checkCData (line 410) Invalid input image.

Error in imcrop>parseInputs (line 256) checkCData(a);

Error in imcrop (line 93) [x,y,a,cm,spatial_rect,h_image,placement_cancelled] = parseInputs(varargin{:});

ِAny help ? .. also are there another function for cropping?

Minions
  • 5,104
  • 5
  • 50
  • 91
  • 1
    Note that cropping the image in the frequency domain will also reduce the size of the image in the time domain. If you just want to "remove" the high frequency components but keep the same image size, then you could zero-out those pixels instead of straight out removing them. – SleuthEye Jul 31 '16 at 19:50
  • This is was my old idea , but i was unable to apply it, could you help me? – Minions Jul 31 '16 at 19:53

2 Answers2

1

The problem is indeed the complex values in the tensor F. A proof is the fact that replacing imcrop(F,[100, 100, 800, 800]) by imcrop(abs(F),[100, 100, 800, 800]).

A suggestion I have is to decompose the signal F in a magnitude and phase part and to use imcrop on those two images, followed by a reconstruction. As far as understand 'imcrop' this should yield the same result.

The code would look then like:

I = imread('PersonalPhoto.JPG'); %loading

ID = im2double(I);
FID = fft2(ID); %FFT
F = fftshift(FID); %shifting

Fabs = imcrop(abs(F),[100, 100, 800, 800]);
Fang = imcrop(angle(F),[100, 100, 800, 800]);

F = Fabs.*exp(1j.*Fang);

FID = ifftshift(F); %inverse of shifting
IFID = ifft2(FID); %inverse of FFT

I8 = im2uint8(IFID);
  • Thaaaanx , could you exp. this: F = Fabs.*exp(1j.*Fang); – Minions Jul 31 '16 at 19:40
  • What happens there is a standard representation of a complex number as a combination of its magnitude Fabs and its angle Fang. Namely a complex number can be written as `z = a + b*j = Magn*exp(Angle*j)`. The dots are required in Matlab because the operations are element-wise and not vector operations. – Christof Vermeersch Jul 31 '16 at 20:01
1

Cropping a real-valued decomposition of the image (either the magnitude and phase, or the real and imaginary part) would avoid the reported error from imcrop.

However, since you indicated that your intention is to filter high frequency components, you should note that cropping will also have the side effect of reducing the resulting time-domain image.

To preserve the image size, you may consider zeroing out those frequency bins instead (short of a using a more elaborate filter design). You can achieve this by multiplying the frequency domain data with a matrix acting as a mask over the frequency component you want to keep.

The code to achieve this would look like:

% create a mask to zero-out high frequency components
H = zeros(size(I));
halfwidth = 400;
xmin = size(H,2)/2+1 - halfwidth;
xmax = size(H,2)/2+1 + halfwidth;
ymin = size(H,1)/2+1 - halfwidth;
ymax = size(H,1)/2+1 + halfwidth;
H(xmin:xmax, ymin:ymax, :) = 1;

% apply mask
F = F.*H;

Which would give you the following overall code:

I = imread('2.jpg'); %loading

ID = im2double(I);
FID = fft2(ID); %FFT
F = fftshift(FID); %shifting

% create a mask to zero-out high frequency components
H = zeros(size(I));
halfwidth = 400;
xmin = size(H,2)/2+1 - halfwidth;
xmax = size(H,2)/2+1 + halfwidth;
ymin = size(H,1)/2+1 - halfwidth;
ymax = size(H,1)/2+1 + halfwidth;
H(xmin:xmax, ymin:ymax, :) = 1;

% apply mask
F = F.*H;

FID = ifftshift(F); %inverse of shifting
IFID = real(ifft2(FID)); %inverse of FFT

I8 = im2uint8(IFID);
SleuthEye
  • 14,379
  • 2
  • 32
  • 61
  • what you meant by: H(100:800, 100:800) = 1? , also, the image was a combination of shapes with a different color for each, drawn on white background .. after applying your code the image become blue ! is this what should be ? – Minions Jul 31 '16 at 20:11
  • The index `100:800` assigns to a slice of `H`. I have just added a third dimension for the colors. – SleuthEye Jul 31 '16 at 20:28
  • oops had copied the `real` part at the wrong place. latest edit should fix that. Also since that sample is an 800x800 image (instead of 1000x1000) you will have to adjust `halfwidth` – SleuthEye Jul 31 '16 at 20:43
  • Also, this should be edited: ymax = size(H,1)/2+1 - halfwidth; to ymax = size(H,1)/2+1 + halfwidth; – Minions Jul 31 '16 at 20:47