我正在做一个项目,拍摄粉末衍射图像,并试图找到图像中的所有椭圆环。
我使用的是RANSAC算法,它将椭圆拟合到数据中,然后减去这些点(内嵌点),然后继续拟合另一个椭圆,直到内嵌比变得足够小。
我的问题是,根据我如何设置阈值距离,它要么适合的椭圆比应该有的多,要么不够。
我想知道有没有改进RANSAC更准确,或者有没有更好的算法,我应该使用?
我对你正在处理的过程没有背景知识,但看起来所有的椭圆(如果真的是椭圆,很难说)都是同心的,所以为了提高准确性,我会尝试:
>
找到中心
或者它的近似值。让我们称之为x0, y0
,让图像分辨率为xs,ys
。要么你已经知道它的位置(由于你对图像属性的了解),要么估计它(扫描一个椭圆形,找到穿过整个椭圆形的两条线,它们的交叉点就是你的中心)。如果中心不精确,那么结果将更像椭圆形,然后是椭圆形,但这没关系,你可以稍后重建原始去噪图像,或者根据后者的数据重新计算中心…
从(x0, y0)
到(xs-1,0)
的投射射线
并将图像内容复制到一些大小为xs ys
的清除行缓冲区,以确保覆盖任何中心位置…
将整个图像与光线整合
所以投射光线总是从(x0, y0)
到(xs-1,1),(xs-1,2)…(xs-1,ys-1)
然后(xs-2,ys-1),…(0,ys-1)
等来覆盖整个图像周长。找出与原始存储行的比例(大多数峰值必须匹配)并将重新缩放的图像内容沿着光线添加到存储的行缓冲区中。
记住每个角度的刻度。
用用过的光线计数覆盖整个图像分割线缓冲区后,你可以在椭圆形环中平均切割出很多情人噪声。现在只需找到其中的峰。每个峰代表单独的椭圆形,它的位置给你初始光线位置角的半径。
刻度给你椭圆形/椭圆形的属性。所以找到最小和最大刻度,给你主轴和小轴所在的角度…具有峰值位置的刻度本身给你轴的大小…所以不需要RANSAC(但是你仍然可以用它来计算刻度)。
[笔记]
为了避免出现在平均线上,您可以为每个像素添加一个计数,其中包含添加到每个像素的光线数量,并将其用于最终分割。
此外,这些QA可能会有所帮助:
[Edit1]一些进一步的信息
我很好奇,所以我尝试了一下(概念证明)。我将您的图像调整为512x512
,以便它适合窗口以便于视觉检查,并手动将中心设置为(133,285)
然后创建所有光线的集成(暂时不缩放),然后我部分重建图像:
像太阳一样的形状是由综合平均线重建的图像,其余的是原始图像。正如你所看到的,这两个几乎完全吻合,所以你的椭圆几乎是圆形的(或者是圆形的,我的中心有点偏离)。
水图的强度(y轴)与积分平均线中心的距离有关。每个峰值代表一个圆。因此,您可以在1D数据中找到圆,而不是在2D中拟合。这里完全重建图像,无需任何调试绘制:
不管怎么看,缩放不是一个好方法,应该使用偏移(从上次光线偏移 /-几个像素)来代替。如果有更多的时间心情,我会试一试…
[edit2]更精确的中心和更多信息
你越接近中心,平均线上出现的尖峰就越尖锐和更大。它可以用来更精确地拟合中心(我用它发现我在x轴上偏离了1个像素,这对于手动选择中心非常好…)。之后,由于椭圆是圆,不需要缩放或移动。然后只需减去平均线的滑动平均值(Aqua图)并仅检测正尖峰(蓝图):
每个尖峰代表一个圆(半径是距离中心的距离,这也是以像素为单位的线数组中的地址),因此只需保持强度尖峰并输出圆…
在应用峰值检测和全精度集成后: