【问题标题】:How do I create a binary mask on a square grid from a 2D cloud of points in Python?如何从 Python 中的二维点云在方形网格上创建二进制掩码?
【发布时间】:2021-03-06 17:38:55
【问题描述】:

我有一个二维点云的 X 和 Y 坐标,我想将其映射到一个二维均匀网格上,分辨率为 imageResolution,最初全为零。我希望网格中覆盖二维点云的所有像素都包含一个像素,以生成二值图像。

请注意,在我的二维点云和统一网格中都有大量的点,因此循环在这里不是一个有效的解决方案。

我看过凸包,但我的点不一定在凸集中。

我已经尝试过以下代码,但它没有给我正确的二进制地图,因为它只将 1 分配给最接近点云中的点的最近网格点(见下图):

X = points[:,0] #1D array of X coordinates
Y = points[:,1] #1D array of Y coordinates

imageResolution = 256
xVec = np.linspace(0,800,imageResolution)
yVec = xVec

def find_index(x,y):
    xi=np.searchsorted(xVec,x)
    yi=np.searchsorted(yVec,y)
    return xi,yi

xIndex, yIndex = find_index(X,Y)

binaryMap = np.zeros((imageResolution,imageResolution))

binaryMap[xIndex,yIndex] = 1

fig = plt.figure(1)
plt.imshow(binaryMap, cmap='jet')
plt.colorbar()

请看这张图片,它显示了我的二维点云、我想要的所需二进制映射以及我从上面的代码中获得的当前二进制映射。请注意,最后一张图片中的红色像素很难看到。

如何在 Python 中从二维点云在方形网格上创建二进制掩码?

谢谢

【问题讨论】:

  • 也许这个答案会有所帮助:stackoverflow.com/a/10560275/6386471
  • 嗨@user6386471,griddata 使用凸包的概念,而我的数据点不一定在凸集中。我也有非凸数据点

标签: python image numpy matplotlib points


【解决方案1】:

免责声明 :: 未经测试的建议

如果我理解正确,而不是用1 标记单个像素,您应该标记像素邻域。

您可以尝试在 binaryMap[xIndex,yIndex] = 1 之前插入以下行:

DELTA_UPPER=2                                # Param. Needs fine-tuning
delta = np.arange(DELTA_UPPER).reshape(-1,1)
xIndex = xIndex + delta
xIndex [xIndex >= imageResolution] = imageResolution-1
yIndex = yIndex + delta
yIndex [yIndex >= imageResolution] = imageResolution-1

x_many, y_many = np.broadcast_arrays (xIndex[:,None], yIndex)

xIndex = x_many.reshape(-1)
yIndex = y_many.reshape(-1)

注意:

DELTA_UPPER 是一个参数,您必须通过使用来进行微调。 (可能以DELTA_UPPER=3开头)

【讨论】:

  • 您好,感谢您的回答。如果我标记一个像素邻域,形状的边界将无法在二进制地图上正确表示
  • @InternetUser0947 引用:“我已经尝试过以下代码,但它没有给我正确的二进制地图,因为它只将 1 分配给最接近点云中的点的最近网格点”。对我来说,这听起来像是您要求的症结所在。 (我将其解释为绘图的精确性导致事物不那么明显)。因此我发布了这个解决方案。您能否重新澄清当前输出中的错误以及您对输出的期望。谢谢。
  • @InternetUser0947 -- 如果您正在寻找更准确的绘图方式,也许您可​​以尝试使用binaryMap[X,Y] = 1 而不是binaryMap[xIndex,yIndex] = 1(因为您已经定义了X = points[:,0]Y = points[:,1] )。这假定points 中的值是range(imageResolution) 中的严格整数。 find_index() 函数需要什么?我错过了什么吗?
  • 请查看我提出的问题以及我提出的图像。特别是,请看我想要的输出,与当前输出相比。我基本上想要二维点云所在域中的所有地方,而其他地方都为零。关于您的第二点,X 和 Y 是 1)不是整数且 2)与 2D 网格点不重合的点。
  • 请看我刚刚发布的第二个答案。它对XY 中的值进行四舍五入,并确保它们可以安全地用作binaryMap 的索引。请让我知道它是否有效。
【解决方案2】:

未经测试的代码

鉴于points 包含浮点数,基于进一步澄清,发布第二个答案以更好地索引binaryMap

imageResoluton = 256
MAX_X = # Fill in here the max x value ever possible in `points`
MIN_X = # Fill in here the min x value ever possible in `points`
MAX_Y = # Fill in here the max y value ever possible in `points`
MIN_Y = # Fill in here the min y value ever possible in `points`

SCALE_FAC = imageResolution / max(MAX_X-MIN_X, MAX_Y-MIN_Y)

X = np.around(SCALE_FAC * points[:,0]).astype(np.int64)
Y = np.around(SCALE_FAC * points[:,1]).astype(np.int64)
X [X >= imageResolution] = imageResolution-1
Y [Y >= imageResolution] = imageResolution-1

binaryMap[X, Y] = 1

(不需要find_index()

【讨论】:

  • 您好,这不起作用。因为 X 和 Y 是独立的点云坐标。它们与统一网格不一致。它们只是构成形状的点的散布点的 x 坐标和 y 坐标。
  • points 中的值是否有任何定义的最大和最小范围?一些永远不会超过的范围?如果是这样,您可以找到缩放因子来缩放points 的所有 x 和 y 值,缩小到 256x256 网格的比例
  • @InternetUser0947 -- 我已编辑此答案以显示缩放逻辑的外观。让我知道这是否可行
  • 我刚刚尝试了这个解决方案,我可以确认它仍然不起作用。它产生的输出看起来类似于第三张图像,其中只有几个点的值为 1。而我想要像第二张图片这样的图像。
  • 这可能意味着云太稀疏而看不到(点相距太远。这意味着,您可能必须标记像素邻域而不是单个像素。你能告诉我有多少点你有points 吗?
猜你喜欢
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多