如何使用R找到最佳拟合的圆/椭圆?
我一直在阅读一些将圆与数据拟合的方法(如)。我想看看这些方法是如何在真实数据上工作的,并考虑使用R来实现这一点。我尝试在rseek中搜索可以帮助实现这一点的包,但没有找到任何有用的东西如何使用R找到最佳拟合的圆/椭圆?,r,best-fit-curve,R,Best Fit Curve,我一直在阅读一些将圆与数据拟合的方法(如)。我想看看这些方法是如何在真实数据上工作的,并考虑使用R来实现这一点。我尝试在rseek中搜索可以帮助实现这一点的包,但没有找到任何有用的东西 那么,是否有软件包可以帮助轻松计算给定数据集的最佳拟合圆(类似于lm()将线性模型拟合到数据集的方式)?否则,如何在R中执行这样的任务?这是一个相当简单的函数实现,它可以最小化该论文中的SS(a,b,R): fitSS <- function(xy, a0=mean(xy
那么,是否有软件包可以帮助轻松计算给定数据集的最佳拟合圆(类似于
lm()
将线性模型拟合到数据集的方式)?否则,如何在R中执行这样的任务?这是一个相当简单的函数实现,它可以最小化该论文中的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, ...)
}
fit$par
值是x中心、y中心和半径的向量
> 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)
)
}
circlexy好吧,看这里:安已经写了一些代码来适应椭圆和圆。他的代码基于Radim Halíř和Jan Flusser在Matlab中完成的先前工作,我不在这里重复。他的代码包括(注释)用于比较的原始Matlab行
我浏览了很多关于这个主题的论文,只能说我没有资格确定哪些算法是最健壮的。对于感兴趣的人,请查看以下文件:
后续编辑:我将Spacedman的代码与用于拟合椭圆的链接R代码进行对比,使用同一个“嘈杂”的圆上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
通过fit.eliple
,我们得到
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
你可以看到,对于偏离圆的项,椭圆方程的系数接近于零;绘制这两个结果会产生几乎无法区分的曲线。看看这篇文章和这个闪亮的应用程序。你引用的论文中的方法看起来并不难实现。只有三个参数(x,y,r),而封闭形式解的方法甚至不需要优化。试试编程吧,你会学到很多R技巧。制作一个包…因为椭圆不是单值的,所以不能使用线性(甚至非线性)拟合工具,因为这些工具几乎只需要单值函数。因此,照@Spacedman说的去做。见鬼,如果你不这么做,我会的,因为这看起来很有趣:-)投票重新开放,因为我不认为计算一个边界椭圆真的适合这个问题。即使你计算一个50%的边界椭圆,也不清楚它是否(例如,最小二乘法)最适合点本身。嘿,我以为你让SO写了这个包:-)知道我会在某个地方找到它(最后):plotrix::draw.circle
似乎和你的行(circlexy(foo))一样
有。我想sim_圆的某个地方有runif(n.-pi,pi)
。也许函数(n=10,radius=1,var=radius/10){angle=runif(n.-pi,pi);list(x=radius*sin(angle)+var*runif(n),y=radius*cos(angle)+var*runif(n))}
对于“xy=sim_圆(10)”,需要什么库,数据集不可用??如何从中得到半径
ssfit
$par
[1] 249.9530 149.9927 200.0512
$value
[1] 185.8195
$counts
function gradient
134 NA
$convergence
[1] 0
$message
NULL
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