gpt4 book ai didi

image-processing - 最佳圆拟合算法

转载 作者:行者123 更新时间:2023-12-03 23:15:34 34 4
gpt4 key购买 nike

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

编辑:
校准目标可以定位在视场的任何区域。以下是我使用 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

编辑:数值生成的模型和中心的真实坐标:
alt text
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

最佳答案

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

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

运行如下:

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

我们开始尝试隔离圆圈。 Bottom Hat Transform使用 Box Matrix 内核会有所帮助。几乎所有图像库都带有已经实现的算法。

a = Import@"http://i.stack.imgur.com/hiSjj.png";   
b = BottomHatTransform[Binarize@a, BoxMatrix[30]]

结果是

alt text

2. 运行 Hit Miss Transform 以隔离圆圈

The Hit Miss Transform擅长寻找定义明确的几何对象。它也很容易编程并且几乎总是存在于图像库中。
c = Binarize@HitMissTransform[b, DiskMatrix[20]]

结果是:

alt text

我们的圈子已经被孤立并缩小到他们的中心核心。

3. 只获取图像中的白色像素

这是一个依赖于实现的步骤,所以我不会对此发表评论。
ttflat = Flatten[Table[{i, j, ImageData[c][[i, j]]}, {i, 1232}, {j, 1624}], 1];  
ttfilter = Select[ttflat, #[[3]] == 1 &];

看看还剩多少像素
Dimensions@ttfilter  
{3684, 3}

所以还剩 3684 个像素,几乎每圈 82 个。做一些统计就够了。

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

聚类分析在这里可能有点矫枉过正,但正如我已经实现的那样,使用它比编写新的东西更容易:)。您可以自己做或使用统计库。
ttc = FindClusters[ttfilter, 45, Method -> {"Agglomerate", "Linkage" -> "Complete"}];

已经找到我们的集群,让我们找到每个集群中 x 和 y 的平均值。这些是圆的中心:
means = N[Mean /@ ttc, 5]  

结果是一个包含 45 个坐标的列表,例如:
{{161.67, 1180.1}, {162.75, 1108.9}, 
{164.11, 1037.6}, {165.47, 966.19} .....

我们快完成了。

让我们检查一下我们的结果。我们叠加了两个图像,在检测到的中心周围画了十字和圆圈。

alt text

Click to enlarge ,因此您可能会了解所涉及的错误。

哼!

编辑

我将您表中的结果与我的结果进行了比较。

假设圆是直线,我使用最小二乘法来追踪一条线并计算残差。

从下面的图表中,您可能会看到“M”y 线比“Y”线更适合。但这是假设圆圈对齐......

alt text

编辑 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}}

这是图像:

alt text

关于image-processing - 最佳圆拟合算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4387488/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com