From b3fb7bc594c9b429829629f6cca221426fd4ddf8 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Sat, 23 Nov 2024 04:51:52 +0100 Subject: [PATCH 1/9] FPS overload --- cpp/open3d/geometry/PointCloud.cpp | 12 +++++++++++- cpp/open3d/geometry/PointCloud.h | 11 +++++++++++ cpp/open3d/t/geometry/PointCloud.cpp | 16 +++++++++++++++- cpp/open3d/t/geometry/PointCloud.h | 10 ++++++++++ cpp/pybind/geometry/pointcloud.cpp | 13 ++++++++++++- cpp/pybind/t/geometry/pointcloud.cpp | 13 ++++++++++++- 6 files changed, 71 insertions(+), 4 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index 3c93f370395..4b86e86edb2 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -508,6 +508,12 @@ std::shared_ptr PointCloud::RandomDownSample( std::shared_ptr PointCloud::FarthestPointDownSample( size_t num_samples) const { + constexpr size_t start_index = 0; + return FarthestPointDownSample(num_samples, start_index); +} + +std::shared_ptr PointCloud::FarthestPointDownSample( + size_t num_samples, const size_t start_index) const { if (num_samples == 0) { return std::make_shared(); } else if (num_samples == points_.size()) { @@ -516,6 +522,10 @@ std::shared_ptr PointCloud::FarthestPointDownSample( utility::LogError( "Illegal number of samples: {}, must <= point size: {}", num_samples, points_.size()); + } else if (start_index >= points_.size()) { + utility::LogError( + "Illegal start index: {}, must < point size: {}", + start_index, points_.size()); } // We can also keep track of the non-selected indices with unordered_set, // but since typically num_samples << num_points, it may not be worth it. @@ -524,7 +534,7 @@ std::shared_ptr PointCloud::FarthestPointDownSample( const size_t num_points = points_.size(); std::vector distances(num_points, std::numeric_limits::infinity()); - size_t farthest_index = 0; + size_t farthest_index = start_index; for (size_t i = 0; i < num_samples; i++) { selected_indices.push_back(farthest_index); const Eigen::Vector3d &selected = points_[farthest_index]; diff --git a/cpp/open3d/geometry/PointCloud.h b/cpp/open3d/geometry/PointCloud.h index 32afbc34653..c84f812f8f6 100644 --- a/cpp/open3d/geometry/PointCloud.h +++ b/cpp/open3d/geometry/PointCloud.h @@ -179,6 +179,17 @@ class PointCloud : public Geometry3D { std::shared_ptr FarthestPointDownSample( size_t num_samples) const; + /// \brief Function to downsample input pointcloud into output pointcloud + /// with a set of points has farthest distance. + /// + /// The sample is performed by selecting the farthest point from previous + /// selected points iteratively, starting from `start_index`. + /// + /// \param num_samples Number of points to be sampled. + /// \param start_index Index to start downsampling from. + std::shared_ptr FarthestPointDownSample( + size_t num_samples, const size_t start_index) const; + /// \brief Function to crop pointcloud into output pointcloud /// /// All points with coordinates outside the bounding box \p bbox are diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index 032a13d3437..1564d096702 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -385,6 +385,12 @@ PointCloud PointCloud::RandomDownSample(double sampling_ratio) const { } PointCloud PointCloud::FarthestPointDownSample(size_t num_samples) const { + constexpr size_t start_index = 0; + return FarthestPointDownSample(num_samples, start_index); +} + +PointCloud PointCloud::FarthestPointDownSample( + size_t num_samples, const size_t start_index) const { const core::Dtype dtype = GetPointPositions().GetDtype(); const int64_t num_points = GetPointPositions().GetLength(); if (num_samples == 0) { @@ -395,6 +401,14 @@ PointCloud PointCloud::FarthestPointDownSample(size_t num_samples) const { utility::LogError( "Illegal number of samples: {}, must <= point size: {}", num_samples, num_points); + } else if (start_index >= size_t(num_points)) { + utility::LogError( + "Illegal start index: {}, must <= point size: {}", + start_index, num_points); + } else if (start_index > static_cast(std::numeric_limits::max())) { + utility::LogError( + "Illegal start index: {}, must <= int64_t max: {}", + start_index, std::numeric_limits::max()); } core::Tensor selection_mask = core::Tensor::Zeros({num_points}, core::Bool, GetDevice()); @@ -402,7 +416,7 @@ PointCloud PointCloud::FarthestPointDownSample(size_t num_samples) const { {num_points}, std::numeric_limits::infinity(), dtype, GetDevice()); - int64_t farthest_index = 0; + int64_t farthest_index = static_cast(start_index); for (size_t i = 0; i < num_samples; i++) { selection_mask[farthest_index] = true; diff --git a/cpp/open3d/t/geometry/PointCloud.h b/cpp/open3d/t/geometry/PointCloud.h index 4cc0ba87ff7..eb5a3a6f673 100644 --- a/cpp/open3d/t/geometry/PointCloud.h +++ b/cpp/open3d/t/geometry/PointCloud.h @@ -357,6 +357,16 @@ class PointCloud : public Geometry, public DrawableGeometry { /// \param num_samples Number of points to be sampled. PointCloud FarthestPointDownSample(size_t num_samples) const; + /// \brief Downsample a pointcloud into output pointcloud with a set of + /// points has farthest distance. + /// + /// The sampling is performed by selecting the farthest point from previous + /// selected points iteratively, starting from `start_index`. + /// + /// \param num_samples Number of points to be sampled. + /// \param start_index Index to start downsampling from. + PointCloud FarthestPointDownSample(size_t num_samples, const size_t start_index) const; + /// \brief Remove points that have less than \p nb_points neighbors in a /// sphere of a given radius. /// diff --git a/cpp/pybind/geometry/pointcloud.cpp b/cpp/pybind/geometry/pointcloud.cpp index 42ca23e7b4f..6be6c5990d8 100644 --- a/cpp/pybind/geometry/pointcloud.cpp +++ b/cpp/pybind/geometry/pointcloud.cpp @@ -85,12 +85,23 @@ void pybind_pointcloud_definitions(py::module &m) { "sampling the indexes from the point cloud.", "sampling_ratio"_a) .def("farthest_point_down_sample", - &PointCloud::FarthestPointDownSample, + py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), "Downsamples input pointcloud into output pointcloud with a " "set of points has farthest distance. The sample is performed " "by selecting the farthest point from previous selected " "points iteratively.", "num_samples"_a) + .def("farthest_point_down_sample", + py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + "Downsamples input pointcloud into output pointcloud with a " + "set of points has farthest distance. The sample is performed " + "by selecting the farthest point from previous selected " + "points iteratively.", + "num_samples"_a, + "Index to start downsampling from. Valid index is a " + "non-negative number less than number of points in the " + "input pointcloud.", + "start_index"_a) .def("crop", (std::shared_ptr(PointCloud::*)( const AxisAlignedBoundingBox &, bool) const) & diff --git a/cpp/pybind/t/geometry/pointcloud.cpp b/cpp/pybind/t/geometry/pointcloud.cpp index 10a5735389c..3e6a599be06 100644 --- a/cpp/pybind/t/geometry/pointcloud.cpp +++ b/cpp/pybind/t/geometry/pointcloud.cpp @@ -251,12 +251,23 @@ void pybind_pointcloud_definitions(py::module& m) { "and its attributes.", "sampling_ratio"_a); pointcloud.def("farthest_point_down_sample", - &PointCloud::FarthestPointDownSample, + py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), "Downsample a pointcloud into output pointcloud with a set " "of points has farthest distance.The sampling is performed " "by selecting the farthest point from previous selected " "points iteratively", "num_samples"_a); + pointcloud.def("farthest_point_down_sample", + py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + "Downsample a pointcloud into output pointcloud with a set " + "of points has farthest distance.The sampling is performed " + "by selecting the farthest point from previous selected " + "points iteratively", + "num_samples"_a, + "Index to start downsampling from. Valid index is a " + "non-negative number less than number of points in the " + "input pointcloud.", + "start_index"_a); pointcloud.def("remove_radius_outliers", &PointCloud::RemoveRadiusOutliers, "nb_points"_a, "search_radius"_a, R"(Remove points that have less than nb_points neighbors in a From 482f720432d51780ed285cf22dee03fc0b569eef Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Mon, 25 Nov 2024 17:28:38 +0100 Subject: [PATCH 2/9] namespace tests ends later down below --- cpp/tests/geometry/PointCloud.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index 0a8d56d9890..67393adb072 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -882,7 +882,7 @@ TEST(PointCloud, FarthestPointDownSample) { {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}})); -} // namespace tests +} TEST(PointCloud, Crop_AxisAlignedBoundingBox) { geometry::AxisAlignedBoundingBox aabb({0, 0, 0}, {2, 2, 2}); From e8887315224fff877d7024ca899ba2c98306818c Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Mon, 25 Nov 2024 21:16:01 +0100 Subject: [PATCH 3/9] FPS overload tests --- cpp/tests/geometry/PointCloud.cpp | 12 ++++++++---- cpp/tests/t/geometry/PointCloud.cpp | 11 +++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index 67393adb072..0920f738729 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -876,12 +876,16 @@ TEST(PointCloud, FarthestPointDownSample) { {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, 1.0, 1.5}}); + std::vector expected = {{0, 2.0, 0}, + {1.0, 1.0, 0}, + {1.0, 0, 1.0}, + {0, 1.0, 1.0}}; std::shared_ptr pcd_down = pcd.FarthestPointDownSample(4); - ExpectEQ(pcd_down->points_, std::vector({{0, 2.0, 0}, - {1.0, 1.0, 0}, - {1.0, 0, 1.0}, - {0, 1.0, 1.0}})); + std::shared_ptr pcd_down_2 = + pcd.FarthestPointDownSample(4, 0); + ExpectEQ(pcd_down->points_, expected); + ExpectEQ(pcd_down_2->points_, expected); } TEST(PointCloud, Crop_AxisAlignedBoundingBox) { diff --git a/cpp/tests/t/geometry/PointCloud.cpp b/cpp/tests/t/geometry/PointCloud.cpp index 8abf761acdb..0a27cef788f 100644 --- a/cpp/tests/t/geometry/PointCloud.cpp +++ b/cpp/tests/t/geometry/PointCloud.cpp @@ -954,11 +954,14 @@ TEST_P(PointCloudPermuteDevices, FarthestPointDownSample) { {0, 1.0, 1.0}, {1.0, 1.0, 1.5}}, device)); - auto pcd_small_down = pcd_small.FarthestPointDownSample(4); - EXPECT_TRUE(pcd_small_down.GetPointPositions().AllClose( - core::Tensor::Init( + + auto expected = core::Tensor::Init( {{0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}, - device))); + device); + auto pcd_small_down = pcd_small.FarthestPointDownSample(4); + auto pcd_small_down_2 = pcd_small.FarthestPointDownSample(4, 0); + EXPECT_TRUE(pcd_small_down.GetPointPositions().AllClose(expected)); + EXPECT_TRUE(pcd_small_down_2.GetPointPositions().AllClose(expected)); } TEST_P(PointCloudPermuteDevices, RemoveRadiusOutliers) { From 83bcad61ab9546a63a633482f65546e1c3710c77 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Mon, 25 Nov 2024 21:41:42 +0100 Subject: [PATCH 4/9] FPS input args can be const --- cpp/open3d/geometry/PointCloud.cpp | 4 ++-- cpp/open3d/geometry/PointCloud.h | 4 ++-- cpp/open3d/t/geometry/PointCloud.cpp | 4 ++-- cpp/open3d/t/geometry/PointCloud.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index 4b86e86edb2..32f8df1b767 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -507,13 +507,13 @@ std::shared_ptr PointCloud::RandomDownSample( } std::shared_ptr PointCloud::FarthestPointDownSample( - size_t num_samples) const { + const size_t num_samples) const { constexpr size_t start_index = 0; return FarthestPointDownSample(num_samples, start_index); } std::shared_ptr PointCloud::FarthestPointDownSample( - size_t num_samples, const size_t start_index) const { + const size_t num_samples, const size_t start_index) const { if (num_samples == 0) { return std::make_shared(); } else if (num_samples == points_.size()) { diff --git a/cpp/open3d/geometry/PointCloud.h b/cpp/open3d/geometry/PointCloud.h index c84f812f8f6..1f6eab37915 100644 --- a/cpp/open3d/geometry/PointCloud.h +++ b/cpp/open3d/geometry/PointCloud.h @@ -177,7 +177,7 @@ class PointCloud : public Geometry3D { /// /// \param num_samples Number of points to be sampled. std::shared_ptr FarthestPointDownSample( - size_t num_samples) const; + const size_t num_samples) const; /// \brief Function to downsample input pointcloud into output pointcloud /// with a set of points has farthest distance. @@ -188,7 +188,7 @@ class PointCloud : public Geometry3D { /// \param num_samples Number of points to be sampled. /// \param start_index Index to start downsampling from. std::shared_ptr FarthestPointDownSample( - size_t num_samples, const size_t start_index) const; + const size_t num_samples, const size_t start_index) const; /// \brief Function to crop pointcloud into output pointcloud /// diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index 1564d096702..bd2e2f4b7d7 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -384,13 +384,13 @@ PointCloud PointCloud::RandomDownSample(double sampling_ratio) const { false, false); } -PointCloud PointCloud::FarthestPointDownSample(size_t num_samples) const { +PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples) const { constexpr size_t start_index = 0; return FarthestPointDownSample(num_samples, start_index); } PointCloud PointCloud::FarthestPointDownSample( - size_t num_samples, const size_t start_index) const { + const size_t num_samples, const size_t start_index) const { const core::Dtype dtype = GetPointPositions().GetDtype(); const int64_t num_points = GetPointPositions().GetLength(); if (num_samples == 0) { diff --git a/cpp/open3d/t/geometry/PointCloud.h b/cpp/open3d/t/geometry/PointCloud.h index eb5a3a6f673..b3220e87988 100644 --- a/cpp/open3d/t/geometry/PointCloud.h +++ b/cpp/open3d/t/geometry/PointCloud.h @@ -355,7 +355,7 @@ class PointCloud : public Geometry, public DrawableGeometry { /// selected points iteratively. /// /// \param num_samples Number of points to be sampled. - PointCloud FarthestPointDownSample(size_t num_samples) const; + PointCloud FarthestPointDownSample(const size_t num_samples) const; /// \brief Downsample a pointcloud into output pointcloud with a set of /// points has farthest distance. @@ -365,7 +365,7 @@ class PointCloud : public Geometry, public DrawableGeometry { /// /// \param num_samples Number of points to be sampled. /// \param start_index Index to start downsampling from. - PointCloud FarthestPointDownSample(size_t num_samples, const size_t start_index) const; + PointCloud FarthestPointDownSample(const size_t num_samples, const size_t start_index) const; /// \brief Remove points that have less than \p nb_points neighbors in a /// sphere of a given radius. From e64d67862447f4abba231ed2401f5a7dbfff8339 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Mon, 25 Nov 2024 21:46:26 +0100 Subject: [PATCH 5/9] update FPS docstring --- cpp/pybind/t/geometry/pointcloud.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/pybind/t/geometry/pointcloud.cpp b/cpp/pybind/t/geometry/pointcloud.cpp index 3e6a599be06..e0547753359 100644 --- a/cpp/pybind/t/geometry/pointcloud.cpp +++ b/cpp/pybind/t/geometry/pointcloud.cpp @@ -667,7 +667,8 @@ The implementation is inspired by the PCL implementation. Reference: "in the pointcloud."}}); docstring::ClassMethodDocInject( m, "PointCloud", "farthest_point_down_sample", - {{"num_samples", "Number of points to be sampled."}}); + {{"num_samples", "Number of points to be sampled."}, + {"start_index", "Index of point to start downsampling from."}}); docstring::ClassMethodDocInject( m, "PointCloud", "remove_radius_outliers", {{"nb_points", From 9dbe9c9a426141812ee3955725ff6d1dd1d06f89 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Mon, 25 Nov 2024 22:28:36 +0100 Subject: [PATCH 6/9] FPS style guide compliance --- cpp/open3d/geometry/PointCloud.cpp | 5 ++--- cpp/open3d/t/geometry/PointCloud.cpp | 17 ++++++++--------- cpp/open3d/t/geometry/PointCloud.h | 3 ++- cpp/pybind/geometry/pointcloud.cpp | 6 ++++-- cpp/pybind/t/geometry/pointcloud.cpp | 6 ++++-- cpp/tests/geometry/PointCloud.cpp | 6 ++---- cpp/tests/t/geometry/PointCloud.cpp | 3 +-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index 32f8df1b767..b1da4855416 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -523,9 +523,8 @@ std::shared_ptr PointCloud::FarthestPointDownSample( "Illegal number of samples: {}, must <= point size: {}", num_samples, points_.size()); } else if (start_index >= points_.size()) { - utility::LogError( - "Illegal start index: {}, must < point size: {}", - start_index, points_.size()); + utility::LogError("Illegal start index: {}, must < point size: {}", + start_index, points_.size()); } // We can also keep track of the non-selected indices with unordered_set, // but since typically num_samples << num_points, it may not be worth it. diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index bd2e2f4b7d7..0665e4f4c62 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -389,8 +389,8 @@ PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples) const { return FarthestPointDownSample(num_samples, start_index); } -PointCloud PointCloud::FarthestPointDownSample( - const size_t num_samples, const size_t start_index) const { +PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples, + const size_t start_index) const { const core::Dtype dtype = GetPointPositions().GetDtype(); const int64_t num_points = GetPointPositions().GetLength(); if (num_samples == 0) { @@ -402,13 +402,12 @@ PointCloud PointCloud::FarthestPointDownSample( "Illegal number of samples: {}, must <= point size: {}", num_samples, num_points); } else if (start_index >= size_t(num_points)) { - utility::LogError( - "Illegal start index: {}, must <= point size: {}", - start_index, num_points); - } else if (start_index > static_cast(std::numeric_limits::max())) { - utility::LogError( - "Illegal start index: {}, must <= int64_t max: {}", - start_index, std::numeric_limits::max()); + utility::LogError("Illegal start index: {}, must <= point size: {}", + start_index, num_points); + } else if (start_index > + static_cast(std::numeric_limits::max())) { + utility::LogError("Illegal start index: {}, must <= int64_t max: {}", + start_index, std::numeric_limits::max()); } core::Tensor selection_mask = core::Tensor::Zeros({num_points}, core::Bool, GetDevice()); diff --git a/cpp/open3d/t/geometry/PointCloud.h b/cpp/open3d/t/geometry/PointCloud.h index b3220e87988..03ab04fa5e5 100644 --- a/cpp/open3d/t/geometry/PointCloud.h +++ b/cpp/open3d/t/geometry/PointCloud.h @@ -365,7 +365,8 @@ class PointCloud : public Geometry, public DrawableGeometry { /// /// \param num_samples Number of points to be sampled. /// \param start_index Index to start downsampling from. - PointCloud FarthestPointDownSample(const size_t num_samples, const size_t start_index) const; + PointCloud FarthestPointDownSample(const size_t num_samples, + const size_t start_index) const; /// \brief Remove points that have less than \p nb_points neighbors in a /// sphere of a given radius. diff --git a/cpp/pybind/geometry/pointcloud.cpp b/cpp/pybind/geometry/pointcloud.cpp index 6be6c5990d8..56873d78e1f 100644 --- a/cpp/pybind/geometry/pointcloud.cpp +++ b/cpp/pybind/geometry/pointcloud.cpp @@ -85,14 +85,16 @@ void pybind_pointcloud_definitions(py::module &m) { "sampling the indexes from the point cloud.", "sampling_ratio"_a) .def("farthest_point_down_sample", - py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + py::overload_cast(&PointCloud::FarthestPointDownSample, + py::const_), "Downsamples input pointcloud into output pointcloud with a " "set of points has farthest distance. The sample is performed " "by selecting the farthest point from previous selected " "points iteratively.", "num_samples"_a) .def("farthest_point_down_sample", - py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + py::overload_cast( + &PointCloud::FarthestPointDownSample, py::const_), "Downsamples input pointcloud into output pointcloud with a " "set of points has farthest distance. The sample is performed " "by selecting the farthest point from previous selected " diff --git a/cpp/pybind/t/geometry/pointcloud.cpp b/cpp/pybind/t/geometry/pointcloud.cpp index e0547753359..acd5181ce68 100644 --- a/cpp/pybind/t/geometry/pointcloud.cpp +++ b/cpp/pybind/t/geometry/pointcloud.cpp @@ -251,14 +251,16 @@ void pybind_pointcloud_definitions(py::module& m) { "and its attributes.", "sampling_ratio"_a); pointcloud.def("farthest_point_down_sample", - py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + py::overload_cast( + &PointCloud::FarthestPointDownSample, py::const_), "Downsample a pointcloud into output pointcloud with a set " "of points has farthest distance.The sampling is performed " "by selecting the farthest point from previous selected " "points iteratively", "num_samples"_a); pointcloud.def("farthest_point_down_sample", - py::overload_cast(&PointCloud::FarthestPointDownSample, py::const_), + py::overload_cast( + &PointCloud::FarthestPointDownSample, py::const_), "Downsample a pointcloud into output pointcloud with a set " "of points has farthest distance.The sampling is performed " "by selecting the farthest point from previous selected " diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index 0920f738729..bce6fa2c771 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -876,10 +876,8 @@ TEST(PointCloud, FarthestPointDownSample) { {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, 1.0, 1.5}}); - std::vector expected = {{0, 2.0, 0}, - {1.0, 1.0, 0}, - {1.0, 0, 1.0}, - {0, 1.0, 1.0}}; + std::vector expected = { + {0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}; std::shared_ptr pcd_down = pcd.FarthestPointDownSample(4); std::shared_ptr pcd_down_2 = diff --git a/cpp/tests/t/geometry/PointCloud.cpp b/cpp/tests/t/geometry/PointCloud.cpp index 0a27cef788f..d6f41f94888 100644 --- a/cpp/tests/t/geometry/PointCloud.cpp +++ b/cpp/tests/t/geometry/PointCloud.cpp @@ -956,8 +956,7 @@ TEST_P(PointCloudPermuteDevices, FarthestPointDownSample) { device)); auto expected = core::Tensor::Init( - {{0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}, - device); + {{0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}, device); auto pcd_small_down = pcd_small.FarthestPointDownSample(4); auto pcd_small_down_2 = pcd_small.FarthestPointDownSample(4, 0); EXPECT_TRUE(pcd_small_down.GetPointPositions().AllClose(expected)); From 8f25cb8b99feaa548fea5ebeedbff8aa5bcfa752 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Sat, 30 Nov 2024 18:56:53 +0100 Subject: [PATCH 7/9] default value instead of overload --- cpp/open3d/geometry/PointCloud.cpp | 6 ------ cpp/open3d/geometry/PointCloud.h | 12 +----------- cpp/open3d/t/geometry/PointCloud.cpp | 5 ----- cpp/open3d/t/geometry/PointCloud.h | 11 +---------- cpp/pybind/geometry/pointcloud.cpp | 13 ++----------- cpp/pybind/t/geometry/pointcloud.cpp | 13 ++----------- 6 files changed, 6 insertions(+), 54 deletions(-) diff --git a/cpp/open3d/geometry/PointCloud.cpp b/cpp/open3d/geometry/PointCloud.cpp index b1da4855416..12da953bb11 100644 --- a/cpp/open3d/geometry/PointCloud.cpp +++ b/cpp/open3d/geometry/PointCloud.cpp @@ -506,12 +506,6 @@ std::shared_ptr PointCloud::RandomDownSample( return SelectByIndex(indices); } -std::shared_ptr PointCloud::FarthestPointDownSample( - const size_t num_samples) const { - constexpr size_t start_index = 0; - return FarthestPointDownSample(num_samples, start_index); -} - std::shared_ptr PointCloud::FarthestPointDownSample( const size_t num_samples, const size_t start_index) const { if (num_samples == 0) { diff --git a/cpp/open3d/geometry/PointCloud.h b/cpp/open3d/geometry/PointCloud.h index 1f6eab37915..e55d89e4b88 100644 --- a/cpp/open3d/geometry/PointCloud.h +++ b/cpp/open3d/geometry/PointCloud.h @@ -169,16 +169,6 @@ class PointCloud : public Geometry3D { /// number of points in the pointcloud. std::shared_ptr RandomDownSample(double sampling_ratio) const; - /// \brief Function to downsample input pointcloud into output pointcloud - /// with a set of points has farthest distance. - /// - /// The sample is performed by selecting the farthest point from previous - /// selected points iteratively. - /// - /// \param num_samples Number of points to be sampled. - std::shared_ptr FarthestPointDownSample( - const size_t num_samples) const; - /// \brief Function to downsample input pointcloud into output pointcloud /// with a set of points has farthest distance. /// @@ -188,7 +178,7 @@ class PointCloud : public Geometry3D { /// \param num_samples Number of points to be sampled. /// \param start_index Index to start downsampling from. std::shared_ptr FarthestPointDownSample( - const size_t num_samples, const size_t start_index) const; + const size_t num_samples, const size_t start_index = 0) const; /// \brief Function to crop pointcloud into output pointcloud /// diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index 0665e4f4c62..3cc2a5cc3f5 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -384,11 +384,6 @@ PointCloud PointCloud::RandomDownSample(double sampling_ratio) const { false, false); } -PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples) const { - constexpr size_t start_index = 0; - return FarthestPointDownSample(num_samples, start_index); -} - PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples, const size_t start_index) const { const core::Dtype dtype = GetPointPositions().GetDtype(); diff --git a/cpp/open3d/t/geometry/PointCloud.h b/cpp/open3d/t/geometry/PointCloud.h index 03ab04fa5e5..2dff4e6aa9f 100644 --- a/cpp/open3d/t/geometry/PointCloud.h +++ b/cpp/open3d/t/geometry/PointCloud.h @@ -348,15 +348,6 @@ class PointCloud : public Geometry, public DrawableGeometry { /// number of points in the pointcloud. PointCloud RandomDownSample(double sampling_ratio) const; - /// \brief Downsample a pointcloud into output pointcloud with a set of - /// points has farthest distance. - /// - /// The sampling is performed by selecting the farthest point from previous - /// selected points iteratively. - /// - /// \param num_samples Number of points to be sampled. - PointCloud FarthestPointDownSample(const size_t num_samples) const; - /// \brief Downsample a pointcloud into output pointcloud with a set of /// points has farthest distance. /// @@ -366,7 +357,7 @@ class PointCloud : public Geometry, public DrawableGeometry { /// \param num_samples Number of points to be sampled. /// \param start_index Index to start downsampling from. PointCloud FarthestPointDownSample(const size_t num_samples, - const size_t start_index) const; + const size_t start_index = 0) const; /// \brief Remove points that have less than \p nb_points neighbors in a /// sphere of a given radius. diff --git a/cpp/pybind/geometry/pointcloud.cpp b/cpp/pybind/geometry/pointcloud.cpp index 56873d78e1f..2dbb4c741d3 100644 --- a/cpp/pybind/geometry/pointcloud.cpp +++ b/cpp/pybind/geometry/pointcloud.cpp @@ -85,16 +85,7 @@ void pybind_pointcloud_definitions(py::module &m) { "sampling the indexes from the point cloud.", "sampling_ratio"_a) .def("farthest_point_down_sample", - py::overload_cast(&PointCloud::FarthestPointDownSample, - py::const_), - "Downsamples input pointcloud into output pointcloud with a " - "set of points has farthest distance. The sample is performed " - "by selecting the farthest point from previous selected " - "points iteratively.", - "num_samples"_a) - .def("farthest_point_down_sample", - py::overload_cast( - &PointCloud::FarthestPointDownSample, py::const_), + &PointCloud::FarthestPointDownSample, "Downsamples input pointcloud into output pointcloud with a " "set of points has farthest distance. The sample is performed " "by selecting the farthest point from previous selected " @@ -103,7 +94,7 @@ void pybind_pointcloud_definitions(py::module &m) { "Index to start downsampling from. Valid index is a " "non-negative number less than number of points in the " "input pointcloud.", - "start_index"_a) + "start_index"_a = 0) .def("crop", (std::shared_ptr(PointCloud::*)( const AxisAlignedBoundingBox &, bool) const) & diff --git a/cpp/pybind/t/geometry/pointcloud.cpp b/cpp/pybind/t/geometry/pointcloud.cpp index acd5181ce68..fb5cb244028 100644 --- a/cpp/pybind/t/geometry/pointcloud.cpp +++ b/cpp/pybind/t/geometry/pointcloud.cpp @@ -251,16 +251,7 @@ void pybind_pointcloud_definitions(py::module& m) { "and its attributes.", "sampling_ratio"_a); pointcloud.def("farthest_point_down_sample", - py::overload_cast( - &PointCloud::FarthestPointDownSample, py::const_), - "Downsample a pointcloud into output pointcloud with a set " - "of points has farthest distance.The sampling is performed " - "by selecting the farthest point from previous selected " - "points iteratively", - "num_samples"_a); - pointcloud.def("farthest_point_down_sample", - py::overload_cast( - &PointCloud::FarthestPointDownSample, py::const_), + &PointCloud::FarthestPointDownSample, "Downsample a pointcloud into output pointcloud with a set " "of points has farthest distance.The sampling is performed " "by selecting the farthest point from previous selected " @@ -269,7 +260,7 @@ void pybind_pointcloud_definitions(py::module& m) { "Index to start downsampling from. Valid index is a " "non-negative number less than number of points in the " "input pointcloud.", - "start_index"_a); + "start_index"_a = 0); pointcloud.def("remove_radius_outliers", &PointCloud::RemoveRadiusOutliers, "nb_points"_a, "search_radius"_a, R"(Remove points that have less than nb_points neighbors in a From cdc00cb2f2baa9353537113675ed42e865dd0bf6 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Sat, 30 Nov 2024 19:03:06 +0100 Subject: [PATCH 8/9] overflow check not needed --- cpp/open3d/t/geometry/PointCloud.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cpp/open3d/t/geometry/PointCloud.cpp b/cpp/open3d/t/geometry/PointCloud.cpp index 3cc2a5cc3f5..9b48eea0170 100644 --- a/cpp/open3d/t/geometry/PointCloud.cpp +++ b/cpp/open3d/t/geometry/PointCloud.cpp @@ -399,10 +399,6 @@ PointCloud PointCloud::FarthestPointDownSample(const size_t num_samples, } else if (start_index >= size_t(num_points)) { utility::LogError("Illegal start index: {}, must <= point size: {}", start_index, num_points); - } else if (start_index > - static_cast(std::numeric_limits::max())) { - utility::LogError("Illegal start index: {}, must <= int64_t max: {}", - start_index, std::numeric_limits::max()); } core::Tensor selection_mask = core::Tensor::Zeros({num_points}, core::Bool, GetDevice()); From 9f7627d6d01c209be44c695ed905cd2d84678ef8 Mon Sep 17 00:00:00 2001 From: Abhishek Kashyap Date: Sat, 30 Nov 2024 20:02:24 +0100 Subject: [PATCH 9/9] updated FPS tests --- cpp/tests/geometry/PointCloud.cpp | 12 ++++++++---- cpp/tests/t/geometry/PointCloud.cpp | 10 +++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cpp/tests/geometry/PointCloud.cpp b/cpp/tests/geometry/PointCloud.cpp index bce6fa2c771..64e1bee0248 100644 --- a/cpp/tests/geometry/PointCloud.cpp +++ b/cpp/tests/geometry/PointCloud.cpp @@ -876,14 +876,18 @@ TEST(PointCloud, FarthestPointDownSample) { {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, 1.0, 1.5}}); - std::vector expected = { - {0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}; std::shared_ptr pcd_down = pcd.FarthestPointDownSample(4); + std::vector expected = { + {0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}; + std::shared_ptr pcd_down_2 = - pcd.FarthestPointDownSample(4, 0); + pcd.FarthestPointDownSample(4, 4); + std::vector expected_2 = { + {0, 2.0, 0}, {1.0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.5}}; + ExpectEQ(pcd_down->points_, expected); - ExpectEQ(pcd_down_2->points_, expected); + ExpectEQ(pcd_down_2->points_, expected_2); } TEST(PointCloud, Crop_AxisAlignedBoundingBox) { diff --git a/cpp/tests/t/geometry/PointCloud.cpp b/cpp/tests/t/geometry/PointCloud.cpp index d6f41f94888..2a74c9c75c1 100644 --- a/cpp/tests/t/geometry/PointCloud.cpp +++ b/cpp/tests/t/geometry/PointCloud.cpp @@ -955,12 +955,16 @@ TEST_P(PointCloudPermuteDevices, FarthestPointDownSample) { {1.0, 1.0, 1.5}}, device)); + auto pcd_small_down = pcd_small.FarthestPointDownSample(4); auto expected = core::Tensor::Init( {{0, 2.0, 0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}}, device); - auto pcd_small_down = pcd_small.FarthestPointDownSample(4); - auto pcd_small_down_2 = pcd_small.FarthestPointDownSample(4, 0); + + auto pcd_small_down_2 = pcd_small.FarthestPointDownSample(4, 4); + auto expected_2 = core::Tensor::Init( + {{0, 2.0, 0}, {1.0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.5}}, device); + EXPECT_TRUE(pcd_small_down.GetPointPositions().AllClose(expected)); - EXPECT_TRUE(pcd_small_down_2.GetPointPositions().AllClose(expected)); + EXPECT_TRUE(pcd_small_down_2.GetPointPositions().AllClose(expected_2)); } TEST_P(PointCloudPermuteDevices, RemoveRadiusOutliers) {