I have a little issue, when I take the contour of an image, I get this figure:
As you can see I can extract the contour, but as soon as I extract the path, it will leave these strange secants that will cross the image because there are 2 discontinuous areas in on the curve. I wonder if there is a way to disconnect discontinuous lines or is it my path extracting code is wrong
import matplotlib.pyplot as plt
import numpy as np
def contourPath(img, width, height):
x = np.arange(0,width)
y = np.arange(height,0,-1)
X, Y = np.meshgrid(x,y)
plot = plt.contour(X,Y,img, [0])
pathList = plot.collections[0].get_paths()
x, y = [], []
for i in range(0, len(pathList)):
iterPath = pathList[i].iter_segments()
for point in iterPath:
pt = np.rint(point[0])
x.append(pt[0])
y.append(pt[1])
X = np.hstack(x)
Y = np.hstack(y)
return np.dstack((X,Y))[0]
Thank you for your time
for user545424 Here I guess. Matplotlib contour function is working properly since, there is two discontinuous spot on the image that caused this little event to happen.
I learn that those secant lines are cause by scypi, but it raises another issue on how the libraries interact with the contour points
Oh well, I believe it is possible to mask the problem by finding the path and interpolate it. But, I like to avoid refinding the path, since traveling salemans problem is not nice on my computer.
Do you have any suggestions?
The matplotlib.pyplot.plot () function by default produces a curve by joining two adjacent points in the data with a straight line, and hence the matplotlib.pyplot.plot () function does not produce a smooth curve for a small range of data points.
It plots a smooth spline curve by first determining the spline curve’s coefficients using the scipy.interpolate.make_interp_spline (). We use the given data points to estimate the coefficients for the spline curve, and then we use the coefficients to determine the y-values for very closely spaced x-values to make the curve appear smooth.
The scipy.ndimage.gaussian_filter1d() class will smooth the Y-values to generate a smooth curve, but the original Y-values might get changed. The sigma parameter represents the standard deviation for Gaussian kernel and we get a smoother curve upon increasing the value of sigma. Plot Smooth Curve Using the scipy.interpolate.interp1d Class
It generates a cubic interpolation curve using the scipy.interpolate.interp1d class, and then we use the curve to determine the y-values for closely spaced x-values for a smooth curve. Here also we will be using np.linspace () method which returns evenly spaced samples, calculated over a specified interval.
I guess I am answering my own question. Those strange secants are cause by scipy conecting the ends of the list. The default behaviour, I believe is the scipy will connect 2 sequential points regardless of location. The vertices are working properly, because it did strictly took the contour of this image and it has surrounded the curve. The reason why the secant is connected to the middle of the top semi-circle. That is the location where the last path ends.
I guess converting to polar and refinding the path is simple but not exactly optimial, but oh well.
I wonder if someone else have a better solution
def cart2polar(x,y, origin=None, size=np.array([200,200])):
ny, nx= size[0], size[1]
print size.shape
if origin is None:
origin_x, origin_y = nx//2, ny//2
else:
origin_x, origin_y = origin[0], origin[1]
x -= origin_x
y -= origin_y
r = np.sqrt(x**2 + y**2)
theta = np.arctan2(y, x)
return r, theta
def main():
index = np.argsort(theta)
r, theta = r[index[:]], theta[index[:]]
f = interpolate.interp1d(theta,r)
theta = np.linspace(round(theta.min()+.00005,),theta.max(), 200)
r = f(theta)
x,y = polar2cart(r, theta)
def polar2cart(r, theta, origin=None, size=np.array([200,200]) ):
ny, nx= size[0], size[1]
if origin is None:
origin_x, origin_y = nx//2, ny//2
else:
origin_x, origin_y = origin[0], origin[1]
x += origin_x
y += origin_y
return x, y
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With