Open3d学习计划——高级篇 6(体素化)

点云和三角网格是一种十分灵活的,但是不规则的几何类型。体素网格是通过规则的3D网格来表示的另一种3D几何类型,并且它可以看作是2D像素在3D上的对照物。Open3d中的VoxelGrid几何类型能够被用来处理体素网格数据。

从三角网格中生成

Open3d提供了create_from_triangle_mesh函数能够从三角网格中生成体素网格。它返回一个体素网格,其中所有与三角形相交的网格被设置为1,其余的设置为0。其中voxel_zie参数是用来设置网格分辨率。

print('input')
mesh = o3dtut.get_bunny_mesh()
# fit to unit cube
mesh.scale(1 / np.max(mesh.get_max_bound() - mesh.get_min_bound()), center=mesh.get_center())
o3d.visualization.draw_geometries([mesh])print('voxelization')
voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh(mesh,voxel_size=0.05)
o3d.visualization.draw_geometries([voxel_grid])

input

voxelization

从点云中生成

也能够使用create_from_point_cloud函数从点云中生成体素网格。如果点云中至少有一个点在体素网格内,则该网格被占用。颜色表示的是该体素中点的平均值。参数voxel_size 用来定义网格分辨率。

print('input')
N = 2000
pcd = o3dtut.get_armadillo_mesh().sample_points_poisson_disk(N)
# fit to unit cube
pcd.scale(1 / np.max(pcd.get_max_bound() - pcd.get_min_bound()), center=pcd.get_center())
pcd.colors = o3d.utility.Vector3dVector(np.random.uniform(0,1,size=(N,3)))
o3d.visualization.draw_geometries([pcd])print('voxelization')
voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd,voxel_size=0.05)
o3d.visualization.draw_geometries([voxel_grid])

input

voxelization

包含测试

体素网格也能够用来测试点是否在被占用的网格内。方法check_if_included接受一个(n,3)数组作为输入,返回一个bool类型的数组。

queries = np.asarray(pcd.points)
output = voxel_grid.check_if_included(o3d.utility.Vector3dVector(queries))
print(output[:10])

[True, True, True, True, True, True, True, True, True, True]

体素雕刻

方法create_from_point_cloudcreate_from_triangle_mesh只能够在几何体的表面创造体素网格。然而从大量的深度图或者轮廓中雕刻一个体素网格是有可能的。Open3d提供了carve_depth_mapcarve_silhouette方法用于体素雕刻。

下面的代码展示了使用方法,首先从一个几何形状中得到 depthmaps ,之后使用 depthmaps 去雕刻出稠密的体素网格。最后的结果是一个给定形状的填充的体素网格。

def xyz_spherical(xyz):x = xyz[0]y = xyz[1]z = xyz[2]r = np.sqrt(x * x + y * y + z * z)r_x = np.arccos(y / r)r_y = np.arctan2(z, x)return [r, r_x, r_y]def get_rotation_matrix(r_x, r_y):rot_x = np.asarray([[1, 0, 0], [0, np.cos(r_x), -np.sin(r_x)],[0, np.sin(r_x), np.cos(r_x)]])rot_y = np.asarray([[np.cos(r_y), 0, np.sin(r_y)], [0, 1, 0],[-np.sin(r_y), 0, np.cos(r_y)]])return rot_y.dot(rot_x)def get_extrinsic(xyz):rvec = xyz_spherical(xyz)r = get_rotation_matrix(rvec[1], rvec[2])t = np.asarray([0, 0, 2]).transpose()trans = np.eye(4)trans[:3, :3] = rtrans[:3, 3] = treturn transdef preprocess(model):min_bound = model.get_min_bound()max_bound = model.get_max_bound()center = min_bound + (max_bound - min_bound) / 2.0scale = np.linalg.norm(max_bound - min_bound) / 2.0vertices = np.asarray(model.vertices)vertices -= centermodel.vertices = o3d.utility.Vector3dVector(vertices / scale)return modeldef voxel_carving(mesh,output_filename,camera_path,cubic_size,voxel_resolution,w=300,h=300,use_depth=True,surface_method='pointcloud'):mesh.compute_vertex_normals()camera_sphere = o3d.io.read_triangle_mesh(camera_path)# setup dense voxel gridvoxel_carving = o3d.geometry.VoxelGrid.create_dense(width=cubic_size,height=cubic_size,depth=cubic_size,voxel_size=cubic_size / voxel_resolution,origin=[-cubic_size / 2.0, -cubic_size / 2.0, -cubic_size / 2.0])# rescale geometrycamera_sphere = preprocess(camera_sphere)mesh = preprocess(mesh)# setup visualizer to render depthmapsvis = o3d.visualization.Visualizer()vis.create_window(width=w, height=h, visible=False)vis.add_geometry(mesh)vis.get_render_option().mesh_show_back_face = Truectr = vis.get_view_control()param = ctr.convert_to_pinhole_camera_parameters()# carve voxel gridpcd_agg = o3d.geometry.PointCloud()centers_pts = np.zeros((len(camera_sphere.vertices), 3))for cid, xyz in enumerate(camera_sphere.vertices):# get new camera posetrans = get_extrinsic(xyz)param.extrinsic = transc = np.linalg.inv(trans).dot(np.asarray([0, 0, 0, 1]).transpose())centers_pts[cid, :] = c[:3]ctr.convert_from_pinhole_camera_parameters(param)# capture depth image and make a point cloudvis.poll_events()vis.update_renderer()depth = vis.capture_depth_float_buffer(False)pcd_agg += o3d.geometry.PointCloud.create_from_depth_image(o3d.geometry.Image(depth),param.intrinsic,param.extrinsic,depth_scale=1)# depth map carving methodif use_depth:voxel_carving.carve_depth_map(o3d.geometry.Image(depth), param)else:voxel_carving.carve_silhouette(o3d.geometry.Image(depth), param)print("Carve view %03d/%03d" % (cid + 1, len(camera_sphere.vertices)))vis.destroy_window()# add voxel grid survaceprint('Surface voxel grid from %s' % surface_method)if surface_method == 'pointcloud':voxel_surface = o3d.geometry.VoxelGrid.create_from_point_cloud_within_bounds(pcd_agg,voxel_size=cubic_size / voxel_resolution,min_bound=(-cubic_size / 2, -cubic_size / 2, -cubic_size / 2),max_bound=(cubic_size / 2, cubic_size / 2, cubic_size / 2))elif surface_method == 'mesh':voxel_surface = o3d.geometry.VoxelGrid.create_from_triangle_mesh_within_bounds(mesh,voxel_size=cubic_size / voxel_resolution,min_bound=(-cubic_size / 2, -cubic_size / 2, -cubic_size / 2),max_bound=(cubic_size / 2, cubic_size / 2, cubic_size / 2))else:raise Exception('invalid surface method')voxel_carving_surface = voxel_surface + voxel_carvingreturn voxel_carving_surface, voxel_carving, voxel_surface
mesh = o3dtut.get_armadillo_mesh()output_filename = os.path.abspath("../../TestData/voxelized.ply")
camera_path = os.path.abspath("../../TestData/sphere.ply")
visualization = True
cubic_size = 2.0
voxel_resolution = 128.0voxel_grid, voxel_carving, voxel_surface = voxel_carving(mesh, output_filename, camera_path,cubic_size, voxel_resolution)

Carve view 001/642
Carve view 002/642
Carve view 003/642
Carve view 004/642

Carve view 642/642
Surface voxel grid from pointcloud

print("surface voxels")
print(voxel_surface)
o3d.visualization.draw_geometries([voxel_surface])print("carved voxels")
print(voxel_carving)
o3d.visualization.draw_geometries([voxel_carving])print("combined voxels (carved + surface)")
print(voxel_grid)
o3d.visualization.draw_geometries([voxel_grid])

surface voxels
geometry::VoxelGrid with 17215 voxels.

carved voxels
geometry::VoxelGrid with 48370 voxels.

combined voxels (carved + surface)
geometry::VoxelGrid with 50786 voxels.

关于翻译大家有更好的意见欢迎评论一起学习!!

欢迎大家加入知识星球一起学习。

Open3d学习计划——高级篇 6(体素化)相关推荐

  1. Open3d学习计划——高级篇 9(表面重建)

    Open3d学习计划--高级篇 9(表面重建) 在许多场景下我们希望生成密集的3D几何形状,比如三角网格.然而从多视图立体算法和深度传感器中我们只能够获得非结构化的点云数据.我们需要使用表面重建算法来 ...

  2. Open3d学习计划—高级篇 6(体素化)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  3. Open3d学习计划—高级篇 3(点云全局配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  4. Open3d学习计划—高级篇 2(彩色点云配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  5. Open3d学习计划—高级篇 8(网格变形)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  6. Open3d学习计划—高级篇 7(颜色映射)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  7. Open3d学习计划—高级篇 5(RGBD融合)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  8. Open3d学习计划—高级篇 4(多视角点云配准)

    本文为转载文章,原创作者为blue同学,可关注他的博客:https://blog.csdn.net/io569417668 Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和 ...

  9. Open3d 学习计划—12(Jupyter 可视化)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

最新文章

  1. sklearn使用pipeline、ParameterGrid以及GridSearchCV进行超参数调优
  2. 熊出没之伐木机器人_熊出没第一首富之争:李老板真的是第一吗?难道不是他第一?...
  3. hitTest和pointInside如何响应用户点击事件
  4. [Android]Android端ORM框架——RapidORM(v2.1)
  5. 讲一点分布式的基础知识,图解!
  6. 最近面试一些厂的面经整理(阿里,腾讯,字节等)
  7. java自带的xml解析,使用Java自带SAX工具解析XML
  8. java虚拟内存扩展_Java 8虚拟扩展方法
  9. 【洛谷】1600:天天爱跑步【LCA】【开桶】【容斥】【推式子】
  10. 手把手教你启动若依微服务项目
  11. libevent c++高并发网络编程_高并发-网络I/O
  12. 小米2s安卓10刷机包_小米10刷机包
  13. 维普c语言代码查重原理,维普查重太假了?面对变态查重方式,如何修正才能通过考核?...
  14. kindle 4 简易电子书格式转换(txt转mobi)
  15. 翻译《有关编程、重构及其他的终极问题?》——13.表格化的格式化
  16. Gos ——操作键盘
  17. python爬取微信好友头像_python 使用wxpy实现获取微信好友列表 头像 群成员
  18. Linux常用命令汇总 - 近乎全量命令!
  19. html 超链接标签 a 的基本用法
  20. 无U盘 安装纯净win7系统

热门文章

  1. 小学第三册上计算机wps教案,小学三年级上册信息技术教案【三篇】
  2. # 关于给小程序字体加粗
  3. 如何制作网站?如何制作网站教程
  4. hana迁移可行性评估_评估``有益的AI''的可行性以及如何将其应用于自动驾驶汽车
  5. PAT习题6-8单词首字母大写
  6. xiyou linux 2018面试题基本知识点
  7. 数据库连接池基本使用步骤
  8. 吴恩达说,现在你可以拿起手机打一辆自动驾驶汽车去市中心
  9. 多供应商IT系统稳定性保障
  10. 使用petalinux定制Linux系统(基于xsa文件)