From 1be10fe5712e73f0987dc6941532e258a7b17f84 Mon Sep 17 00:00:00 2001 From: Hadrien Rothea Date: Mon, 18 Sep 2023 19:13:10 -0400 Subject: [PATCH 1/2] Added optional invert in cropping --- cpp/open3d/geometry/PointCloud.cpp | 10 +++++--- cpp/open3d/geometry/PointCloud.h | 6 +++-- cpp/pybind/geometry/pointcloud.cpp | 11 +++++---- cpp/tests/geometry/PointCloud.cpp | 39 ++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index 3e55bc3acd6..7ac0442a04f 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -542,22 +542,24 @@ std::shared_ptr PointCloud::FarthestPointDownSample( } std::shared_ptr PointCloud::Crop( - const AxisAlignedBoundingBox &bbox) const { + const AxisAlignedBoundingBox &bbox, + bool invert) const { if (bbox.IsEmpty()) { utility::LogError( "AxisAlignedBoundingBox either has zeros size, or has wrong " "bounds."); } - return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_)); + return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),invert); } std::shared_ptr PointCloud::Crop( - const OrientedBoundingBox &bbox) const { + const OrientedBoundingBox &bbox, + bool invert) const { if (bbox.IsEmpty()) { utility::LogError( "AxisAlignedBoundingBox either has zeros size, or has wrong " "bounds."); } - return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_)); + return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),invert); } std::tuple, std::vector> diff --git a/cpp/open3d/geometry/PointCloud.h b/cpp/open3d/geometry/PointCloud.h index b55840106b6..d42753e118e 100644 --- a/cpp/open3d/geometry/PointCloud.h +++ b/cpp/open3d/geometry/PointCloud.h @@ -185,7 +185,8 @@ class PointCloud : public Geometry3D { /// clipped. /// /// \param bbox AxisAlignedBoundingBox to crop points. - std::shared_ptr Crop(const AxisAlignedBoundingBox &bbox) const; + /// \param invert Optional boolean to invert cropping. + std::shared_ptr Crop(const AxisAlignedBoundingBox &bbox, bool invert=false) const; /// \brief Function to crop pointcloud into output pointcloud /// @@ -193,7 +194,8 @@ class PointCloud : public Geometry3D { /// clipped. /// /// \param bbox OrientedBoundingBox to crop points. - std::shared_ptr Crop(const OrientedBoundingBox &bbox) const; + /// \param invert Optional boolean to invert cropping. + std::shared_ptr Crop(const OrientedBoundingBox &bbox, bool invert=false) const; /// \brief Function to remove points that have less than \p nb_points in a /// sphere of a given radius. diff --git a/cpp/pybind/geometry/pointcloud.cpp b/cpp/pybind/geometry/pointcloud.cpp index d9e2ce935c6..304c1c59c08 100644 --- a/cpp/pybind/geometry/pointcloud.cpp +++ b/cpp/pybind/geometry/pointcloud.cpp @@ -86,16 +86,16 @@ void pybind_pointcloud(py::module &m) { "num_samples"_a) .def("crop", (std::shared_ptr(PointCloud::*)( - const AxisAlignedBoundingBox &) const) & + const AxisAlignedBoundingBox &, bool) const) & PointCloud::Crop, "Function to crop input pointcloud into output pointcloud", - "bounding_box"_a) + "bounding_box"_a, "invert"_a = false) .def("crop", (std::shared_ptr(PointCloud::*)( - const OrientedBoundingBox &) const) & + const OrientedBoundingBox &, bool) const) & PointCloud::Crop, "Function to crop input pointcloud into output pointcloud", - "bounding_box"_a) + "bounding_box"_a, "invert"_a = false) .def("remove_non_finite_points", &PointCloud::RemoveNonFinitePoints, "Removes all points from the point cloud that have a nan " "entry, or infinite entries. It also removes the " @@ -289,7 +289,8 @@ camera. Given depth value d at (u, v) image coordinate, the corresponding 3d poi "number of points[0-1]"}}); docstring::ClassMethodDocInject( m, "PointCloud", "crop", - {{"bounding_box", "AxisAlignedBoundingBox to crop points"}}); + {{"bounding_box", "AxisAlignedBoundingBox to crop points"}, + {"invert", "optional boolean to invert cropping"}}); docstring::ClassMethodDocInject( m, "PointCloud", "remove_non_finite_points", {{"remove_nan", "Remove NaN values from the PointCloud"}, diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index 379b8ad0941..06888f06eb0 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -982,6 +982,45 @@ TEST(PointCloud, Crop_OrientedBoundingBox) { })); } +TEST(PointCloud, Crop_AxisAlignedBoundingBox_Invert) { + geometry::AxisAlignedBoundingBox aabb({0, 0, 0}, {2, 2, 2}); + geometry::PointCloud pcd({{0, 0, 0}, + {2, 2, 2}, + {1, 1, 1}, + {1, 1, 2}, + {3, 1, 1}, + {-1, 1, 1}}); + pcd.normals_ = {{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, + {3, 0, 0}, {4, 0, 0}, {5, 0, 0}}; + pcd.colors_ = {{0.0, 0.0, 0.0}, {0.1, 0.0, 0.0}, {0.2, 0.0, 0.0}, + {0.3, 0.0, 0.0}, {0.4, 0.0, 0.0}, {0.5, 0.0, 0.0}}; + pcd.covariances_ = { + 0.0 * Eigen::Matrix3d::Identity(), + 1.0 * Eigen::Matrix3d::Identity(), + 2.0 * Eigen::Matrix3d::Identity(), + 3.0 * Eigen::Matrix3d::Identity(), + 4.0 * Eigen::Matrix3d::Identity(), + 5.0 * Eigen::Matrix3d::Identity(), + }; + std::shared_ptr pc_crop = pcd.Crop(aabb, true); + ExpectEQ(pc_crop->points_, std::vector({ + {3, 1, 1}, + {-1, 1, 1} + })); + ExpectEQ(pc_crop->normals_, std::vector({ + {4, 0, 0}, + {5, 0, 0} + })); + ExpectEQ(pc_crop->colors_, std::vector({ + {0.4, 0.0, 0.0}, + {0.5, 0.0, 0.0} + })); + ExpectEQ(pc_crop->covariances_, std::vector({ + 4.0 * Eigen::Matrix3d::Identity(), + 5.0 * Eigen::Matrix3d::Identity() + })); +} + TEST(PointCloud, EstimateNormals) { geometry::PointCloud pcd({ {0, 0, 0}, From 9ae3e39c666980ba00dd998443d5bee42616e3fe Mon Sep 17 00:00:00 2001 From: Sameer Sheorey Date: Wed, 27 Sep 2023 14:21:01 -0700 Subject: [PATCH 2/2] Style fix. --- cpp/open3d/geometry/PointCloud.cpp | 16 ++++++++-------- cpp/open3d/geometry/PointCloud.h | 6 ++++-- cpp/pybind/geometry/pointcloud.cpp | 2 +- cpp/tests/geometry/PointCloud.cpp | 25 +++++++++---------------- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index 7ac0442a04f..b0b6e0130ae 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -541,25 +541,25 @@ std::shared_ptr PointCloud::FarthestPointDownSample( return SelectByIndex(selected_indices); } -std::shared_ptr PointCloud::Crop( - const AxisAlignedBoundingBox &bbox, - bool invert) const { +std::shared_ptr PointCloud::Crop(const AxisAlignedBoundingBox &bbox, + bool invert) const { if (bbox.IsEmpty()) { utility::LogError( "AxisAlignedBoundingBox either has zeros size, or has wrong " "bounds."); } - return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),invert); + return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_), + invert); } -std::shared_ptr PointCloud::Crop( - const OrientedBoundingBox &bbox, - bool invert) const { +std::shared_ptr PointCloud::Crop(const OrientedBoundingBox &bbox, + bool invert) const { if (bbox.IsEmpty()) { utility::LogError( "AxisAlignedBoundingBox either has zeros size, or has wrong " "bounds."); } - return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),invert); + return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_), + invert); } std::tuple, std::vector> diff --git a/cpp/open3d/geometry/PointCloud.h b/cpp/open3d/geometry/PointCloud.h index d42753e118e..334bdc9f0f5 100644 --- a/cpp/open3d/geometry/PointCloud.h +++ b/cpp/open3d/geometry/PointCloud.h @@ -186,7 +186,8 @@ class PointCloud : public Geometry3D { /// /// \param bbox AxisAlignedBoundingBox to crop points. /// \param invert Optional boolean to invert cropping. - std::shared_ptr Crop(const AxisAlignedBoundingBox &bbox, bool invert=false) const; + std::shared_ptr Crop(const AxisAlignedBoundingBox &bbox, + bool invert = false) const; /// \brief Function to crop pointcloud into output pointcloud /// @@ -195,7 +196,8 @@ class PointCloud : public Geometry3D { /// /// \param bbox OrientedBoundingBox to crop points. /// \param invert Optional boolean to invert cropping. - std::shared_ptr Crop(const OrientedBoundingBox &bbox, bool invert=false) const; + std::shared_ptr Crop(const OrientedBoundingBox &bbox, + bool invert = false) const; /// \brief Function to remove points that have less than \p nb_points in a /// sphere of a given radius. diff --git a/cpp/pybind/geometry/pointcloud.cpp b/cpp/pybind/geometry/pointcloud.cpp index 304c1c59c08..835ec3123b1 100644 --- a/cpp/pybind/geometry/pointcloud.cpp +++ b/cpp/pybind/geometry/pointcloud.cpp @@ -290,7 +290,7 @@ camera. Given depth value d at (u, v) image coordinate, the corresponding 3d poi docstring::ClassMethodDocInject( m, "PointCloud", "crop", {{"bounding_box", "AxisAlignedBoundingBox to crop points"}, - {"invert", "optional boolean to invert cropping"}}); + {"invert", "optional boolean to invert cropping"}}); docstring::ClassMethodDocInject( m, "PointCloud", "remove_non_finite_points", {{"remove_nan", "Remove NaN values from the PointCloud"}, diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index 06888f06eb0..21bfe5659bf 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -1003,22 +1003,15 @@ TEST(PointCloud, Crop_AxisAlignedBoundingBox_Invert) { 5.0 * Eigen::Matrix3d::Identity(), }; std::shared_ptr pc_crop = pcd.Crop(aabb, true); - ExpectEQ(pc_crop->points_, std::vector({ - {3, 1, 1}, - {-1, 1, 1} - })); - ExpectEQ(pc_crop->normals_, std::vector({ - {4, 0, 0}, - {5, 0, 0} - })); - ExpectEQ(pc_crop->colors_, std::vector({ - {0.4, 0.0, 0.0}, - {0.5, 0.0, 0.0} - })); - ExpectEQ(pc_crop->covariances_, std::vector({ - 4.0 * Eigen::Matrix3d::Identity(), - 5.0 * Eigen::Matrix3d::Identity() - })); + ExpectEQ(pc_crop->points_, + std::vector({{3, 1, 1}, {-1, 1, 1}})); + ExpectEQ(pc_crop->normals_, + std::vector({{4, 0, 0}, {5, 0, 0}})); + ExpectEQ(pc_crop->colors_, + std::vector({{0.4, 0.0, 0.0}, {0.5, 0.0, 0.0}})); + ExpectEQ(pc_crop->covariances_, + std::vector({4.0 * Eigen::Matrix3d::Identity(), + 5.0 * Eigen::Matrix3d::Identity()})); } TEST(PointCloud, EstimateNormals) {