isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.2k stars 2.27k forks source link

Minimum Bounding Box appears to be not minimum #5417

Closed lschirmbrand closed 1 year ago

lschirmbrand commented 2 years ago

Checklist

Describe the issue

I have computed a point cloud of an object. The goal is to measure the object size in pixel, use a reference object with a known width and calculate the pixel/mm ration, to apply to other pointclouds of the same measure system.

But for that, the width, height, and length are necessary. I suppose one could calculate the rotation and translation, orient it to the origin of the coordinate system and just calculate the size then.

To make that shorter and faster, I was trying to use a bounding box. But it seems like, the bounding box is not the minimal bounding box, instead it's rotated and returns a big bounding box, which I can't use for measurement.

image

Maybe I have done something wrong, but the documentation pointed me this way, so I don't know.

Steps to reproduce the bug

import open3d as o3d

...

bb_pcd_ref = pcd_ref.get_oriented_bounding_box()

... 

o3d.visualization.draw_geometries([bb_pcd_ref, pcd_ref, coordinate_system])

Error message

No response

Expected behavior

I expected the output to be the minimal bounding box, but it was not.

Open3D, Python and System information

- Operating system: Windows 10 64-bit
- Python version: Python 3.8.13
- Open3D version: output from python: 0.11.2
- System architecture: x86
- Is this a remote workstation?: no
- How did you install Open3D?: conda

Additional information

No response

lschirmbrand commented 2 years ago

Small update here:

tried to compute the bounding box with the robust flag, like stated in the documentation, to see if that changes something:

get_oriented_bounding_box(self: open3d.cpu.pybind.geometry.Geometry3D, robust: bool = False)

Error:

TypeError: get_oriented_bounding_box(): incompatible function arguments. The following argument types are supported:
    1. (self: open3d.cpu.pybind.geometry.Geometry3D) -> open3d::geometry::OrientedBoundingBox

So there is no flag, as far as I can see.

nigels-com commented 2 years ago

If I'm looking at the right C++ source indeed it's not attempting to minimise the oriented box.

    /// Creates an oriented bounding box using a PCA.
    /// Note, that this is only an approximation to the minimum oriented
    /// bounding box that could be computed for example with O'Rourke's
    /// algorithm (cf. http://cs.smith.edu/~jorourke/Papers/MinVolBox.pdf,
    /// https://www.geometrictools.com/Documentation/MinimumVolumeBox.pdf)
    /// \param points The input points
    /// \param robust If set to true uses a more robust method which works
    ///               in degenerate cases but introduces noise to the points
    ///               coordinates.
    static OrientedBoundingBox CreateFromPoints(
            const std::vector<Eigen::Vector3d>& points, bool robust = false);
bkhanal-11 commented 2 years ago

I ran into similar problem with get_oriented_bounding_box(). Using get_axis_aligned_bounding_box() worked better for me.

lschirmbrand commented 2 years ago

I ran into similar problem with get_oriented_bounding_box(). Using get_axis_aligned_bounding_box() worked better for me.

As far as I know, that creates a bounding box relative to coordinate axes. So if your pointcloud is not aligned to any axis, the result won't be minimum either.

lschirmbrand commented 2 years ago

For people running into the same problem as me:

I did not fix the problem with the bounding box functions. Instead, I used references in the pointcloud, calculated the plane with some RANSAC algorithm, calculated the plane orientation, rotated it, calculated the bounding box manually.

ligerlac commented 1 year ago

@lschirmbrand would you mind sharing the code of your work-around? I encountered the same problem and ended up using a different library to calculate the oriented bounding box (compas). I used the function oriented_bounding_box_numpy() . The implementation is here: https://github.com/compas-dev/compas/blob/main/src/compas/geometry/bbox/bbox_numpy.py You can find an example comparison below. Open3d is white, compas is black.

o3d_vs_compas

benjaminum commented 1 year ago

Closing this issue because it is not a bug. The discussion can continue here or in https://github.com/isl-org/Open3D/discussions . If the minimum bounding box is an important feature create a new feature request issue and consider contributing an implementation.