The Fourier Transform is so powerful that it allows enhancing images in the frequency domain. The convolution theorem can be used to filter and mask unwanted frequencies in the frequency domain. The following activities show the prowess of the Fourier Transform:
First I will showcase the two dots symmetrically along the x- axis and I take their Fourier Transform:
Figure 1 |
To generate the distance, I used the following code as a function of distance:
dist = 50
MAT = zeros(256,256);
MAT([128],[128 - dist, 128 +dist]) = 255,255;
Im = mat2gray(abs(fft2(MAT)));
As one can see, the frequency of the vertical lines increase as the distance between the 2 pixels increase. If I wanted horizontal lines, I would simply edit my code as follows:
dist = 50
MAT = zeros(256,256);
MAT([128 - dist, 128 + dist],[128,128]) = 255,255;
Im = mat2gray(abs(fft2(MAT)));
and get the following results:
Figure 2 |
I could make a checkerboard by changing MAT to:
MAT([128 - dist, 128 + dist],[128 + dist,128 + dist])
The next part of the activity shows an original (hand-drawn) image of two circles with a certain radius:
Figure 3 |
I take its FFT and get this:
Figure 4 |
The patterns look something from the Victorian era huh?
Now instead of circles, let's deal with squares, and see how the FFT vary in the frequency domain:
3 x 3 square (Left) and 5 x 5 square (right) |
I manually input the squares locations at the center of the image.
//Three by three Squares
N = 256
MAT2 = zeros(N,N);
MAT2([N/2 + 1,N/2 ,N/2 + 1],[N/2 - 11,N/2 - 10,N/2 - 9]) = [255,255,255;255,255,255;255,255,255];
MAT2([[N/2 + 1,N/2 ,N/2 + 1],[N/2 + 11,N/2 + 10,N/2 + 9]) = [255,255,255;255,255,255;255,255,255];
IM2 = mat2gray(abs(fft2(MAT2)));
imwrite(IM2, 'Squaredots.bmp');
imshow(IM2);
//Five by Five Squares
MAT3 = zeros(256,256);
MAT3([126,127,128,129,130],[116,117,118,119,120]) = 255*ones(5,5);
MAT3([126,127,128,129,130],[136,137,138,139,140]) = 255*ones(5,5);
IM3 = mat2gray(abs(fft2(MAT3)));
The code snippet above shows exactly how I manually input the squares. Note as one increases the size of the square, the greater the frequency of its FFT. On the next process, I will perform the FFT on ten randomly placed pixels on the image and convolve it with a square mask. The following shows the result:
Figure 6 |
As expected the results show the square mask displayed in the randomly generated area.
In the next part,
//Convolution
A = zeros(200,200);
d = zeros(200,200);
Randomat = grand(10,2,"uin",0,200); //Generates the random locations of the numbers
for i = 1:1:10
A(Randomat(i,1), Randomat(i,2) ) = 1;
end
five = rand(5,5);
d([98,99,100,101,102],[98,99,100,101,102])=five;
FTA = fft2(A);
Ftd = fft2(d);
FTAd = FTA.*Ftd;
IM4 = mat2gray(abs(fft2(FTAd)));
imwrite(IM4, 'RandConvol.bmp');
imshow(IM4);
Now we can do much more complicated filtering as in Figure 7. Here, we have a Lunar Orbiter Image with horizontal lines (left image):
Figure 7: Left image(Lunar Finding without Filter) Right image (Lunar Finding with Filter) |
Figure 7: Left image(FFT of the image without the filter) Right image (FFT of the image with the filter) |
The code snippet below shows how "elegantly," I generated the filter mask. Line 6 defines how much of the FFT image I remove with values ranging from 0 to 0.5. If I put 0.5, it removes everything, if I put 0, nothing happens. The best image is 0.49. The reason is that I apply the filter mask before the log, so the threshold is very small, as 0.48 and 0.49 are very distinct. The strength of this filter mask is that it can be applied on any image.
[1] //Lunar Landing Scanned Pictures: Line Removal
[2] Lunar = double(imread('C:\Users\Phil\Desktop\Academic Folder\Academic Folder 13-14 First Sem\AP 186\Activity 8\lun.jpg'));
[3] R = size(Lunar,1);
[4] C = size(Lunar,2);
[5] fftLunar = fftshift(fft2(Lunar));
[6] remov = 0.49;
[7] fftLunar(R/2 +1, 1:remov*C) = zeros(1,remov*C);
[8] fftLunar(R/2 +1,(1-remov)*C:C)= zeros(1,remov*C +1);
[9] fftLunar(1:remov*R,C/2 +1) = rand(remov*R,1);
[10] fftLunar((1-remov)*R:R,1+ C/2) = rand(remov*R+1,1);
[11] Im6 = mat2gray(abs(fft2(fftLunar)));
[12] imshow(Im6);
Note: Due to SPP and exams, I was unable to update the blog. The blog will continually be updated. Thank you!