You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Open3D中已着色的Voxel对象构建VoxelGrid

问题:Open3D中如何用已着色的Voxel对象组装新VoxelGrid?

问题描述

我用Open3D处理两个点云,先完成体素化,再根据每个体素内的点数量差异为体素着色。已经通过o3d.geometry.VoxelGrid.create_from_point_cloud()创建了两个VoxelGrid对象,计算后得到一批已分配颜色的Voxel对象,但不知道如何将这些Voxel组装成新的VoxelGrid,卡在了这一步。

翻遍Open3D文档也没找到直接实现的函数,我考虑过一种思路:获取目标体素的中心坐标,用这些坐标和对应颜色创建o3d.geometry.PointCloud,再通过o3d.geometry.VoxelGrid.create_from_point_cloud()生成新网格,但不确定有没有更便捷的方式,比如未知的运算符重载。我用Open3D的经验不多。

当前代码片段

common_voxels = []
vox = self.pc_source.voxel_grid.get_voxels()
cmap = LinearSegmentedColormap.from_list('custom_colormap', [(0, 'green'), (0.5, 'yellow'), (1, 'red')])
norm = plt.Normalize(vmin=delta_min, vmax=delta_max)
sm = ScalarMappable(cmap=cmap, norm=norm)
colors = sm.to_rgba(point_count_delta)


for i, (voxel_idx, source_idx, target_idx, source_point_count, target_point_count) in enumerate(self.common_voxel_point_count_idx_map):
    vox[source_idx].color = colors[i][[0, 1, 2]]
    common_voxels.append(vox[source_idx])
    # vox_center = self.pc_source.voxel_grid.get_center_coordinate
    print(i)

vox_grid = o3d.geometry.VoxelGrid()
for i in range(len(common_voxels)):
    vox_grid += common_voxels[i]

解决方案

Open3D的VoxelGrid没有直接添加单个Voxel的API,代码中使用的+=运算符也无效。这里提供两种实用的实现方式:

方法1:基于现有VoxelGrid修改颜色(推荐)

既然你的common_voxels来自源VoxelGrid,直接在源网格基础上修改对应体素的颜色,再复制出新网格即可,无需重新组装:

# 复制源VoxelGrid以保留原参数(体素大小、原点等)
new_vox_grid = self.pc_source.voxel_grid.clone()
# 获取可修改的体素列表
voxels = new_vox_grid.get_voxels()

for i, (voxel_idx, source_idx, target_idx, source_point_count, target_point_count) in enumerate(self.common_voxel_point_count_idx_map):
    voxels[source_idx].color = colors[i][[0, 1, 2]]

# 将修改后的体素列表重新绑定到新网格
new_vox_grid.voxels = voxels

这种方法无需重新计算体素化,效率最高,且能完整保留原网格的所有配置。

方法2:通过点云重建VoxelGrid

如果需要完全从零构建,可以用体素中心坐标创建带颜色的点云,再用与原网格相同的参数重新体素化:

import open3d as o3d
import numpy as np

centers = []
colors_list = []
# 提取原网格的关键参数,保证体素对齐
voxel_size = self.pc_source.voxel_grid.voxel_size
origin = self.pc_source.voxel_grid.origin

for voxel in common_voxels:
    # 计算体素中心坐标:原点 + (体素索引 + 0.5) * 体素大小
    center = origin + (np.array(voxel.grid_index) + 0.5) * voxel_size
    centers.append(center)
    colors_list.append(voxel.color)

# 创建带颜色的点云
color_pc = o3d.geometry.PointCloud()
color_pc.points = o3d.utility.Vector3dVector(np.array(centers))
color_pc.colors = o3d.utility.Vector3dVector(np.array(colors_list))

# 用原参数重建VoxelGrid
new_vox_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(
    color_pc,
    voxel_size=voxel_size,
    origin=origin
)

这种方法需要重新体素化,效率稍低,但适合完全从零构建的场景。

内容的提问来源于stack exchange,提问作者Máté Kosztricz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:47:22