i'm trying to crop a PointCloud using an OrientedBoundingBox with the Open3D built-in method, the pcl is not orthogonal with the axis and I need to get a bounding parallel to the pcl, I tried to set the rotation matrix R of the bounding box but it is always created parallel to XY plane and orthogonal to Z axis, where am I wrong? this is my code
mesh_coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.3, origin=[0, 0, 0.45])
##CREATE BOUNDING BOX FROM CENTER, EXTENSION AND ROTATION
oriented_bounding_box = o3d.geometry.OrientedBoundingBox(center=[0.0, 0.0, 0.65], extent=[0.10, 0.10, 0.02],
R=[[np.cos(np.pi/4), 0, 0], [0, np.sin(np.pi/4), 0], [0, 0, 1]])
##CROP THE VOLUME IN THE BOUNDING BOX
point_cloud_crop = pcd.crop(oriented_bounding_box)
# View original point cloud with the cuboid, all 5 points present
o3d.visualization.draw_geometries([mesh_coord_frame, pcd, oriented_bounding_box])
# View cropped point cloud with the cuboid, only 3 points present
o3d.visualization.draw_geometries([mesh_coord_frame, point_cloud_crop, oriented_bounding_box])
Check how the rotation matrix looks like when doing rotation along 3 axes on the wikipedia.
What you are using as rotation matrix is
[
[np.cos(np.pi/4), 0, 0],
[0, np.sin(np.pi/4), 0],
[0, 0, 1]
]
This when multiplied with any vector (x,y,z), will only scale down x value by np.cos(np.pi/4)
, y value by np.sin(np.pi/4)
and keep z unchanged (multiplied by 1). This matrix is not a rotation matrix.
Now, for rotation, you can generate rotation matrix as:-
R = o3d.geometry.get_rotation_matrix_from_xyz((0, np.pi/4, np.pi/4))
oriented_bounding_box = o3d.geometry.OrientedBoundingBox(
center=[0.0, 0.0, 0.65],
extent=[0.10, 0.10, 0.02],
R=R
)
Another method useful for you will be finding oriented bounding box for your pointcloud.
# Create an example pointcloud
pcl:o3d.geometry.PointCloud = o3d.io.read_point_cloud(o3d.data.PLYPointCloud().path)
# Compute an OBB which covers pcl tightly. Robust = True helps in degenerative cases, it adds a little noise to prevent any computational error.
oriented_bounding_box = pcl.get_oriented_bounding_box(robust=True)
# Set color since OBB will have white color which is difficult to see with white background of visualizer.
oriented_bounding_box.color = [1.0, 0, 0]