Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Eccentricity or principal:secondary axis ratio from contour

Status
Not open for further replies.

dougy83

Well-Known Member
Most Helpful Member
Hi all,

Given a contour (i.e. x-y points around the boundary of a shape), does anyone know how to calculate the eccentricity or even the ratio of eigenvalues of the covariance matrix of the points within the shape? The latter is simple to work out by filling the contour, but is there a method that only operates on the contour?

An example shape and eigenvalue-scaled eigenvectors α & β is shown in the attached image.

Thanks!
Doug
 

Attachments

  • contour.png
    contour.png
    7.8 KB · Views: 272
Last edited:
Hi,

How about curvature, would that be good enough for your application?
 
I don't really know what curvature is, but I don't believe it's what I'm after. I'm after a metric that describes the eccentricity of a shape.

I attempted to utilise the moments in (https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.29.8765&rep=rep1&type=pdf) as I can see that the centred moments in equations (7),(8),(9) are simply the covariance of the shape. I previously used the covariance matrix of the pixels in the shape to get the eigenvectors. Doing the same (but for the contour) based on the above doc gives me a completely different result - it may be due to the difference between the shape and its contour (which has been interpolated to an approximation).

The code based on that doc is here and I've probably made a mistake in it, though I wouldn't ask you to spend time reading through it.
Code:
public static void calcMoments(PointF[] contour, out double ixx, out double ixy, out double iyy)
{
    // make poly circular / wrap-around
    PointF[] contourWrapped = new PointF[contour.Length + 1];
    Array.Copy(contour, contourWrapped, contour.Length);
    contourWrapped[contour.Length] = contourWrapped.First();
    contour = contourWrapped;

    // calculate all moments
    int n = contour.Length;
    double areaSum = 0, sumMomentX = 0, sumMomentY = 0, sumMomentXY = 0, sumCentroidX = 0, sumCentroidY = 0;
    for (int i = 1; i < n; i++)
    {
        double crossProd = contour[i - 1].X * contour[i].Y - contour[i].X * contour[i - 1].Y;
        sumMomentX += (contour[i - 1].X * contour[i - 1].X + contour[i - 1].X * contour[i].X + contour[i].X * contour[i].X) * crossProd;
        sumCentroidX += (contour[i - 1].X + contour[i].X) * crossProd;
        sumMomentY += (contour[i - 1].Y * contour[i - 1].Y + contour[i - 1].Y * contour[i].Y + contour[i].Y * contour[i].Y) * crossProd;
        sumCentroidY += (contour[i - 1].Y + contour[i].Y) * crossProd;
        sumMomentXY += (2 * contour[i - 1].X * contour[i - 1].Y + contour[i - 1].X * contour[i].Y + contour[i].X * contour[i - 1].Y + 2 * contour[i].X * contour[i].Y) * crossProd;
        areaSum += crossProd;
    }

    // centre and scale moments
    double area = areaSum / 2, areaSq = area * area;
    ixx = sumMomentX / 12 / area - sumCentroidX * sumCentroidX / 36 / areaSq;
    ixy = sumMomentXY / 24 / area - sumCentroidX * sumCentroidY / 36 / areaSq;
    iyy = sumMomentY / 12 / area - sumCentroidY * sumCentroidY / 36 / areaSq;
}
 
Last edited:
There were a few errors in the code, namely multiplications instead of additions in the two sumCentroidX/Y += ... lines, and a sumCentroidX instead of sumCentroidY in the iyy = ... line. Works fine now, phew!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top