本周文件交换选择

我们最好的用户反馈

检测图像中的椭圆

布雷特本周的选择是基于一维霍夫变换的椭圆检测,通过马丁Simonovsky

内容

简介

我曾经写过几次关于在图像中检测圆圈的文章(在这里在这里,在这里).我也在上面写过画椭圆.今天,我想写的是检测椭圆

由于椭圆比直线或圆有更多的参数描述,检测椭圆比检测直线或圆更具挑战性。虽然我们有很好的功能来检测更简单的形状(houghlinesimfindcircles),我们(目前)没有检测椭圆的函数。这就是马丁的椭圆探测功能。

幸运的是,马丁恰当地为他的算法引用了源代码;他使用的是一张纸(谢杨,季启刚。“一种新的高效椭圆检测方法。”1051-4651/02 IEEE, 2002),我已经在我的桌子上放了很长一段时间了,想着有一天我会坐下来用MATLAB代码实现它。我喜欢Martin为我做的工作——这让我更加感激文件交换。

实现

在摆弄了马丁的之后ellipseDetection ()一个下午的大部分时间,我都有一些想法要分享。首先,要认识到椭圆检测是一个昂贵的内存消耗者;计算量与非零像素数量的平方成正比,N,在你的搜索图像。几乎可以肯定,您希望对“边缘图像”进行操作,而不是对感兴趣区域的简单二进制掩码进行操作,并使用函数的9个输入参数来限制搜索。在这些参数中,您可以指定要考虑的主轴长度范围和最小纵横比。您还可以指定一些参数来限制所寻求的椭圆的角度;如果你知道椭圆的方向,这将非常有用先天的.即使使用了这样的限制,一个详尽的搜索检查NxN主要轴的候选人。Martin的函数提供了一个参数,允许您在速度和准确性之间进行权衡。(“randomize”参数不是一个布尔变量,顾名思义;相反,它减少了搜索空间NxNNx随机。如果randomize为0,则搜索是穷尽的——以计算代价提高了准确性。)

试驾

所以让我们在我们创作的一个样本图像上尝试一下。我们可以从包含圆的图像开始,并将其扭曲以生成椭圆:

inputImage = imread(“coloredChips.png”);Tform = affine2d([1 0 0;0.75 10;0 0 1]);inputImage = imwarp(inputImage, tform);imshow (inputImage)标题(“测试图像”

分割

分段图片来自:

  1. 使用colorThresholder创建背景的掩码
  2. 将彩色图像分割为R、G和B分量(imsplit
  3. 分别屏蔽R、G和B平面(R(backgroundMask) = 0,……)
  4. 将蒙面平面重新合成为RGB图像(
  5. 将掩码RGB图像转换为灰度(im2gray
  6. 计算(使用精心选择的输入参数)灰度图像的边缘(边缘
  7. 筛选结果以选择所需的主轴长度和面积(imageRegionAnalyzerbwpropfilt

在短短几分钟内,我就有了一个边缘图像来检测这些椭圆:

探测椭圆

有了这个二进制边掩码,我准备搜索椭圆——首先,很天真地:

bestFits = ellipseDetection(edgeMask);

手术在(仅仅)不到一秒钟的时间内完成,但结果并不令人印象深刻:

)顺便说一下,我在打电话ellipseDetection ()在扭曲芯片的二进制掩码上没有第一次计算边缘花了20分钟以上,结果甚至更糟!)

提高结果

为了提高性能,我对输入参数进行了合理的选择,降低了计算量。首先,我用了imdistline测量长、副轴长度:

然后我用了量角器为了了解椭圆的方向:

几分钟后,我找到了自己的方法:

参数个数。minMajorAxis = 55;参数个数。maxMajorAxis = 75;参数个数。minAspectRatio = 0.4;%1 =圆;0 =直线;参数个数。旋转= 35;参数个数。rotationSpan = 10;参数个数。随机化= 0;%穷举搜索参数个数。numBest = 30;%(芯片数量= 26)
bestFits = ellipseDetection(edgeMask, params);

削下来的结果

等等……什么?bestFits包含30个检测的参数(手动计数告诉我,图像中完全包含26个椭圆),但在可视化结果时,似乎少得多。这是怎么呢

结果表明,该算法很容易多次报告同一个椭圆。(如果我拖动这些青色椭圆,下面还有其他重合的椭圆!)

尝试,我发现它非常有用overspecify我想要检测到的椭圆的数量,然后在后处理中对结果进行裁剪。考虑:

参数个数。smoothStddev = 0.5;参数个数。numBest = 1000;%(芯片数量= 26)bestFits = ellipseDetection(edgeMask, params);minCenterDistance = 10;minScore = 30;maxAspectRatio = 0.6;bestFits = pareEllipseFits(bestFits,...minCenterDistance, minScore, maxAspectRatio);

我写了pareResults允许通过最小中心距离(不允许重叠检测)、最小分数和最大长宽比进行过滤。使用这种配对方法,我可以请求更多的检测(参数。numBest = 1000)比我真正想要的,然后放弃“坏”的结果。我对它的工作方式非常满意!

关于可视化结果的说明

最后,我也写了visualizeEllipses打电话给drawellipse直接对输出ellipseDetection

笔记

为了让这篇文章短一点(我知道……太晚了!),我没有发布所有的代码。如果有人想看,我很乐意分享。只要给我发邮件到:

Char (cumsum([98 17 -11 7 -10 7 7 -4 -47 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))

此外,Exchange上还有一些其他文件旨在促进椭圆检测。如果你想在后续的文章中看到这些,请给我留下评论!

几点建议

Martin的实现使用高斯滤波fspecial.不再推荐使用这种语法;更新的imgaussfilt效率更高。还有,调用fspecial需要一个整数第二个参数(“hsize”)参数。(我添加了一个电话到圆的()在我的版本中。)最后,由于获得良好的结果需要调优许多参数,因此该函数只是乞讨为代码生成应用程序前面;这也许是另一个项目!

谢谢你,马丁……找到这个函数并弄清楚如何使用它,为我的图像处理武器库提供了一个有价值的工具。

一如既往,我欢迎你的想法和评论




由MATLAB®R2022a发布

|
  • 打印
  • 发送电子邮件

コメント

コメントを残すには,ここをクリックしてMathWorksアカウントにサインインするか新しいMathWorksアカウントを作成します。