【问题标题】:Finding edge from 2d points Python从二维点Python中寻找边缘
【发布时间】:2015-12-14 21:30:53
【问题描述】:

我有几组 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')  
    

顺便说一句,彩色图左侧的“间隙”与上面黑白图中的“间隙”相同。我也很确定我可以更好地使用 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. 来自 sklearn.cluster 的 KMeans()。使用 n=3 集群,我尝试使用默认设置运行该类并获得三组水平点。我还没有学会如何训练数据来识别形成边缘的点。

这是数据点来自的模型的一部分。实心区域包含点,而空洞则没有。

Herehere 是我提出的其他一些问题,它们显示了我一直在研究的更多内容。

【问题讨论】:

  • 试试图片处理标签;他们一直在处理这种发现。 :-)
  • 您要做的是找到一组点的“凸包”。您可以使用多个algorithms 来执行此操作。
  • 看起来你的情节中有一些结构。有可能利用它吗?或者这是一个非典型的例子?在这里,您似乎只对最左边的边缘感兴趣。是通用的吗?
  • Scipy 可以为您找到凸包:docs.scipy.org/doc/scipy/reference/generated/…
  • 是的,但那条线不是凸包。 OP想要一些接近点的东西,即使它们的“边缘”不是凸的。

标签: python image-processing edge-detection convex-hull scikits


【解决方案1】:

所以我能够以迂回的方式做到这一点。

我使用从 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

这是一个显示掩蔽效果的图:

我仍在微调边框,但现在我有一个非常易于管理的任务,因为蒙版已基本完成。原因是某些掩码点不正确导致条带化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多