Open3D icon indicating copy to clipboard operation
Open3D copied to clipboard

Cropping point cloud using a convex polygon

Open gliese581gg opened this issue 4 years ago • 8 comments

Introduction

Hi!

I added a function that crops a point cloud using a convex hull polygon.

Points within the convex hull will be cropped.

Also , we can use 'invert' argument to select the points outside the convex hull

Test

I tested the function using the following code

import open3d as o3d
import numpy as np
import os,sys,time
import json
from threading import Thread
import copy

x = 3.
y = 3.
z = 3.

vertices = np.array([[0.,0.,0.],
                      [x,y,z],
                      [x,y,-z],
                      [x,-y,z],
                      [x,-y,-z]])
                                           

def get_bounding_convex_hull(points):
    points_v3 = o3d.utility.Vector3dVector(points)
    pcd = o3d.geometry.PointCloud(points_v3)
    ch = o3d.geometry.BoundingConvexHull(pcd)
    return ch

filt = get_bounding_convex_hull(vertices)
filt_ls = o3d.geometry.LineSet.create_from_triangle_mesh(filt.get_convex_hull())

N_iter = 1000
N = 100
start_time = time.time()

axis = o3d.geometry.TriangleMesh.create_coordinate_frame()
pcd_vis = o3d.geometry.PointCloud()
pcd_cropped_vis = o3d.geometry.PointCloud()

gd = {}
gd['axis'] = axis
gd['pcd'] = pcd_vis
gd['pcd_filt'] = pcd_cropped_vis
gd['fov'] = filt_ls

def run_visualizer(geo_dict):
    vis = o3d.visualization.Visualizer()
    vis.create_window()

    for k,v in geo_dict.items():
        vis.add_geometry(v)

    ctrl = vis.get_view_control()
    ctrl.set_up(np.array([0.,1.,0.]))
    p = copy.deepcopy(  ctrl.convert_to_pinhole_camera_parameters()  )
    temp = p.extrinsic.copy()
    temp[:3,3] = np.array([0.,0.,20.])
    p.extrinsic = temp
    ctrl.convert_from_pinhole_camera_parameters(p,allow_arbitrary=True)

    cnt = 0

    while True:
        for k,v in geo_dict.items():
            vis.update_geometry(v)
        poll_result = vis.poll_events()
        vis.update_renderer()
        # vis.capture_screen_image('screenshots/%02d.png'%cnt)
        time.sleep(0.05)
        cnt += 1

        
thr = Thread(target=run_visualizer,args=(gd,))
thr.daemon = True
thr.start()  

points_raw_np = np.random.uniform(-3.,3.,(N,3))
points_raw_np[:,2] *= 0.1

transform_mat = np.array([  [0.9848077, -0.1736482,  0.0000000, 0.3],
                            [0.1736482,  0.9848077,  0.0000000, 0.2],
                            [0.0000000,  0.0000000,  1.0000000, 0.],
                            [0.0000000,  0.0000000,  0.0000000, 1.],
])

for i in range(N_iter):
    # Create point cloud from a numpy array    
    points_raw = o3d.utility.Vector3dVector(points_raw_np)
    pcd_raw = o3d.geometry.PointCloud(points_raw).paint_uniform_color([1.,0.,0.])

    # Move the bounding convex hull to check whether transform works correctly
    filt.transform(transform_mat)
    filt_ls.transform(transform_mat)
    pcd_cropped = pcd_raw.crop_convex_hull(filt,invert=False).paint_uniform_color([0.,1.,0.])
    
    pcd_vis.clear()
    pcd_vis += pcd_raw
    pcd_cropped_vis.clear()
    pcd_cropped_vis += pcd_cropped
 
    time.sleep(0.2)
    
print('Done!')


  • Screenshot 05

Please feel free to point out any issues.


This change is Reviewable

gliese581gg avatar Apr 08 '21 02:04 gliese581gg

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

update-docs[bot] avatar Apr 08 '21 02:04 update-docs[bot]

Hello, I am very interested about using the function (crop_convex_hull) to crop a pointcloud and most importly retrieve the remaining points! Despite updating the open3d python package to currently 0.14.1, I didn't find out your function : AttributeError: 'open3d.cpu.pybind.geometry.PointCloud' object has no attribute 'crop_convex_hull'. Is this function only available in the github code meaning that I have to build from source to be able to have access to this specific function?

Thanks in advance for your help!

raphael715 avatar Feb 14 '22 11:02 raphael715

@gliese581gg Are you going to implement the comments of @errissa? I am looking forward to use such function :D Cheers

fwarmuth avatar Aug 01 '22 09:08 fwarmuth

Hi ! I'm very interested in your functionality, Do you think I could be implemented in the main branch ? Very thank you !

will-44 avatar Nov 12 '22 23:11 will-44

Hi @benjaminum is this functionality now available in tensor point cloud?

ssheorey avatar Jan 20 '23 22:01 ssheorey

Hi @benjaminum is this functionality now available in tensor point cloud?

No but general cropping can be implemented with RaycastingScene and inside outside tests. This here can be more efficient if the convex bounding volume is small like in the example.

I am not sure about the ctor. It always computes the convex hull. Maybe it makes sense to assume a convex mesh for the TriMesh arg ctor.

benjaminum avatar Jan 23 '23 16:01 benjaminum

  • Add convex hull to mesh function for visualization.
  • Any other changes?

ssheorey avatar Jan 24 '23 17:01 ssheorey

Any chance this will get merged with the main branch? Looks super useful for trimming poisson meshes for organic shapes...

cgmcvey avatar Feb 13 '24 19:02 cgmcvey