Skip to content
Advertisement

Create random shape/contour using matplotlib

I am trying to generate an image of a random contour using python but I couldn’t find an easy way to do it.

Here is an example sort of what I want:

enter image description here

Initially I tought of doing it using matplotlib and gaussian functions, but I could not even get close to the image I showed.

Is there a simple way to do it?

I appreciate any help

Advertisement

Answer

matplotlib Path

A simple way to achieve random and quite smoothed shapes is using matplotlib.path module.

Using a cubic Bézier curve, most of the lines will be smoothed, and the number of sharp edges will be one of the parameters to tune.

The steps would be the following. First the parameters of the shape are defined, these are the number of sharp edges n and the maximum perturbation with respect to the default position in the unit circle r. In this example, the points are moved from the unit circle with a radial correction, which modifies the radius from 1 to a random number between 1-r,1+r.

That is why the vertices are defined as sinus or cosinus of the corresponding angle times the radius factor, to place the dots in the circle and then modify their radius in order to introduce the random component. The stack, .T to transpose and [:,None] are merely to convert the arrays to the input accepted by matplotlib.

Below there is an example using this kind of radial correction:

JavaScript

Which for n=8 and r=0.7 produces shapes like these:

shapes


Gaussian filtered matplotlib Path

There is also the option of generating the shape with the code above for a single shape, and then use scipy to performe a gaussian filtering of the generated image.

The main idea behind performing a gaussian filter and retrieving the smoothed shape is to create a filled shape; save the image as a 2d array (whose values will be between 0 and 1 as it will be a greyscale image); then apply the gaussian filter; and eventually, get the smoothed shape as the 0.5 contour of the filtered array.

Therefore, this second version would look like:

JavaScript

smooth shape

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement