简体   繁体   English

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

[英]How do I create a binary mask on a square grid from a 2D cloud of points in Python?

I have a the X and Y coordinates of a 2D cloud of points that I want to map onto a 2D uniform grid with a resolution of imageResolution of initially all zeros.我有一个 2D 点云的 X 和 Y 坐标,我想将这些点映射到一个分辨率为imageResolution最初全为零的 2D 统一网格上。 I want all pixels in the grid which overlay the 2D cloud of points to contain ones, to produce a binary image.我希望网格中覆盖 2D 点云的所有像素都包含像素,以生成二进制图像。

Please note, there are a very large number of points both in my 2D cloud of points and in the uniform grid, and so loops are not an effective solution here.请注意,在我的二维点云和统一网格中都有大量的点,因此循环在这里不是有效的解决方案。

I have looked at convex hulls but my points are not necessarily in a convex set.我看过凸包,但我的点不一定在凸集中。

I have tried this following code, but its not giving me the correct binary map, since its only assigning 1s to the nearest grid points closest to the points in the point cloud (see image below):我已经尝试了以下代码,但它没有给我正确的二进制图,因为它只将 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()

Please see this image which shows my 2D cloud of points, the desired binary map I want, and the current binary map I am getting from the code above.请看这张图片,它显示了我的二维点云、我想要的所需二进制地图,以及我从上面的代码中获得的当前二进制地图。 Please note the red pixels are difficult to see in the last image.请注意,在最后一张图片中很难看到红色像素。

描述此问题的图片

How do I create a binary mask on a square grid from a 2D cloud of points in Python?如何从 Python 中的二维点云在方形网格上创建二进制掩码?

Thank you谢谢

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

If I've understood correctly, rather than mark an individual pixel with 1 , you should be marking a neighborhood of pixels.如果我理解正确的话,不是用1标记单个像素,而是应该标记像素的邻域。

You could try inserting the following lines just before binaryMap[xIndex,yIndex] = 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)

Note:笔记:

DELTA_UPPER is a parameter that you will have to fine-tune by playing around with. DELTA_UPPER是一个参数,您必须通过使用进行微调。 (Maybe start with DELTA_UPPER=3 ) (也许从DELTA_UPPER=3开始)

UNTESTED CODE未经测试的代码

Based on further clarifications, posting this second answer, to better index the binaryMap , given that points contains floats.根据进一步的说明,发布第二个答案,以便更好地索引binaryMap ,因为points包含浮点数。

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

(There's no need for find_index() ) (不需要find_index()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM