简体   繁体   中英

How to extract the bottom layer voxels using open3d?

I want to extract the bottom layer voxels. For example, extract the part from the armadillo. Does anyone know how to do that?

在此处输入图像描述

This is how I find the lowest voxel.

#Get voxels center coordinate
def get_voxel_center_coordinate(voxel_grid):
    voxels = voxel_grid.get_voxels()
    voxel_center = []
    
    for voxel in voxels:
        voxel_center.append(voxel_grid.get_voxel_center_coordinate(voxel.grid_index))
    
    return voxel_center

#Find lowest voxels index
def find_lowest_voxel_index(voxel_grid):
    voxels = voxel_grid.get_voxels()
    voxel_center = get_voxel_center_coordinate(voxel_grid)
    
    for i in range(0, len(voxel_center)):
        if i == 0:
            min_z = voxel_center[i, 2]
        else:
            if min_z > voxel_center[i, 2]:
                min_z = voxel_center[i, 2]
    ind = 0
    lowest_voxel_index = []
    
    for center in voxel_center:
        if center[2] == min_z:
            print(center[2])
            lowest_voxel_index.append(voxels[ind].grid_index)
            ind += 1
    
    return lowest_voxel_index

Your solution is almost correct. I'll point out a few things that you should change and then a way to verify the solution.

Solution

Things that should change in the given solution:

  1. You cannot access the z-axis through voxel_center[i, 2] since voxel_center is a list, not a numpy array. You should instead access them as voxel_center[i][2] .
  2. You should increment ind at each loop, not only when the condition is true. Alternatively, you can use enumerate which overcomes this cleanly.

Therefore, the correct implementation would be the following:

#Get voxels center coordinate
def get_voxel_center_coordinate(voxel_grid):
    voxels = voxel_grid.get_voxels()
    voxel_center = []
    
    for voxel in voxels:
        voxel_center.append(voxel_grid.get_voxel_center_coordinate(voxel.grid_index))
    
    return voxel_center

#Find lowest voxels index
def find_lowest_voxel_index(voxel_grid):
    voxels = voxel_grid.get_voxels()
    voxel_center = get_voxel_center_coordinate(voxel_grid)
    
    for i in range(0, len(voxel_center)):
        if i == 0:
            min_z = voxel_center[i][2]
        else:
            if min_z > voxel_center[i][2]:
                min_z = voxel_center[i][2]
    ind = 0
    lowest_voxel_index = []
    
    for center in voxel_center:
        if center[2] == min_z:
            print(center[2])
            lowest_voxel_index.append(voxels[ind].grid_index)
        ind += 1
    
    return lowest_voxel_index

Verification

To verify the solution, you might want to visualize the results. However, VoxelGrid does not have any method that allows the user to eg, change the color of a particular voxel. Therefore, you can think of creating extra meshes to visualize the filtered voxels. Since VoxelGrid provides get_voxel_bounding_points , you can make use of these points to create an AxisAlignedBoundingBox .

lowest_index = find_lowest_voxel_index(voxel_grid)  # this uses your solution after modifications

bounding_box = []
for i in lowest_index:
    bb = o3d.geometry.AxisAlignedBoundingBox.create_from_points(voxel_grid.get_voxel_bounding_points(i))
    bb.color = np.array([1,0,1])  # feel free to choose any other color
    bounding_box.append(bb)


axes = o3d.geometry.TriangleMesh.create_coordinate_frame(origin=np.array([100,100,100]), size=100)  # in order to be sure of the direction

o3d.visualization.draw_geometries([voxel_grid, *bounding_box, axes])

This is how running this code on an armadillo mesh looks like. Note that I added the coordinate frame to make sure of the direction. Blue arrow points toward +z. The voxel with the lowest z value has purple edges. 在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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