4

我一直在阅读一些将圆拟合到数据的方法(如this)。我想看看这些方法如何处理真实数据,并考虑使用 R 来实现这一点。我尝试在 rseek 搜索可以帮助解决此问题的软件包,但没有找到任何有用的东西。

那么,是否有软件包可以帮助轻松计算给定数据集的最佳拟合圆(类似于如何lm()将线性模型拟合到数据集)?否则,如何在 R 中执行这样的任务?

4

2 回答 2

7

这是该论文中最小化 SS(a,b,r) 的函数的一个相当幼稚的实现:

fitSS <- function(xy,
                  a0=mean(xy[,1]),
                  b0=mean(xy[,2]),
                  r0 = mean(sqrt((xy[,1]-a0)^2 + (xy[,2]-b0)^2)),
                  ...){
    SS <- function(abr){
        sum((abr[3] - sqrt((xy[,1]-abr[1])^2 + (xy[,2]-abr[2])^2))^2)
    }
    optim(c(a0,b0,r0), SS, ...)
}

我编写了几个支持函数来生成圆圈上的随机数据并绘制圆圈。因此:

> xy = sim_circles(10)
> f = fitSS(xy)

fit$par值是 xcenter、ycenter、radius 的向量。

> plot(xy,asp=1,xlim=c(-2,2),ylim=c(-2,2))
> lines(circlexy(f$par))

点和拟合圆

请注意,它不使用梯度,也不检查收敛的错误代码。您可以为其提供初始值,也可以猜测。

绘制和生成圆圈的代码如下:

circlexy <- function(xyr, n=180){
    theta = seq(0,2*pi,len=n)
    cbind(xyr[1] + xyr[3]*cos(theta),
          xyr[2] + xyr[3]*sin(theta)
          )
}
sim_circles <- function(n,x=0,y=0,r=1,sd=0.05){
    theta = runif(n, 0, 2*pi)
    r = r + rnorm(n, mean=0, sd=sd)
    cbind(x + r*cos(theta),
          y + r*sin(theta)
      )
}
于 2014-11-27T17:10:08.523 回答
2

好吧,看这里:一个 R-blogger 专栏已经编写了一些代码来适应椭圆和圆形。他的代码(我不会在这里重新发布)基于 Radim Halíř 和 Jan Flusser 在 Matlab 中所做的工作。他的代码包括(注释)原始 Matlab 行以进行比较。

我看过很多关于这个主题的论文,只能说我没有资格确定哪些算法是最健壮的。有兴趣的可以看看这些论文:

http://www.emis.de/journals/BBMS/Bulletin/sup962/gander.pdf

http://ralph.cs.cf.ac.uk/papers/Geometry/fit.pdf

http://autotrace.sourceforge.net/WSCG98.pdf

后续编辑:我针对链接的 R 代码运行 Spacedman 的代码以拟合椭圆,使用圆圈上相同的“嘈杂”集 1e5 点作为输入。结果是:

testcircle<-create.test.ellipse(Rx=200,Ry=200,Rot=.56,Noise=5.5,leng=100000)
 dim(testcircle)
[1] 100000      2

microbenchmark(fitSS(testcircle),fit.ellipse(testcircle))
Unit: milliseconds
                    expr       min        lq    median        uq       max
       fitSS(testcircle) 649.98245 704.05751 731.61282 787.84212 2053.7096
 fit.ellipse(testcircle)  25.74518  33.87718  38.87143  95.23499  256.2475
 neval
   100
   100

作为参考,两个拟合函数的输出为:

SSfit, 列表

ssfit
$par
[1] 249.9530 149.9927 200.0512

$value
[1] 185.8195

$counts
function gradient 
     134       NA 

$convergence
[1] 0

$message
NULL

fit.ellipse,我们得到

ellfit
$coef
            a             b             c             d             e 
-7.121109e-01 -1.095501e-02 -7.019815e-01  3.563866e+02  2.136497e+02 
            f 
-3.195427e+04 

$center
       x        y 
249.0769 150.2326 

$major
[1] 201.7601

$minor
[1] 199.6424

$angle
[1] 0.412268

您可以看到椭圆方程的系数对于“偏离”圆的项接近于零;绘制这两个结果会产生几乎无法区分的曲线。

于 2014-12-11T21:30:49.257 回答