Smooth a bumpy circle

  • A+

I am detecting edges of round objects and am obtaining "bumpy" irregular edges. Is there away to smooth the edges so that I have a more uniform shape?

For example, in the code below I generate a "bumpy" circle (left). Is there a smoothing or moving average kind of function I could use to obtain or approximate the "smooth" circle (right). Preferably with some sort of parameter I can control as my actual images arn't perfectly circular.

import numpy as np import matplotlib.pyplot as plt  fig, (bumpy, smooth) = plt.subplots(ncols=2, figsize=(14, 7))  an = np.linspace(0, 2 * np.pi, 100)   bumpy.plot(3 * np.cos(an) + np.random.normal(0,.03,100), 3 * np.sin(an) + np.random.normal(0,.03,100))  smooth.plot(3 * np.cos(an), 3 * np.sin(an)) 

Smooth a bumpy circle


You can do this in frequency domain. Take the (x,y) coordinates of the points of your curve and construct the signal as signal = x + yj, then take the Fourier transform of this signal. Filter out the high frequency components, then take the inverse Fourier transform and you'll get a smooth curve. You can control the smoothness by adjusting the cutoff frequency.

Here's an example:

import numpy as np from matplotlib import pyplot as plt  r = 3 theta = np.linspace(0, 2 * np.pi, 100)  noise_level = 2 # construct the signal x = r *  np.cos(theta) + noise_level * np.random.normal(0,.03,100) y = r *  np.sin(theta) + noise_level * np.random.normal(0,.03,100) signal = x + 1j*y # FFT and frequencies fft = np.fft.fft(signal) freq = np.fft.fftfreq(signal.shape[-1]) # filter cutoff = 0.1 fft[np.abs(freq) > cutoff] = 0 # IFFT signal_filt = np.fft.ifft(fft)  plt.figure() plt.subplot(121) plt.axis('equal') plt.plot(x, y, label='Noisy') plt.subplot(122) plt.axis('equal') plt.plot(signal_filt.real, signal_filt.imag, label='Smooth') 

Smooth a bumpy circle


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: