Skip to content

Commit

Permalink
Tensor PointCloud RemoveDuplicatedPoints (#5311)
Browse files Browse the repository at this point in the history
  • Loading branch information
reyanshsolis authored Aug 26, 2022
1 parent ea9ab1f commit 6805e74
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 0 deletions.
12 changes: 12 additions & 0 deletions cpp/open3d/core/Tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,18 @@ Tensor& Tensor::operator=(Tensor&& other) && {
return *this;
}

Tensor Tensor::ReinterpretCast(const core::Dtype& dtype) const {
if (dtype_.ByteSize() != dtype.ByteSize()) {
utility::LogError(
"Cannot reinterpret cast between data-types of different "
"sizes. Expected data-type of {} bytes ({}), but got "
"data-type {} of {} bytes.",
dtype_.ByteSize(), dtype_.ToString(), dtype.ToString(),
dtype.ByteSize());
}
return Tensor(shape_, strides_, data_ptr_, dtype, blob_);
}

Tensor Tensor::Empty(const SizeVector& shape,
Dtype dtype,
const Device& device) {
Expand Down
6 changes: 6 additions & 0 deletions cpp/open3d/core/Tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ class Tensor : public IsDevice {
return *this;
}

/// Tensor reinterpret cast operator.
/// It changes the tensor's dtype without changing the underlying memory
/// blob itself. The byte-size of dtype must be same as the original dtype
/// before casting.
Tensor ReinterpretCast(const core::Dtype& dtype) const;

/// Assign an object to a tensor. The tensor being assigned to must be a
/// scalar tensor of shape {}. The element byte size of the tensor must be
/// the same as the size of the object. The object must be a POD.
Expand Down
22 changes: 22 additions & 0 deletions cpp/open3d/t/geometry/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,28 @@ std::tuple<PointCloud, core::Tensor> PointCloud::RemoveNonFinitePoints(
finite_indices_mask);
}

std::tuple<PointCloud, core::Tensor> PointCloud::RemoveDuplicatedPoints()
const {
core::Tensor points_voxeli;
const core::Dtype dtype = GetPointPositions().GetDtype();
if (dtype.ByteSize() == 4) {
points_voxeli = GetPointPositions().ReinterpretCast(core::Int32);
} else if (dtype.ByteSize() == 8) {
points_voxeli = GetPointPositions().ReinterpretCast(core::Int64);
} else {
utility::LogError(
"Unsupported point position data-type. Only support "
"Int32, Int64, Float32 and Float64.");
}

core::HashSet points_voxeli_hashset(points_voxeli.GetLength(),
points_voxeli.GetDtype(), {3}, device_);
core::Tensor buf_indices, masks;
points_voxeli_hashset.Insert(points_voxeli, buf_indices, masks);

return std::make_tuple(SelectByMask(masks), masks);
}

PointCloud PointCloud::PaintUniformColor(const core::Tensor &color) const {
core::AssertTensorShape(color, {3});
core::Tensor clipped_color = color.To(GetDevice());
Expand Down
6 changes: 6 additions & 0 deletions cpp/open3d/t/geometry/PointCloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ class PointCloud : public Geometry, public DrawableGeometry {
std::tuple<PointCloud, core::Tensor> RemoveRadiusOutliers(
size_t nb_points, double search_radius) const;

/// \brief Remove duplicated points and there associated attributes.
///
/// \return tuple of filtered PointCloud and boolean indexing tensor w.r.t.
/// input point cloud.
std::tuple<PointCloud, core::Tensor> RemoveDuplicatedPoints() const;

/// \brief Remove all points from the point cloud that have a nan entry, or
/// infinite value. It also removes the corresponding attributes.
///
Expand Down
3 changes: 3 additions & 0 deletions cpp/pybind/t/geometry/pointcloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ The attributes of the point cloud have different levels::
"nb_points"_a, "search_radius"_a,
"Remove points that have less than nb_points neighbors in a "
"sphere of a given search radius.");
pointcloud.def("remove_duplicated_points",
&PointCloud::RemoveDuplicatedPoints,
"Remove duplicated points and there associated attributes.");
pointcloud.def(
"remove_non_finite_points", &PointCloud::RemoveNonFinitePoints,
"remove_nan"_a = true, "remove_infinite"_a = true,
Expand Down
25 changes: 25 additions & 0 deletions cpp/tests/t/geometry/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,31 @@ TEST_P(PointCloudPermuteDevices, RemoveRadiusOutliers) {
device)));
}

TEST_P(PointCloudPermuteDevices, RemoveDuplicatedPoints) {
core::Device device = GetParam();

const t::geometry::PointCloud pcd_small(
core::Tensor::Init<float>({{1.0, 1.0, 1.0},
{1.0, 1.0, 1.0},
{1.1, 1.1, 1.1},
{1.1, 1.1, 1.1},
{1.2, 1.2, 1.2},
{1.3, 1.3, 1.3}},
device));

t::geometry::PointCloud output_pcd;
core::Tensor selected_boolean_mask;
std::tie(output_pcd, selected_boolean_mask) =
pcd_small.RemoveDuplicatedPoints();

EXPECT_TRUE(output_pcd.GetPointPositions().AllClose(
core::Tensor::Init<float>({{1.0, 1.0, 1.0},
{1.1, 1.1, 1.1},
{1.2, 1.2, 1.2},
{1.3, 1.3, 1.3}},
device)));
}

TEST_P(PointCloudPermuteDevices, RemoveNonFinitePoints) {
core::Device device = GetParam();

Expand Down

0 comments on commit 6805e74

Please sign in to comment.