Skip to content

Commit

Permalink
Added optional invert parameter in Pointcloud cropping (similar to te…
Browse files Browse the repository at this point in the history
…nsor pointcloud) (#6377)

* Added optional invert in cropping
---------
Co-authored-by: Sameer Sheorey <sameer.sheorey@intel.com>
  • Loading branch information
wakkoyankee authored Sep 28, 2023
1 parent f1a0f3e commit ea2001f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
14 changes: 8 additions & 6 deletions cpp/open3d/geometry/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,23 +541,25 @@ std::shared_ptr<PointCloud> PointCloud::FarthestPointDownSample(
return SelectByIndex(selected_indices);
}

std::shared_ptr<PointCloud> PointCloud::Crop(
const AxisAlignedBoundingBox &bbox) const {
std::shared_ptr<PointCloud> 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_));
return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),
invert);
}
std::shared_ptr<PointCloud> PointCloud::Crop(
const OrientedBoundingBox &bbox) const {
std::shared_ptr<PointCloud> 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_));
return SelectByIndex(bbox.GetPointIndicesWithinBoundingBox(points_),
invert);
}

std::tuple<std::shared_ptr<PointCloud>, std::vector<size_t>>
Expand Down
8 changes: 6 additions & 2 deletions cpp/open3d/geometry/PointCloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,19 @@ class PointCloud : public Geometry3D {
/// clipped.
///
/// \param bbox AxisAlignedBoundingBox to crop points.
std::shared_ptr<PointCloud> Crop(const AxisAlignedBoundingBox &bbox) const;
/// \param invert Optional boolean to invert cropping.
std::shared_ptr<PointCloud> Crop(const AxisAlignedBoundingBox &bbox,
bool invert = false) const;

/// \brief Function to crop pointcloud into output pointcloud
///
/// All points with coordinates outside the bounding box \p bbox are
/// clipped.
///
/// \param bbox OrientedBoundingBox to crop points.
std::shared_ptr<PointCloud> Crop(const OrientedBoundingBox &bbox) const;
/// \param invert Optional boolean to invert cropping.
std::shared_ptr<PointCloud> 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.
Expand Down
11 changes: 6 additions & 5 deletions cpp/pybind/geometry/pointcloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@ void pybind_pointcloud(py::module &m) {
"num_samples"_a)
.def("crop",
(std::shared_ptr<PointCloud>(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>(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 "
Expand Down Expand Up @@ -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"},
Expand Down
32 changes: 32 additions & 0 deletions cpp/tests/geometry/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,38 @@ 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<geometry::PointCloud> pc_crop = pcd.Crop(aabb, true);
ExpectEQ(pc_crop->points_,
std::vector<Eigen::Vector3d>({{3, 1, 1}, {-1, 1, 1}}));
ExpectEQ(pc_crop->normals_,
std::vector<Eigen::Vector3d>({{4, 0, 0}, {5, 0, 0}}));
ExpectEQ(pc_crop->colors_,
std::vector<Eigen::Vector3d>({{0.4, 0.0, 0.0}, {0.5, 0.0, 0.0}}));
ExpectEQ(pc_crop->covariances_,
std::vector<Eigen::Matrix3d>({4.0 * Eigen::Matrix3d::Identity(),
5.0 * Eigen::Matrix3d::Identity()}));
}

TEST(PointCloud, EstimateNormals) {
geometry::PointCloud pcd({
{0, 0, 0},
Expand Down

0 comments on commit ea2001f

Please sign in to comment.