如何删除Skimage拟合调整后的参数化椭圆内的数据点
问题描述
我有如下数据分布:
我使用from skimage.measure import EllipseModel围绕部分数据拟合椭圆,通过输入B0_M数据(X1)和对应5200-5350区间的q²数据(Y1)完成拟合,代码如下:
X1Y1 = np.column_stack((X1,Y1)) ell = EllipseModel() ell.estimate(X1Y1) xc, yc, a, b, theta = ell.params
拟合得到的椭圆参数为:
a = 0.399894 b = 37.826 xc = 5272 yc = 9.27 theta = 1.573
由于拟合效果不理想,我对参数做了缩放、微调,得到图中红色椭圆,绘制代码如下:
xc, yc, a, b, theta = ell.params t = np.linspace(0, 2*np.pi, 100) dt = 0.01*theta ell_x = xc + 2*a*np.cos(theta+dt)*np.cos(t) - 1.8*b*np.sin(theta+dt)*np.sin(t) ell_y = yc + 0.47*a*np.sin(theta+dt)*np.cos(t) + 0.47*b*np.cos(theta+dt)*np.sin(t)+0.26 plt.scatter(X,Y, marker = '.', alpha = 0.05, color = 'navy', s =0.2) plt.scatter(xc, yc+0.26, color='red', s=10) plt.plot(ell_x, ell_y, color = 'red') plt.xlim(5150,5400) plt.ylim(7,12) plt.xlabel('B0_M') plt.ylabel('$q^2$') plt.title('jpsi')
现在我想删除X1和Y1中所有位于这个椭圆内部的点。原本想用椭圆方程判断,但因为是调整后的参数化形式,实现起来麻烦,有没有简便方法?
解决方法
直接基于你调整后的椭圆参数化逻辑,把点转换到椭圆的局部坐标系下,用标准椭圆不等式判断即可,具体步骤:
- 提取调整后的椭圆关键参数
先把你绘制椭圆时用到的调整项明确出来:# 提取你调整后的关键参数 adjusted_theta = theta + dt scale_a = 2 scale_b = 1.8 offset_y = 0.26 # 对应调整后的椭圆中心 adjusted_xc = xc adjusted_yc = yc + offset_y - 将原始点转换到椭圆局部坐标系
把每个点平移到椭圆中心为原点,再旋转抵消椭圆的倾斜角度:# 平移点到椭圆中心 dx = X1 - adjusted_xc dy = Y1 - adjusted_yc # 旋转坐标,得到无倾斜的局部坐标系 cos_theta = np.cos(adjusted_theta) sin_theta = np.sin(adjusted_theta) x_local = dx * cos_theta + dy * sin_theta y_local = -dx * sin_theta + dy * cos_theta - 判断点是否在椭圆内部
调整后的椭圆在局部坐标系下的半轴长是scale_a * a和scale_b * b,满足以下不等式的点即为内部点:# 内部点返回True,外部点返回False inside = (x_local / (scale_a * a))**2 + (y_local / (scale_b * b))**2 <= 1 - 筛选保留椭圆外部的点
用布尔索引过滤掉内部点:# 保留所有不在椭圆内部的点 X1_outer = X1[~inside] Y1_outer = Y1[~inside]
这样就能精准匹配你绘制的椭圆,直接完成点的筛选,不需要重新推导复杂的椭圆方程。
内容的提问来源于stack exchange,提问作者probablysid
相关产品推荐
相关产品推荐

