1

I want to convert a set of point cloud (X, Y, Z) to a binary mask image using python. The problem is that these points are float and out of range of 0-255. To more specific, the points are related to an object (rectangle or ellipsoid), so I should make a binary image based on Z dimension, to specify the rectangle, for example, as 0 number and other points as 1 number in binary mask. Can anyone give me some ideas to achieve my goal?

My point is like this array:

 [[-1.56675167e+01  1.59539632e+01  1.15432026e-02]
 [-1.26066835e+01  6.48645007e+00  1.15510724e-02]
 [-1.18854252e+01  1.71767061e+01  1.15392632e-02]
 ...
 [-1.45721083e+01  1.39116935e+01 -9.86438582e-04]
 [-1.42607847e+01  1.28141373e+01 -1.73514791e-03]
 [-1.48834319e+01  1.50092497e+01  7.59929187e-04]]

I was tried to get such binary mask that was answered in this example ():

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path
from descartes import PolygonPatch
import alphashape
from shapely.geometry import Point, Polygon

def poly2mask():
    
    # First of all, I separated the contour of the polygon and get vertices 
    # in the border

    hull = alphashape.alphashape(surface_org, 0.)  # convex hull  
    poly = PolygonPatch(hull, alpha=0.2, edgecolor='#999999')
    vertices = poly.get_path().vertices
    x = vertices[:, 0] * 10
    y = vertices[:, 1] * 10
    vertices_ls = list(zip(x, y))

    width, height = 120, 120

    poly_path = Path(vertices_ls, closed=True)

    x, y = np.mgrid[:height, :width]
    coors = np.hstack((x.reshape(-1, 1), y.reshape(-1, 1)))  

    mask = poly_path.contains_points(coors)
    mask = mask.reshape(height, width)
    #print(mask)
    plt.imshow(mask)
    plt.ylim(-200, 200)
    plt.xlim(-200, 200)
    plt.show()

The image would look like this: enter image description here

Masoumeh
  • 23
  • 1
  • 6
  • It looks to me like your point array is simply plotting points on an X,Y,Z coordinate system. Since a binary mask image is simply an 8-bit rendering of an image using values in the range of 0 to 255, there isn't enough information to create a mask. – itprorh66 Jun 09 '21 at 23:13
  • Could you tell me what the information is needed? Thank you for your help – Masoumeh Jun 10 '21 at 07:01
  • 1
    what do you mean by binary mask image? if you have a Nx3 array of points you can create Nx1 sized mask, if you want to create some sort of a 2D image from your points cloud you would need to apply some sort of a projection to reduce dimensionality – Dominik Ficek Jun 10 '21 at 10:06
  • Thank you for your answer. I mean that I need to create a mask map (0 and 1) from a polygon with floating points. I searched a lot and I found that **matplotlib.path** and **pillow** libraries can be helpful, however, it does not work for my polygon. I have no idea – Masoumeh Jun 10 '21 at 14:41
  • 1
    Please post a picture (or post a link to a graphic, or even a pen drawing) showing the raw data, then an example showing what the binary mask should look like. Pick just one shape--a rectangle (or cuboid, if the source data is in 3D). You mention floats being out of range of an 8-bit integer, but that the result should be a binary mask image. Graphics would make this a bit clearer. – Rethunk Jun 10 '21 at 23:30
  • Thank for your response. I have updated my question. I added image and my code. – Masoumeh Jun 11 '21 at 18:19
  • To do that you need first to project on the Z axis. You can use matplotlib to do that easely by rotating your point cloud and save your figure(look this [function][1]). Next step is to open your image in a matrix and you change the value in 255 is you got a color. [1]: https://github.com/daavoo/pyntcloud/blob/master/pyntcloud/plot/matplotlib_backend.py – Eldir Jun 22 '21 at 06:31

0 Answers0