Calculating Roundness

I'm currently developing a simple shape detection algorithm where I'd like to distinguish extracted shapes from an image into different types, like triangle, square, circle, ....

I got no problems extracting all of these areas - I just got problems with the Circle detection.


What I've got so far is, I'm able to extract all of the contour coordinates of a shape (like in this case of a circle) -->red line displays the contour coordinates (maybe about 100points):

Image

Now I'd like to calculate the percentage value how accurate this coordinates are matching to a perfect circle.

This was my first idea of calculating the "accuracy percentage value" (see the comments).

Note: Code is written in javaScript.

let areaCoordinates = [[142, 267], [141, 268], [136, 268], [135, 269], [133, 269], [132, 270], [131, 270], [129, 272], [128, 272], [126, 274], [125, 274], [125, 275], [120, 280], [120, 281], [119, 282], [119, 284], [117, 286], [117, 289], [116, 290], [116, 300], [117, 301], [117, 304], [118, 305], [118, 307], [119, 308], [119, 309], [122, 312], [122, 313], [124, 315], [124, 316], [125, 316], [128, 319], [129, 319], [130, 320], [131, 320], [132, 321], [133, 321], [134, 322], [135, 322], [136, 323], [139, 323], [140, 324], [148, 324], [149, 323], [154, 323], [155, 322], [157, 322], [158, 321], [159, 321], [162, 318], [163, 318], [168, 313], [168, 312], [171, 309], [171, 307], [172, 306], [172, 304], [173, 303], [173, 302], [174, 301], [174, 292], [173, 291], [173, 287], [172, 286], [172, 285], [170, 283], [170, 282], [169, 281], [169, 279], [164, 274], [163, 274], [160, 271], [159, 271], [158, 270], [157, 270], [156, 269], [155, 269], [154, 268], [150, 268], [149, 267]]


function calculateCircleAccuracy(areaCoordinates) {
   var percentageValue = 0;
   
   // calculate areas center
   var centerX = 0, centerY = 0;
   for (var i=0; i<areaCoordinates.length; i++) {
      centerX+=areaCoordinates[i][0];
      centerY+=areaCoordinates[i][1];
   }
   centerX/=areaCoordinates.length;
   centerY/=areaCoordinates.length;
   
   // calculate radius for every contour point
   var centerDistances = [];   
   for (var i=0; i<areaCoordinates.length; i++) {
      let dx = centerX - areaCoordinates[i][0],
          dy = centerY - areaCoordinates[i][1];
      let centerDistance = Math.sqrt( dx*dx + dy*dy );
      centerDistances.push(centerDistance)
   }
   
   // calculate percentage value using [centerDistances]?!
   // got no idea how to go on!   
   
   return percentageValue;
}


console.log("Area is to " + calculateCircleAccuracy(areaCoordinates) + "% a perfect circle!");

This code is all that I've got so far and tbh I got really NO idea how to go on to calculate the percentage value.

Any help would be very appreciated, thanks a million in advance, TEMPI.

Here are some test coordinates of the circle in the image above:

[142, 267], [141, 268], [136, 268], [135, 269], [133, 269], [132, 270], [131, 270], [129, 272], [128, 272], [126, 274], [125, 274], [125, 275], [120, 280], [120, 281], [119, 282], [119, 284], [117, 286], [117, 289], [116, 290], [116, 300], [117, 301], [117, 304], [118, 305], [118, 307], [119, 308], [119, 309], [122, 312], [122, 313], [124, 315], [124, 316], [125, 316], [128, 319], [129, 319], [130, 320], [131, 320], [132, 321], [133, 321], [134, 322], [135, 322], [136, 323], [139, 323], [140, 324], [148, 324], [149, 323], [154, 323], [155, 322], [157, 322], [158, 321], [159, 321], [162, 318], [163, 318], [168, 313], [168, 312], [171, 309], [171, 307], [172, 306], [172, 304], [173, 303], [173, 302], [174, 301], [174, 292], [173, 291], [173, 287], [172, 286], [172, 285], [170, 283], [170, 282], [169, 281], [169, 279], [164, 274], [163, 274], [160, 271], [159, 271], [158, 270], [157, 270], [156, 269], [155, 269], [154, 268], [150, 268], [149, 267]

Note: I would really prefer to get some example code snippets, this would be really helpful.

Answers:

Answer

You can use either the "single trace" or "multi trace" method to achieve this.

A formula for the single trace method is given here

Roundness (object) - Calculation in two dimensions

You can also use these formulae for circularity and roundness, both of which determine the value as a function of the perimeter and area of a given shape.

Roundness

Roundness

Circularity

Circularity

Or in code, something like...

function circularity(x) {
   4 * Math.PI * area(x) / Math.sqrt(perimeter(x))
}

Where a value of 1.0 indicates a perfect circle and values higher or lower than 1 represent objects deviating from circular (the area and perimeter calculations are left for you).

Another definition is the ISO definition of roundness - defined as the ratio between an inscribed and circumscribed circle. i.e. The maximum and minimum circles that fit inside and outside the shape - you can use a method like this to determine roundness quite easily.

If you search for either "calculating single trace roundness" or "calculating roundness" I am sure you will find plenty of implementations and guides.

As noted in the wiki link there are quite a number of other methods for Roundness error definition e.g. Least square circle, Minimum Zone circle, etc - which could be more applicable in your case.

For example:

https://github.com/Meakk/circle-fit

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.