问题
I am performing the 2D FFT on a particular image and I get its spectral components. Now this image has been superimposed with another image to create periodic noise.
The original image as well as the periodic noise version is shown below:
Original Image
Periodic Noise Image
To filter this out, I used manual boxes that masked the components in the magnitude spectrum that are quite large relative to the other components as shown below.
After this is done, I perform an inverse FFT, but I do not get the original image back.
Does anyone know what I'm doing wrong?
Here is the code that masks the values and then proceeds to do an inverse 2D FFT on the masked spectral image:
pat1 = imread('Pattern1.png');
spec_orig = fft2(double(pat1));
spec_orig2 = abs(spec_orig);
spec_img = fftshift(spec_orig2);
for j = 115:125
for n = 96:106
spec_img(n,j) = 0;
end
for n = 216:226
spec_img(n,j) = 0;
end
for n = 274:284
spec_img(n,j) = 0;
end
for n = 298:308
spec_img(n,j) = 0;
end
for n = 12:22
spec_img(n,j) = 0;
end
for n = 37:47
spec_img(n,j) = 0;
end
end
%Getting Back the Image for Pattern1
figure;subplot(2,1,1);
spec_img = log(1 + spec_img);
imshow(spec_img,[]);
subplot(2,1,2);
ptnfx = ifft2(spec_img);
imshow(ptnfx);
回答1:
Filtering in the frequency domain is a tricky business to get right. Your code has a few errors that are preventing you from reconstructing the original image:
You are applying the filtering on the magnitude component only. You have to do this on the original image spectrum, not just the magnitude component. The phase is essential for proper reconstruction. BTW, to coin a signal processing term, what you are implementing is a notch filter or a band-stop filter, which removes certain select frequencies.
You centered the spectrum via
fftshift
but after you filtered you forgot to undo the shift. You must invokeifftshift
on your resulting filtered image to undo the centering.You're finding the inverse FFT of the log-transformed image. Remember that performing a log transform of the spectrum is only for display purposes. You do not use this when filtering or finding the inverse. Doing this will give you unintended consequences as the majority of the spectrum has been changed due to a non-linear operation. You have to do it on the original image spectrum itself.
A minor note, but make sure you call
real
after you filter the result after you take the inverse FFT. There are most likely some residual imaginary components that are due to computational floating-point errors and so callingreal
will only extract the real components of the signal.
With these corrections, this is the code I have. I've read your image directly from StackOverflow to be reproducible:
pat1 = imread('http://i.stack.imgur.com/oIumJ.png');
%// Change
spec_orig = fft2(double(pat1));
spec_img = fftshift(spec_orig);
for j = 115:125
for n = 96:106
spec_img(n,j) = 0;
end
for n = 216:226
spec_img(n,j) = 0;
end
for n = 274:284
spec_img(n,j) = 0;
end
for n = 298:308
spec_img(n,j) = 0;
end
for n = 12:22
spec_img(n,j) = 0;
end
for n = 37:47
spec_img(n,j) = 0;
end
end
%// Change
ptnfx = real(ifft2(ifftshift(spec_img)));
imshow(ptnfx,[]);
I get this image:
A pretty good reconstruction of the original image I'll add. You'll still see a bit of streaking and that is highly dependent on the notch filter shape and size. Perhaps make the size bigger and even more so, make the shape of the notch filter circular instead of square. This has a tendency to preserve more of the original image as hard edges introduced by the corners of the squares have unintended ringing effects.
来源:https://stackoverflow.com/questions/34027840/removing-periodic-noise-from-an-image-using-the-fourier-transform