Since I'm learning frequency domain and I'm really curios about this topic, I'm trying to solve a problem (that I have already solved it using morphology [detecting lines by their thickness]) in frequency space (I know it's possible). here it is the picture: enter image description here

I'm trying to build a notch filter to remove lines frequencies. enter image description here

I'm not sure but I think peaks on horizontal and vertical line are the noises (paper lines) and I've tried so many ways to remove them and none of them works. I'm not looking for a code and just wanna learn how it works and some tips to solve the problem. I really appreciate your kind contribution in advance.

Results after removing peaks:

Now I'm pretty sure I'm doing something wrong in detecting peaks (I've no idea what kind of peaks I'm looking for)

enter image description here enter image description here

  • $\begingroup$ yes. what is the point of inverting it? does it really matter in fft of a binary image? can you elaborate what is trough in fft and how can I find them? $\endgroup$
    – Abolfazl74
    Commented May 10, 2021 at 18:57
  • $\begingroup$ I added result of removing peaks $\endgroup$
    – Abolfazl74
    Commented May 10, 2021 at 20:05
  • 2
    $\begingroup$ What is the find_peaks call, is this a numpy thing or did you write it? Did you check what the actual prominence of the peaks are, and whether there's anything left after you remove that? $\endgroup$
    – TimWescott
    Commented May 11, 2021 at 0:34
  • $\begingroup$ are you removing all of the peaks in the grid, or only the ones along the axes? Plot the FFT afterward $\endgroup$
    – endolith
    Commented May 11, 2021 at 1:15
  • 1
    $\begingroup$ The peaks are equally spaced in both dimensions, like the lines are equally spaced in both dimensions: i.imgur.com/Kdp3p2U.png Find the distance between the peaks in each direction and then remove everything at those intervals $\endgroup$
    – endolith
    Commented May 11, 2021 at 9:51

2 Answers 2


You should start with a simpler one-dimensional case first and then work your way up to two dimensions.

If you slice one row of your graph paper:

from matplotlib import image
import matplotlib.pyplot as plt

# load image as pixel array
image = image.imread('7ocEX.jpg')

image = 255-image  # Invert

You can see it's an (intermittent) impulse train:

Impulse train slice

The first is at pixel 23.5 and the last is at pixel 672, so you know the period of the train is (672-23.5)/11 = 58.9545 pixels/cycle, and so the frequency is:

700 pixels/image / 58.9545 pixels/cycle = 11.8736 cycles/image

If you plot the Fourier transform:

F = fft.rfft(image[42])

you see peaks at harmonics of 11.9 pixels, as expected:

Fourier transform peaks

If you then remove those peaks from the spectrum and inverse transform, the impulse train will be removed, too. You know their frequency, and you know that harmonics are integer multiples of the fundamental, so you can eliminate them from the spectrum without any peak finding.

  • $\begingroup$ I really appreciate it sir. I've no idea which one is the best answer... both of them are awesome $\endgroup$
    – Abolfazl74
    Commented May 12, 2021 at 20:47

Even though the lines are periodic, but they are closer to a train of impulses than a harmonic, so they will leak to many harmonics.

The best feature to distinguish the lines from the rest is that the lines are either horizontal or vertical, vertical lines are represented at the horizontal borders of the FFT, horizontal lines are represented at the vertical borders of the FFT.

Here is the result if you filter out (set to zero) the first four and the last three lines and column of the FFT.


Answering a comment

Here you can see the frequency domain log(fftshift(abs(fft2(image)))), before and after filtering.

enter image description here


Just because maybe you would be interested, you can apply morphological filters and get a result like this :D

morphological filtering


Yesterday the the author said this enter image description here

He accepted the answer, but after unaccepted enter image description here

  • $\begingroup$ Thank you sir. I finally found main problem of my algorithm couple of hours ago but still there a problem. I built a notch filter and made a mask with filtered frequencies. multiplying mask (same size with fft) with image's fft suppose to remove(make zero) all paper lines but its giving me this i.imgur.com/bUzZb94.png. (I'm quite sure there is trick that I don't know is this type of filtering). one more thing, you said "the first four and the last three lines" did you find them without shifting fft?if not thats a new way an I would be glad to hear more explanation about it. $\endgroup$
    – Abolfazl74
    Commented May 12, 2021 at 19:42
  • $\begingroup$ Your explanation is pretty good. please add your fft plot (peak spots) to mark it as the answer of my question. $\endgroup$
    – Abolfazl74
    Commented May 12, 2021 at 19:47
  • 1
    $\begingroup$ Added all the code the code $\endgroup$
    – Bob
    Commented May 12, 2021 at 19:55
  • 1
    $\begingroup$ So in summary, I am not searching for peaks, I am relying on the assumption that the lines are vertical/horizontal and based on that I already know where their energy will be concentrated in the frequency domain. I am not using fftshift as well. $\endgroup$
    – Bob
    Commented May 12, 2021 at 20:21
  • 2
    $\begingroup$ I've no idea why you took that personally but I still think your answer is very helpful and your explanation really help people like me to understand the issue and I appreciate it. the second answer (that was submitted after your answer) mathematically explain the problem and it tell me a lot of stuff about the problem and I think when somebody like me is trying to understand how frequency filtering works that mathematical example is very helpful. I'm really sorry if changing the answer bothered you sir. $\endgroup$
    – Abolfazl74
    Commented May 13, 2021 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.