如何将椭圆拟合到二维数据

信息处理 计算机视觉 形状分析
2021-12-20 01:18:50

我想找到椭圆与连续的、可能是凹形的“最佳”拟合,例如:

在此处输入图像描述

我尝试了什么?

我认为可以指定主轴和次轴的方向a,b通过将像素值映射到坐标、均值相减和保存 PCA 中最大的两个特征向量来计算椭圆。似乎在寻找方向方面效果很好:

在此处输入图像描述

我的问题是确定这两个向量的长度。目前,我已经使用λ1 λ2,来自 PCA 的特征值。这似乎低估了长度。我怎样才能确定|a|, 和|b|或者,最适合这些形状的椭圆?

2个回答

跟进我删除的答案...如果您采用实心椭圆并将所有点投影到x轴,更多的点将投射在原点附近而不是极端,呈圆形分布。不是高斯分布,也不是我在删除的答案中在一维类比中提到的均匀分布。结果分布实际上有pdfp(x)=(1(xr)2),从那里你可以计算出标准差是r2.

因此,如果数据均匀分布在半径椭圆的内部a,b(其轴是xy轴),的标准偏差x坐标是a2和的y坐标是b2. 因此,您需要使用的校正因子只是 2。

这是python中的一个工作示例,从椭圆内部随机采样的点恢复椭圆的中心(平移矩阵)、旋转矩阵和半径:

import numpy

# Generate some points distributed uniformely along an ellipse
x = 2 * (numpy.random.rand(10000, 1) - 0.5)
y = 2 * (numpy.random.rand(10000, 1) - 0.5)
d = (x / 0.5) ** 2 + (y / 0.25) ** 2
inside = numpy.where(d < 1)[0]
x = x[inside]
y = y[inside]
data = numpy.hstack((x, y)).T

# Now rotate by 0.5 rad and translate it to (4, -8)
angle = 0.5
rotation = numpy.array([
    [numpy.cos(0.4), -numpy.sin(0.4)],
    [numpy.sin(0.4), numpy.cos(0.4)]])

data = numpy.dot(rotation, data)
data[0, :] += 4
data[1, :] -= 8

# Step 1: center the data to get the translation vector.
print 'Translation', data.mean(axis=1)
data -= numpy.reshape(data.mean(axis=1), (2, 1))

# Step 2: perform PCA to find rotation matrix.
scatter = numpy.dot(data, data.T)
eigenvalues, transform = numpy.linalg.eig(scatter)
print 'Rotation matrix', transform

# Step 3: Rotate back the data and compute radii.
# You can also get the radii from smaller to bigger
# with 2 / numpy.sqrt(eigenvalues)
rotated = numpy.dot(numpy.linalg.inv(transform), data)
print 'Radii', 2 * rotated.std(axis=1)

检查Fitzgibbon 等人的椭圆的直接最小二乘拟合。这是一个简单的特征值问题,其大小与样本中的像素数不成正比!唯一取决于你扔给它的像素数量的步骤是计算散布矩阵,它仍然是O(n).