Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added optional invert parameter in Pointcloud cropping (similar to tensor pointcloud) #6377

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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