DMelt:DataAnalysis/7 Fitting Shapes

From HandWiki
Member

Fitting data with shapes

DataMelt offers classes to fit 2D data using shapes. Typically, shapes can be specified using equations (for example, parametric). In this section we will show how to fit data using ellipses and circles.

Fitting data with circles

Let us perform a least-squires minimisation of points with the goal to determine a circle that best fits the collection of points. The fit determines the circle position and radius. In addition, it calculates how well points distributed around the circle. In this approach we use parametric equations.

Here is a visual example:

DMelt example: Fit 2D random circle. Object identification

This plot was made using the following script:

# Fit data in the form of random circle 

from java.awt import *
from jhplot import *
from jhplot.shapes  import *
from java.util import Random
from math import *
from jhpro.fit import *

c1 =HPlot("Canvas",500,500)
c1.setAntiAlias(1)
c1.setLegend(0)
c1.setRange(-10.0,10.0,-10,10.0)
c1.visible(1)

p1=P1D("Random ellipse")
rand = Random()
# a, b are the radius on the x and y axes respectively
a=5  # semi-major axis 
b=5  # semi-minor exis
xshift=0 # (X,Y) position
yshift=-1
theta=3.14/1 # rotation
step=0.04
ra=[v*step for v in range(0,int(6.28/step))]
for t in ra:    # fill random ellipse.
   x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift
   y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift
   p1.add(x+0.4*rand.nextGaussian(), y+0.3*rand.nextGaussian())
efit= FitCircle2D(p1) # initialize fitter
print "Average distance=", efit.getDistance()
ele1= efit.getCircle()
ele1.setFill(0)
ele1.setColor(Color.red)
ele1.setTransparency(0.6)
c1.add(ele1)

# now show all objects
c1.draw(p1)
# export to some image (png,eps,pdf,jpeg...)
# c1.export(Editor.DocMasterName()+".png");

You can access the fit quality as described by the jhpro.fit.FitCircle2D jhpro.fit.FitCircle2D class.

Fitting data with ellipses

This approach also uses the algorithm of Fitzgibbon et al and by Halir et al, to find the ellipse which best approximates a collection of points.

As before, let's try to fit random points distributed around a theoretical ellipses, and the let us find this ellipse using input points.

DMelt example: Fitting  2D ellipse. Object recognision

# fit data in the form of random ellipse

from java.awt import *
from jhplot import *
from jhplot.shapes  import *
from java.util import Random
from math import *
from jhpro.fit import *

c1 =HPlot("Canvas",500,500)
c1.setAntiAlias(1)
c1.setLegend(0)
c1.setRange(-10.0,10.0,-10,10.0)
c1.visible(1)

p1=P1D("Random ellipse")
rand = Random()
# a, b are the radius on the x and y axes respectively
a=8  # semi-major axis 
b=3  # semi-minor axis
xshift=0 # (X,Y) position
yshift=-1
theta=3.14/1 # rotation
step=0.04
ra=[v*step for v in range(0,int(6.28/step))]
for t in ra:    # fill random ellipse.
   x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift
   y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift
   p1.add(x+0.4*rand.nextGaussian(), y+0.3*rand.nextGaussian())
efit= FitEllipse2D(p1) # initialize fitter
print "Average distance=", efit.getDistance()
ele1= efit.getEllipse()
ele1.setFill(0)
ele1.setColor(Color.red)
ele1.setTransparency(0.6)
c1.add(ele1)

# now show all objects
c1.draw(p1)
# export to some image (png,eps,pdf,jpeg...)
# c1.export(Editor.DocMasterName()+".png");

Look at the API of the jhpro.fit.FitEllipse2D jhpro.fit.FitEllipse2D class.

The above code also computes the quality of the fit. In this case, this is the average distance of points to the ellipse.