从 2d 点寻找边缘 Python
Finding edge from 2d points Python
我有几组 2d 分散数据,我想找到它们的边缘。有些边可能是开放线,有些可能是多边形。
例如,这是一个有开放边缘的地块,我希望能够保留它。我实际上想从开放边缘创建一个多边形,这样我就可以使用 point_in_poly
检查是否有另一个点在里面。关闭多边形的点是我绘图区域的边界,顺便说一句。
关于从哪里开始的任何想法?
编辑:
这是我已经尝试过的:
来自 sklearn 的内核密度。边缘点密度变化很大,无法与大部分点完全区分开来。
kde = KernelDensity()
kde.fit(my_data)
dens = np.exp(kde.score_samples(ds))
dmax = dens.max()
dens_mask = (0.4 * dmax < dens) & (dens < 0.8 * dmax)
ax.scatter(ds[dens_mask, 0], ds[dens_mask, 1], ds[dens_mask, 2],
c=dens[dens_mask], depthshade=False, marker='o', edgecolors='none')
顺便说一句,彩色图左侧的 'gap' 与上面黑白图中的相同。我也很确定我可以更好地使用 KDE。例如,我想获得更小体积的密度,更像是使用 sklearn 的 NearestNeighbors()
中的 radius_neighbors
来自 scipy 的 ConvexHull。我尝试从半随机数据中删除点(用于练习),同时仍然在凸集内保留一个兴趣点(此处为 0,0)。这不是很有效。我没有从迭代中排除点的复杂方法,只删除了最后一个凸包中使用的点。此代码和随附的图像显示了第一个和最后一个船体,同时将兴趣点保留在集合中。
hull = ConvexHull(pts)
contains = True
while contains:
temp_pts = np.delete(pts, hull.vertices, 0)
temp_hull = ConvexHull(temp_pts)
tp = path.Path(np.hstack((temp_pts[temp_hull.vertices, 0][np.newaxis].T,
temp_pts[temp_hull.vertices, 1][np.newaxis].T)))
if not tp.contains_point([0, 0]):
contains = False
hull = ConvexHull(pts)
plt.plot(pts[hull.vertices, 0], pts[hull.vertices, 1])
else:
pts = temp_pts
plt.plot(pts[hull.vertices, 0], pts[hull.vertices, 1], 'r-')
plt.show()
理想情况下,凸包的目标是最大化凸包内的面积,同时保持仅集合内的兴趣点,但我无法对此进行编码.
- KMeans() 来自 sklearn.cluster。使用 n=3 个集群,我只尝试了 运行 和 class 的默认设置,并得到了三个水平的点组。我还没有学会如何训练数据来识别形成边缘的点。
这是数据点来自的模型的一部分。实心区域包含点,而空隙区域不包含点。
Here, and here 是我问过的其他一些问题,它们显示了我一直在看的更多内容。
所以我能够以迂回的方式做到这一点。
我使用 SolidWorks 生成的 xy 平面中模型切片的图像来区分感兴趣的区域。
如果你看到它们,图片的角上有一些点,我在已知距离处放置在模型中以供参考。这些点使我能够确定每毫米的像素数。从那里,我将分析集中的点映射到像素并检查像素的颜色。如果像素为白色,则它被遮蔽了。
def mask_z_level(xi, yi, msk_img, x0=-14.3887, y0=5.564):
im = plt.imread(msk_img)
msk = np.zeros(xi.shape, dtype='bool')
pxmm = np.zeros((3, 2))
p = 0
for row in range(im.shape[0]):
for col in range(im.shape[1]):
if tuple(im[row, col]) == (1., 0., 0.):
pxmm[p] = (row, col)
p += 1
pxx = pxmm[1, 1] / 5.5
pxy = pxmm[2, 0] / 6.5
print(pxx, pxy)
for j in range(xi.shape[1]):
for i in range(xi.shape[0]):
x, y = xi[i, j], yi[i, j]
dx, dy = x - x0, y - y0
dpx = np.round(dx * pxx).astype('int')
dpy = -np.round(dy * pxy).astype('int')
if tuple(im[dpy, dpx]) == (1., 1., 1.):
msk[i, j] = True
return msk
这是显示掩蔽效果的图表:
我仍在微调边界,但现在我的任务很容易处理,因为蒙版已基本完成。原因是一些掩码点不正确导致条带。
我有几组 2d 分散数据,我想找到它们的边缘。有些边可能是开放线,有些可能是多边形。
例如,这是一个有开放边缘的地块,我希望能够保留它。我实际上想从开放边缘创建一个多边形,这样我就可以使用 point_in_poly
检查是否有另一个点在里面。关闭多边形的点是我绘图区域的边界,顺便说一句。
关于从哪里开始的任何想法?
编辑:
这是我已经尝试过的:
来自 sklearn 的内核密度。边缘点密度变化很大,无法与大部分点完全区分开来。
kde = KernelDensity() kde.fit(my_data) dens = np.exp(kde.score_samples(ds)) dmax = dens.max() dens_mask = (0.4 * dmax < dens) & (dens < 0.8 * dmax) ax.scatter(ds[dens_mask, 0], ds[dens_mask, 1], ds[dens_mask, 2], c=dens[dens_mask], depthshade=False, marker='o', edgecolors='none')
顺便说一句,彩色图左侧的 'gap' 与上面黑白图中的相同。我也很确定我可以更好地使用 KDE。例如,我想获得更小体积的密度,更像是使用 sklearn 的 NearestNeighbors()
来自 scipy 的 ConvexHull。我尝试从半随机数据中删除点(用于练习),同时仍然在凸集内保留一个兴趣点(此处为 0,0)。这不是很有效。我没有从迭代中排除点的复杂方法,只删除了最后一个凸包中使用的点。此代码和随附的图像显示了第一个和最后一个船体,同时将兴趣点保留在集合中。
hull = ConvexHull(pts) contains = True while contains: temp_pts = np.delete(pts, hull.vertices, 0) temp_hull = ConvexHull(temp_pts) tp = path.Path(np.hstack((temp_pts[temp_hull.vertices, 0][np.newaxis].T, temp_pts[temp_hull.vertices, 1][np.newaxis].T))) if not tp.contains_point([0, 0]): contains = False hull = ConvexHull(pts) plt.plot(pts[hull.vertices, 0], pts[hull.vertices, 1]) else: pts = temp_pts plt.plot(pts[hull.vertices, 0], pts[hull.vertices, 1], 'r-') plt.show()
理想情况下,凸包的目标是最大化凸包内的面积,同时保持仅集合内的兴趣点,但我无法对此进行编码.
- KMeans() 来自 sklearn.cluster。使用 n=3 个集群,我只尝试了 运行 和 class 的默认设置,并得到了三个水平的点组。我还没有学会如何训练数据来识别形成边缘的点。
这是数据点来自的模型的一部分。实心区域包含点,而空隙区域不包含点。
Here, and here 是我问过的其他一些问题,它们显示了我一直在看的更多内容。
所以我能够以迂回的方式做到这一点。
我使用 SolidWorks 生成的 xy 平面中模型切片的图像来区分感兴趣的区域。
如果你看到它们,图片的角上有一些点,我在已知距离处放置在模型中以供参考。这些点使我能够确定每毫米的像素数。从那里,我将分析集中的点映射到像素并检查像素的颜色。如果像素为白色,则它被遮蔽了。
def mask_z_level(xi, yi, msk_img, x0=-14.3887, y0=5.564):
im = plt.imread(msk_img)
msk = np.zeros(xi.shape, dtype='bool')
pxmm = np.zeros((3, 2))
p = 0
for row in range(im.shape[0]):
for col in range(im.shape[1]):
if tuple(im[row, col]) == (1., 0., 0.):
pxmm[p] = (row, col)
p += 1
pxx = pxmm[1, 1] / 5.5
pxy = pxmm[2, 0] / 6.5
print(pxx, pxy)
for j in range(xi.shape[1]):
for i in range(xi.shape[0]):
x, y = xi[i, j], yi[i, j]
dx, dy = x - x0, y - y0
dpx = np.round(dx * pxx).astype('int')
dpy = -np.round(dy * pxy).astype('int')
if tuple(im[dpy, dpx]) == (1., 1., 1.):
msk[i, j] = True
return msk
这是显示掩蔽效果的图表:
我仍在微调边界,但现在我的任务很容易处理,因为蒙版已基本完成。原因是一些掩码点不正确导致条带。