计算圆度

4
我目前正在开发一个简单的形状检测算法,我希望能够将从图像中提取出的形状区分为不同的类型,比如三角形、正方形、圆形等。我没有问题提取所有这些区域 - 我只是在圆形检测方面遇到了问题。
我目前所得到的是,我能够提取出形状的所有轮廓坐标 (比如在这个圆形的例子中) --> 红线显示轮廓坐标(大约100个点左右)

Image

现在我想计算百分比值,以确定这些坐标与完美圆形的匹配程度有多精确。

这是我第一个计算“准确度百分比值”的想法(请参见注释)。

注意:代码是用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!");

这是我目前拥有的所有代码,说实话,我真的不知道如何继续计算百分比值。

任何帮助都将非常感激,提前致谢,TEMPI。

这里是上面图片中圆形的一些测试坐标:

[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]

注意:我真的希望能得到一些示例代码片段,这将非常有帮助。


你想将它与哪个圆进行百分比差异比较? - Barmar
我不太确定我是否正确理解了你的评论。然而,我想将该区域与一个完美的圆形进行比较(每个轮廓坐标--->轮廓中心距离相同。一个圆形!)。@Barmar - user9590073
1个回答

4
你可以使用“单迹线”或“多迹线”方法来实现这一点。
此处提供了单迹线方法的公式。 圆度(物体)- 二维计算 您还可以使用这些公式来计算圆度和轮廓度,两者都将给定形状的值作为周长和面积的函数确定。
圆度。

Roundness

循环性

Circularity

或者在代码中,类似于...
function circularity(x) {
   4 * Math.PI * area(x) / Math.sqrt(perimeter(x))
}

数值1.0表示一个完美的圆,高于或低于1的值表示物体偏离圆形(面积和周长计算留给您自己完成)。

另一个定义是ISO的圆度定义-定义为内切圆和外接圆之间的比率。即适合形状内部和外部的最大和最小圆-您可以使用类似这样的方法轻松确定圆度。

如果您搜索“计算单个轮廓圆度”或“计算圆度”,我相信您会找到很多实现和指南。

正如维基链接中所述,还有许多其他圆度误差定义方法,例如最小二乘圆、最小区域圆等-这些方法可能更适用于您的情况。

例如:

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


嘿,非常感谢您的快速回复,但是寻找“单个轨迹圆形度JavaScript...”并没有帮助太多。我已经做了很多研究,但到目前为止还没有找到任何匹配的内容,即使使用您提供的关键字也是如此。:/ 而且,根据给定的公式,我也会遇到困难,所以我不知道如何将其实现到我的代码中。 - user9590073
使用function circularity(x) { 4 * Math.PI * area(x) / Math.sqrt(perimeter(x)) }似乎对我来说不是有效的方法...即使在完美匹配圆形的情况下,其中面积和周长被100%正确确定,我得到的值也在4或甚至5左右。您确定这是正确的公式吗? - user9590073
你还在吗,@Fraser? - user9590073
维基百科对此有一个定义:https://en.wikipedia.org/wiki/Roundness#Calculation_in_two_dimensions,但是将`Math.sqrt(perimeter(x))`替换为`Math.Pow(perimeter(x), 2)`。 - Shawn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接