【问题标题】:How to crop a point cloud in Open3D by using a polygon volume?如何使用多边形体积在 Open3D 中裁剪点云?
【发布时间】:2022-05-18 21:28:49
【问题描述】:

首先我不得不说我对编程很陌生,尤其是在 Open3D 方面。我正在尝试裁剪点云,但不是如 Open3D 教程中所示使用 *.json 文件,而是使用我使用 4 个坐标(2D 边界框的角点)创建的多边形体积。 我的代码如下所示。

model = "point_cloud.ply"
pcd = o3d.io.read_point_cloud(model)
downpcd = pcd.voxel_down_sample(voxel_size = 0.015)

corners = np.array([
        [ -0.091687413867212741, -0.14071210477866827, 0.0 ],
        [ 0.030980770065893004, -0.14071210477866827, 0.0 ],
        [ 0.030980770065893004, -0.044064443478879611, 0.0 ],
        [ -0.091687413867212741, -0.044064443478879611, 0.0 ]
    ])

bounding_polygon = corners.astype("float64")

vol = o3d.visualization.SelectionPolygonVolume()
vol.orthogonal_axis = "Z"
vol.axis_max = 0.81700000000000017
vol.axis_min = -2.8580000000000001
vol.bounding_polygon = o3d.utility.Vector3dVector(bounding_polygon)

到目前为止,一切似乎都运行良好,但是当我尝试使用此多边形体积通过此功能裁剪加载的点云时,我总是收到错误消息。

cropped_pcd = vol.crop_point_cloud([downpcd])

这是我得到的错误:

Traceback (most recent call last):
  File "c:\Users\Privat\Desktop\User\PCD\CropPCDByCoordinates.py", line 42, in <module>
    cropped_pcd = vol.crop_point_cloud([downpcd])
TypeError: crop_point_cloud(): incompatible function arguments. The following argument types are supported:
    1. (self: open3d.cpu.pybind.visualization.SelectionPolygonVolume, input: open3d.cpu.pybind.geometry.PointCloud) -> open3d.cpu.pybind.geometry.PointCloud

Invoked with: SelectionPolygonVolume, access its members:
orthogonal_axis, bounding_polygon, axis_min, axis_max, [PointCloud with 364980 points.]

当我使用具有相同信息的 *.json 文件时,一切正常,但我想在不加载 *.json 文件的情况下对其进行裁剪。

这是我从中获取信息的 *.json 文件:

{
    "axis_max" : 0.81700000000000017,
    "axis_min" : -2.8580000000000001,
    "bounding_polygon" : 
    [
        [ -0.091687413867212741, -0.14071210477866827, 0.0 ],
        [ 0.030980770065893004, -0.14071210477866827, 0.0 ],
        [ 0.030980770065893004, -0.044064443478879611, 0.0 ],
        [ -0.091687413867212741, -0.044064443478879611, 0.0 ]
    ],
    "class_name" : "SelectionPolygonVolume",
    "orthogonal_axis" : "Z",
    "version_major" : 1,
    "version_minor" : 0

} 

任何如何避免此错误的建议和/或解释将不胜感激。谢谢。

我在 Windows 10 上的 MS Visual Studio Code 中使用 Python 3.9。

【问题讨论】:

  • 快速浏览后,我想知道您为什么将[downpcd] 传递给crop_point_cloud 而不是downpcd。该函数需要一个 PointCloud,但您传递的是一个包含一个 PointCloud 元素的列表。

标签: open3d


【解决方案1】:

在 open3d 中裁剪点云的另一种方法是使用类边界框的对象(因此它只处理矩形而不是更高的多边形)。

让我们创建一个以原点为中心的任意边界框,边长小于 1,旋转为 R。

R = np.identity(3)  
extent = np.ones(3)/1.5 # trying to create a bounding box below 1 unit
center = np.zeros(3) 
obb = o3d.geometry.OrientedBoundingBox(center,R,extent) # or you can use axis aligned bounding box class

现在您可以通过以下方式裁剪点云 (pcd):

cropped = pcd.crop(obb)

o3d.visualization.draw_geometries([cropped]) #press ESC to close

要获取此边界框内的点的索引:

inliers_indices = obb.get_point_indices_within_bounding_box(pcd.points)
        
inliers_pcd = pcd.select_by_index(inliers_indices, invert=False) # select inside points = cropped 
outliers_pcd = pcd.select_by_index(inliers_indices, invert=True) #select outside points
    
o3d.visualization.draw_geometries([outliers_pcd])

如果您已经知道要裁剪的边界,则可以像上面一样创建一个边界框并进行裁剪。或者如果你想裁剪 w.r.t.另一个点云/对象的边界框(如果您知道姿势,则可以对其进行变换,然后计算它的边界框)并使用此边界框来裁剪较大的点云。获取点云的边界框:

obb = pcd.get_oriented_bounding_box(robust=False) #set robust =True for more robust computation.
aabb = pcd.get_axis_aligned_bounding_box()

【讨论】:

    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多