Open supriya-gdptl opened 3 years ago
@griegler can we fix this by adding a pybind for the class AddVoxel()
here?
I also want this function. Now I use another method to achieve this. By change it into pointcloud,then use VoxelGrid.create_from_point_cloud() to get the voxel. All code are below,hoping can help you~
import numpy as np
import open3d as o3d
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def voxel2array(grid_index_array,voxel_size=64):
"""
convert a voxel_grid_index array to a fixed size array
(N*3)->(voxel_size*voxel_size*voxel_size)
:input grid_index_array: get from o3d.voxel_grid.get_voxels()
:return array_voxel: array with shape(voxel_size*voxel_size*voxel_size),the grid_index in
"""
array_voxel=np.zeros((voxel_size,voxel_size,voxel_size))
array_voxel[grid_index_array[:,0],grid_index_array[:,1],grid_index_array[:,2]]=1
return array_voxel
def array2voxel(voxel_array):
"""
convert a to a fixed size array to voxel_grid_index array
(voxel_size*voxel_size*voxel_size)->(N*3)
:input voxel_array: array with shape(voxel_size*voxel_size*voxel_size),the grid_index in
:return grid_index_array: get from o3d.voxel_grid.get_voxels()
"""
x,y,z=np.where(voxel_array==1)
index_voxel=np.vstack((x,y,z))
grid_index_array=index_voxel.T
return grid_index_array
#################Main convert here#################
#1: load o3d_voxel and get grid_index_array
#load o3d_voxel
data_path="chair_0001.ply"
o3d_voxel=o3d.io.read_voxel_grid(data_path)
frame = o3d.geometry.TriangleMesh.create_coordinate_frame(1)
o3d.visualization.draw_geometries([o3d_voxel,frame])
#get grid_index_array
voxel_list=o3d_voxel.get_voxels()
grid_index_array=list(map(lambda x:x.grid_index,voxel_list))
grid_index_array=np.array(grid_index_array)
#2: change to full voxel array
voxel_array=voxel2array(grid_index_array)
#3: show voxel in matplab.But this is slow
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.voxels(voxel_array,edgecolor="red")
plt.show()
#4: change back to o3d format
#change to open3d format pointcloud,then change to voxelgrid through create_from_point_cloud
grid_index_array=array2voxel(voxel_array)
pointcloud_array=grid_index_array*0.03125#0.03125 is voxel_size
pc=o3d.geometry.PointCloud()
pc.points=o3d.utility.Vector3dVector(pointcloud_array)
o3d_voxel=o3d.geometry.VoxelGrid.create_from_point_cloud(pc, voxel_size=0.03125)
o3d.visualization.draw_geometries([o3d_voxel,frame])
How is it going on the issue? I cannot find a way to control voxels manually. Even deleting a voxel seems unallowed too.
Discovered the same thing after a bit of fiddling with this lib. There is a bunch of methods on VoxelGrid
if you dir()
it:
['HalfEdgeTriangleMesh',
'Image',
'LineSet',
'PointCloud',
'RGBDImage',
'TetraMesh',
'TriangleMesh',
'Type',
'Unspecified',
'VoxelGrid',
'__add__',
'__class__',
'__copy__',
'__deepcopy__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getstate__',
'__gt__',
'__hash__',
'__iadd__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'add_voxel',
'carve_depth_map',
'carve_silhouette',
'check_if_included',
'clear',
'create_dense',
'create_from_octree',
'create_from_point_cloud',
'create_from_point_cloud_within_bounds',
'create_from_triangle_mesh',
'create_from_triangle_mesh_within_bounds',
'dimension',
'get_axis_aligned_bounding_box',
'get_center',
'get_geometry_type',
'get_max_bound',
'get_min_bound',
'get_minimal_oriented_bounding_box',
'get_oriented_bounding_box',
'get_rotation_matrix_from_axis_angle',
'get_rotation_matrix_from_quaternion',
'get_rotation_matrix_from_xyz',
'get_rotation_matrix_from_xzy',
'get_rotation_matrix_from_yxz',
'get_rotation_matrix_from_yzx',
'get_rotation_matrix_from_zxy',
'get_rotation_matrix_from_zyx',
'get_voxel',
'get_voxel_bounding_points',
'get_voxel_center_coordinate',
'get_voxels',
'has_colors',
'has_voxels',
'is_empty',
'origin',
'remove_voxel',
'rotate',
'scale',
'to_octree',
'transform',
'translate',
'voxel_size']
, but in general i suppose because it's a wrapper around Cpp we don't get either the typehints nor the args right. There's "add voxel" but really, it's not the best library to do fine manipulations on voxel grid. Try something else like pyvista
or do everything in numpy.
I have 64^3 voxel saved as the NumPy array. I want to create an Open3D VoxelGrid object from it and use it for offscreen rendering. I followed the suggestion given in issue #1101, but got the same error as mentioned in #2660 :
AttributeError: 'open3d.cpu.pybind.geometry.VoxelGrid' object has no attribute 'voxels'
Any suggestion on how to create VoxelGrid from NumPy array?