Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I connect discontinous curves in matplotlab, scipy, or etc

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?

enter image description here

like image 993
user1462442 Avatar asked Jun 17 '12 22:06

user1462442


People also ask

How do you plot a curve in Matplotlib?

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.

How do you plot a smooth spline curve in Python?

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.

How to plot a smooth curve using Gaussian kernel in Python?

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

How to generate a cubic interpolation curve using SciPy?

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.


1 Answers

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
like image 149
user1462442 Avatar answered Oct 25 '22 03:10

user1462442