从 2d 点寻找边缘 Python

Finding edge from 2d points Python

我有几组 2d 分散数据,我想找到它们的边缘。有些边可能是开放线,有些可能是多边形。

例如,这是一个有开放边缘的地块,我希望能够保留它。我实际上想从开放边缘创建一个多边形,这样我就可以使用 point_in_poly 检查是否有另一个点在里面。关闭多边形的点是我绘图区域的边界,顺便说一句。

关于从哪里开始的任何想法?

编辑:

这是我已经尝试过的:

  1. 来自 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
  1. 来自 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()
    

理想情况下,凸包的目标是最大化凸包内的面积,同时保持集合内的兴趣点,但我无法对此进行编码.

  1. 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

这是显示掩蔽效果的图表:

我仍在微调边界,但现在我的任务很容易处理,因为蒙版已基本完成。原因是一些掩码点不正确导致条带。