Reputation: 281
I have a 360x360 image I want to remove lines in it
the portion on it has periodic noisy lines I am working on MATLAB I tried median filter, but not working how to denoise this image and remove lines?
I tried this
%image 360x360
[rows, columns, numberOfColorChannels] = size(image);
subplot(2, 2, 1);
imshow(image,[]);
horizontalProfile = mean(image);
subplot(2, 2, [2, 4]);
plot(horizontalProfile, 'b-');
grid on;
bottomEnvelope = movmin(horizontalProfile, 10);
upperEnvelope = movmax(horizontalProfile, 10);
deltaGL = mean(upperEnvelope- bottomEnvelope)
hold on;
plot(bottomEnvelope, 'r-', 'LineWidth', 2);
plot(upperEnvelope, 'r-', 'LineWidth', 2);
% Compute midline
midline = (bottomEnvelope + upperEnvelope) / 2;
plot(midline, 'm-', 'LineWidth', 2);
columnsToDim = horizontalProfile > midline;
image(:, columnsToDim) = image(:, columnsToDim) - deltaGL;
subplot(2, 2, 3);
imshow(image, []);
But that did not work better
I've uploaded the image data to Google Drive
Upvotes: 2
Views: 1228
Reputation: 1777
This is a perfect use case for the Fast Fourier Transform (FFT).
FFT converts an image in the spatial domain to its frequency domain. The frequency domain can be used to smoothen particular noises (vertical lines in your case) in the spatial domain by removing the corresponding high frequency signals. There are tons of sources you can inform yourself about it, so I leave this part to you.
Here is my approach.*
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('coin.png',0)
# get the frequency domain
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
# smoothen the vertical lines in the spatial domain =
# remove the high frequency signals (i.e. horizontal lines) in the frequency domain
rows, cols = img.shape
crow,ccol = rows//2 , cols//2
fshift[crow-5:crow+6, 0:ccol-10] = 0
fshift[crow-5:crow+6, ccol+11:] = 0
magnitude_spectrum_no_vertical = 20*np.log(np.abs(fshift))
# get the spatial domain back
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
img_back = np.real(img_back)
This is the output image only.
Feel free to play around with different approaches: Applying a gaussian filter before FFT to improve the outcome, masking background and so on.
*: Sorry I have no MATLAB. It should be easy to port my Python script to MATLAB, though.
Upvotes: 4