最好的圆拟合算法

Mar*_*cin 13 geometry image-processing computer-vision

我需要一个非常精确的算法来将圆拟合到数据点集(实际上我需要确定中心).数据在图像的二值化和分割之后出现.我尝试了简单的质心和加权质心算法以及预制的OpenCv :: fitEllipse函数.我已经从OpenCV函数中获得了最好的结果,但仍然不够准确.当中心锚定在子像素区域时,结果显着受损.即使在处理模型化数据时,我获得的准确性也是不够的,这是不好的,因为最终,程序将不得不处理由相机捕获的数据.您有什么建议我应该寻找什么样的算法,或者您有任何现成的解决方案吗?我宁愿不要连接任何外部库.谢谢你的帮助. 替代文字

编辑:校准目标可以在视野的任何区域进行定位.以下是我使用OpenCV程序获得的最佳结果:

169,367 748,345  
167,557 820,788  
165,690 893,158  
164,047 965,197  
162,715 1036,729  
161,575 1108,089  
160,477 1179,552  
233,297 1015,313  
232,076 1086,965  
220,359 1229,578  
268,494 1160,275  
339,544 1162,980  
362,017 1235,669  
433,390 1238,491  
482,754 1168,299  
505,233 1241,039  
554,856 1170,664  
577,302 1243,439  
627,331 1172,795  
649,507 1245,665  
713,572 588,896  
711,995 661,853  
710,440 735,034  
708,722 808,856  
707,018 882,674  
705,377 956,169  
703,609 1029,211  
701,716 1101,950  
699,760 1174,689  
721,895 1247,620  
785,829 614,754  
784,344 687,750  
782,819 761,315  
781,292 835,225  
779,389 908,975  
777,619 982,335  
775,688 1055,275  
773,672 1128,091  
771,603 1200,724  
Run Code Online (Sandbox Code Playgroud)

编辑:数字生成的模型和中心的真实坐标: 替代文字

51,1    79,8
51,1    179,8
51,1    279,8
51,1    379,8
51,1    479,8
51,1    579,8
51,1    679,8
51,1    779,8
51,1    879,8
51,1    979,8
51,1    1079,8
51,1    1179,8
51,1    1279,8
51,1    1379,8
51,1    1479,8
151,1   79,8
151,1   179,8
151,1   279,8
151,1   379,8
151,1   479,8
151,1   579,8
151,1   679,8
151,1   779,8
151,1   879,8
151,1   979,8
151,1   1079,8
151,1   1179,8
151,1   1279,8
151,1   1379,8
151,1   1479,8
251,1   79,8
251,1   179,8
251,1   279,8
251,1   379,8
251,1   479,8
251,1   579,8
251,1   679,8
251,1   779,8
251,1   879,8
251,1   979,8
251,1   1079,8
251,1   1179,8
251,1   1279,8
251,1   1379,8
251,1   1479,8
351,1   79,8
351,1   179,8
351,1   279,8
351,1   379,8
351,1   479,8
351,1   579,8
351,1   679,8
351,1   779,8
351,1   879,8
351,1   979,8
351,1   1079,8
351,1   1179,8
351,1   1279,8
351,1   1379,8
351,1   1479,8
451,1   79,8
451,1   179,8
451,1   279,8
451,1   379,8
451,1   479,8
451,1   579,8
451,1   679,8
451,1   779,8
451,1   879,8
451,1   979,8
451,1   1079,8
451,1   1179,8
451,1   1279,8
451,1   1379,8
451,1   1479,8
551,1   79,8
551,1   179,8
551,1   279,8
551,1   379,8
551,1   479,8
551,1   579,8
551,1   679,8
551,1   779,8
551,1   879,8
551,1   979,8
551,1   1079,8
551,1   1179,8
551,1   1279,8
551,1   1379,8
551,1   1479,8
651,1   79,8
651,1   179,8
651,1   279,8
651,1   379,8
651,1   479,8
651,1   579,8
651,1   679,8
651,1   779,8
651,1   879,8
651,1   979,8
651,1   1079,8
651,1   1179,8
651,1   1279,8
651,1   1379,8
651,1   1479,8
751,1   79,8
751,1   179,8
751,1   279,8
751,1   379,8
751,1   479,8
751,1   579,8
751,1   679,8
751,1   779,8
751,1   879,8
751,1   979,8
751,1   1079,8
751,1   1179,8
751,1   1279,8
751,1   1379,8
751,1   1479,8
851,1   79,8
851,1   179,8
851,1   279,8
851,1   379,8
851,1   479,8
851,1   579,8
851,1   679,8
851,1   779,8
851,1   879,8
851,1   979,8
851,1   1079,8
851,1   1179,8
851,1   1279,8
851,1   1379,8
851,1   1479,8
951,1   79,8
951,1   179,8
951,1   279,8
951,1   379,8
951,1   479,8
951,1   579,8
951,1   679,8
951,1   779,8
951,1   879,8
951,1   979,8
951,1   1079,8
951,1   1179,8
951,1   1279,8
951,1   1379,8
951,1   1479,8
1051,1  79,8
1051,1  179,8
1051,1  279,8
1051,1  379,8
1051,1  479,8
1051,1  579,8
1051,1  679,8
1051,1  779,8
1051,1  879,8
1051,1  979,8
1051,1  1079,8
1051,1  1179,8
1051,1  1279,8
1051,1  1379,8
1051,1  1479,8
1151,1  79,8
1151,1  179,8
1151,1  279,8
1151,1  379,8
1151,1  479,8
1151,1  579,8
1151,1  679,8
1151,1  779,8
1151,1  879,8
1151,1  979,8
1151,1  1079,8
1151,1  1179,8
1151,1  1279,8
1151,1  1379,8
1151,1  1479,8
Run Code Online (Sandbox Code Playgroud)

Dr.*_*ius 20

一种使用图像变换和聚类的算法


我使用图像变换和一些统计来制作一个小算法来检测你的圈子.让我们看看它是否符合您的错误预期.
任何好的图像和统计库都可以,我使用Mathematica实现它.

运行如下:

1.导入图像并运行Bottom Hat Transform

我们开始尝试隔离圈子.使用Box Matrix内核的Bottom Hat变换有帮助.几乎所有图像库都附带已经实现的算法.

a = Import@"http://i.stack.imgur.com/hiSjj.png";   
b = BottomHatTransform[Binarize@a, BoxMatrix[30]]  
Run Code Online (Sandbox Code Playgroud)

结果是

替代文字

2.运行命中小姐变换以隔离圆圈

Hit Miss Transform擅长于找到定义明确的几何对象.它也很容易编程,几乎总是出现在图像库中.

c = Binarize@HitMissTransform[b, DiskMatrix[20]]
Run Code Online (Sandbox Code Playgroud)

结果是:

替代文字

我们的圈子已经被孤立并缩减为核心.

3.从图像中获取白色像素

这是一个依赖于实现的步骤,因此我不会对此进行评论.

ttflat = Flatten[Table[{i, j, ImageData[c][[i, j]]}, {i, 1232}, {j, 1624}], 1];  
ttfilter = Select[ttflat, #[[3]] == 1 &];  
Run Code Online (Sandbox Code Playgroud)

让我们看看剩下多少像素

Dimensions@ttfilter  
{3684, 3}   
Run Code Online (Sandbox Code Playgroud)

所以剩下3684像素,每圈几乎82.足够做一些统计.

3.使用"聚类分析"选择每个圆圈

群集分析在这里可能有点过头了,但是我已经实现了它,比使用新的程序更容易使用它:).您可以自己动手或使用统计库.

ttc = FindClusters[ttfilter, 45, Method -> {"Agglomerate", "Linkage" -> "Complete"}];
Run Code Online (Sandbox Code Playgroud)

通过找到我们的集群,让我们找到每个集群中x和y的均值.这些是圈子的中心:

means = N[Mean /@ ttc, 5]  
Run Code Online (Sandbox Code Playgroud)

结果是45个坐标的列表,如:

{{161.67, 1180.1}, {162.75, 1108.9}, 
 {164.11, 1037.6}, {165.47, 966.19} .....  
Run Code Online (Sandbox Code Playgroud)

我们差不多完成了.

我们来看看我们的结果.我们叠加了两个图像,在检测到的中心周围绘制了十字和圆圈.

替代文字

点击放大,这样您就可以了解所涉及的错误.

HTH!

编辑

我将您桌子上的结果与我的结果进行了比较.

假设圆是直线的,我使用最小二乘拟合来跟踪一条线并计算残差.

从下面的图表中可以看出,"M"y线比我们的"Y"更合适.但这是假设圆圈对齐......

替代文字

编辑2

这些是第二张图像中前45个圆的计算坐标.我有1像素的系统偏移.可能是由于我做了一些图像处理,但很容易纠正:) ...只是在X和Y上减去一个像素...

{{51.135, 79.692}, {51.135, 179.69}, {51.135, 279.69},{51.135, 379.69}, {51.135, 479.69},
 {51.135, 579.69}, {51.135, 679.69}, {51.135, 779.69},{51.135, 879.69}, {51.135, 979.69}, 
 {51.135, 1079.7}, {51.135, 1179.7}, {51.135, 1279.7},{51.135, 1379.7}, {51.135, 1479.7}, 
 {151.13, 79.692}, {151.13, 179.69}, {151.13, 279.69},{151.13, 379.69}, {151.13, 479.69},
 {151.13, 579.69}, {151.13, 679.69}, {151.13, 779.69},{151.13, 879.69}, {151.13, 979.69}, 
 {151.13, 1079.7}, {151.13, 1179.7}, {151.13, 1279.7},{151.13, 1379.7}, {151.13, 1479.7}, 
 {251.13, 79.692}, {251.13, 179.69}, {251.13, 279.69},{251.13, 379.69}, {251.13, 479.69}, 
 {251.13, 579.69}, {251.13, 679.69}, {251.13, 779.69},{251.13, 879.69}, {251.13, 979.69}, 
 {251.13, 1079.7}, {251.13, 1179.7}, {251.13, 1279.7},{251.13, 1379.7}, {251.13, 1479.7}}
Run Code Online (Sandbox Code Playgroud)

这是图像:

替代文字