Search code examples
pythonarraysmatlabopencvoctave

Convert Contours into Set of Points


I have a contour of a shape(flower boundary) that i got using contour function in Octave (have attached it below).

I want to convert it into set of points that represents the shape and fit a function such to unwrap the shape, to a linear function of the angle in the polar form. I'm trying it in MATLAB but answer in python will also work.

Main concern is how to convert that contour into set of points.

Have attached the contour image below,

Contour image

Please help me out!


Solution

  • Your question is very vague, so I'm making a lot of assumptions here, but this is what I understood from your question:

    1. You have a "plot window", showing a contour plot.
    2. As far as you're concerned, you have no control over this process, you have no idea how the contour plot was produced, from what data, there's no way to call something else instead of the contour plot that gives you the data.
    3. You just want to extract the desired contour's points directly from the graphical object.

    Here's an example of how to do that. I don't have your plot, so I'll use the built-in "peaks" function to generate the contour.

    % Generate a surface plot
      peaks;
    
    % Grab the 'peaks' graphical object, which here is the only 'child' object of the main 'axes' object
      PeaksObj = get( gca, 'children' );
    
    % Grab the X, Y, and Z data that was used to generate this surface plot
      X = get( PeaksObj, 'xdata' );
      Y = get( PeaksObj, 'ydata' );
      Z = get( PeaksObj, 'zdata' );
    
    % Generate our example contour plot
      contour( X, Y, Z );
    

    Great, now we have a contour plot to work with. Let's assume we have no idea how this was generated.

    In octave, a 'contour plot' is actually a group of individual line plots. First we need to get the 'group object' from the current axes object:

    % Grab the contour 'group' object from the current axes object
      ContourGrp = get( gca, 'children' );
    
    % The contour 'group' object should have children, which are individual contours.
      Contours = get( ContourGrp, 'children' );
    

    At this point, you have an array of individual line plots, corresponding to individual contours. You need to identify which of those contours is the one you're interested in. One way to do this interactively, is to 'fill and unfill' each contour, one-by-one, and find the one you're interested in. E.g., do this for each element of that "Contours" array (i.e. if there are 'k' elements, change k to take values from 1 to however many elements there are):

    % Experiment to find the contour of interest
      k = 1
      set( Contours(k), 'facecolor', 'r'    );
      set( Contours(k), 'facecolor', 'none' );
    

    Let's say the contour you wanted was k = 5. Now we can grab the X and Y data that makes up that contour line:

    % Get the X and Y data from the right contour
      X = get( Contours(k), 'xdata' );
      Y = get( Contours(k), 'ydata' );
    
    % Plot X against Y to confirm
      plot( X, Y );
    

    Congrats. Now you have the X Y points, from which you can calculate a centre of mass and derive radii and angles to pass into a polar plot.