ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
PointCloud.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <Logging.h>
11 
12 #include <vector>
13 
17 
18 namespace cloudViewer {
19 namespace t {
20 namespace geometry {
21 namespace kernel {
22 namespace pointcloud {
23 
24 void Unproject(const core::Tensor& depth,
25  utility::optional<std::reference_wrapper<const core::Tensor>>
26  image_colors,
28  utility::optional<std::reference_wrapper<core::Tensor>> colors,
29  const core::Tensor& intrinsics,
30  const core::Tensor& extrinsics,
31  float depth_scale,
32  float depth_max,
33  int64_t stride) {
34  if (image_colors.has_value() != colors.has_value()) {
36  "Both or none of image_colors and colors must have values.");
37  }
38 
39  core::AssertTensorShape(intrinsics, {3, 3});
40  core::AssertTensorShape(extrinsics, {4, 4});
41 
42  static const core::Device host("CPU:0");
43  core::Tensor intrinsics_d = intrinsics.To(host, core::Float64).Contiguous();
44  core::Tensor extrinsics_d = extrinsics.To(host, core::Float64).Contiguous();
45 
46  const core::Device device = depth.GetDevice();
47 
48  if (image_colors.has_value()) {
49  core::AssertTensorDevice(image_colors.value(), device);
50  }
51 
52  if (depth.IsCPU()) {
53  UnprojectCPU(depth, image_colors, points, colors, intrinsics_d,
54  extrinsics_d, depth_scale, depth_max, stride);
55  } else if (depth.IsCUDA()) {
56  CUDA_CALL(UnprojectCUDA, depth, image_colors, points, colors,
57  intrinsics_d, extrinsics_d, depth_scale, depth_max, stride);
58  } else {
59  utility::LogError("Unimplemented device");
60  }
61 }
62 
63 void Project(
64  core::Tensor& depth,
65  utility::optional<std::reference_wrapper<core::Tensor>> image_colors,
66  const core::Tensor& points,
67  utility::optional<std::reference_wrapper<const core::Tensor>> colors,
68  const core::Tensor& intrinsics,
69  const core::Tensor& extrinsics,
70  float depth_scale,
71  float depth_max) {
72  if (image_colors.has_value() != colors.has_value()) {
74  "Both or none of image_colors and colors must have values.");
75  }
76 
77  core::AssertTensorShape(intrinsics, {3, 3});
78  core::AssertTensorShape(extrinsics, {4, 4});
79 
80  static const core::Device host("CPU:0");
81  core::Tensor intrinsics_d = intrinsics.To(host, core::Float64).Contiguous();
82  core::Tensor extrinsics_d = extrinsics.To(host, core::Float64).Contiguous();
83 
84  const core::Device device = depth.GetDevice();
85 
86  if (image_colors.has_value()) {
87  core::AssertTensorDevice(image_colors.value(), device);
88  }
89 
90  if (depth.IsCPU()) {
91  ProjectCPU(depth, image_colors, points, colors, intrinsics_d,
92  extrinsics_d, depth_scale, depth_max);
93  } else if (depth.IsCUDA()) {
94  CUDA_CALL(ProjectCUDA, depth, image_colors, points, colors,
95  intrinsics_d, extrinsics_d, depth_scale, depth_max);
96  } else {
97  utility::LogError("Unimplemented device");
98  }
99 }
100 
102  const core::Tensor& min_bound,
103  const core::Tensor& max_bound,
104  core::Tensor& mask) {
105  core::AssertTensorShape(min_bound, {3});
106  core::AssertTensorShape(max_bound, {3});
107  core::AssertTensorShape(mask, {points.GetLength()});
108  // Mask must be a bool tensor.
110 
111  // Convert points, min_bound and max_bound into contiguous Tensor.
112  const core::Tensor min_bound_d = min_bound.Contiguous();
113  const core::Tensor max_bound_d = max_bound.Contiguous();
114  const core::Tensor points_d = points.Contiguous();
115 
116  if (mask.IsCPU()) {
117  GetPointMaskWithinAABBCPU(points_d, min_bound_d, max_bound_d, mask);
118  } else if (mask.IsCUDA()) {
119  CUDA_CALL(GetPointMaskWithinAABBCUDA, points_d, min_bound_d,
120  max_bound_d, mask);
121  } else {
122  utility::LogError("Unimplemented device");
123  }
124 }
125 
127  const core::Tensor& center,
128  const core::Tensor& rotation,
129  const core::Tensor& extent,
130  core::Tensor& mask) {
131  core::AssertTensorShape(mask, {points.GetLength()});
133 
134  // Convert points, center, rotation and extent into contiguous Tensor.
135  const core::Tensor center_d = center.Contiguous();
136  const core::Tensor rotation_d = rotation.Contiguous();
137  const core::Tensor extent_d = extent.Contiguous();
138  const core::Tensor points_d = points.Contiguous();
139 
140  if (mask.IsCPU()) {
141  GetPointMaskWithinOBBCPU(points_d, center_d, rotation_d, extent_d,
142  mask);
143  } else if (mask.IsCUDA()) {
144  CUDA_CALL(GetPointMaskWithinOBBCUDA, points_d, center_d, rotation_d,
145  extent_d, mask);
146  } else {
147  utility::LogError("Unimplemented device");
148  }
149 }
150 
151 } // namespace pointcloud
152 } // namespace kernel
153 } // namespace geometry
154 } // namespace t
155 } // namespace cloudViewer
Common CUDA utilities.
#define CUDA_CALL(cuda_function,...)
Definition: CUDAUtils.h:49
int points
#define AssertTensorDevice(tensor,...)
Definition: TensorCheck.h:45
#define AssertTensorDtype(tensor,...)
Definition: TensorCheck.h:21
#define AssertTensorShape(tensor,...)
Definition: TensorCheck.h:61
size_t stride
bool IsCUDA() const
Definition: Device.h:99
bool IsCPU() const
Definition: Device.h:95
Tensor Contiguous() const
Definition: Tensor.cpp:772
Device GetDevice() const override
Definition: Tensor.cpp:1435
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:739
double colors[3]
#define LogError(...)
Definition: Logging.h:60
const Dtype Bool
Definition: Dtype.cpp:52
const Dtype Float64
Definition: Dtype.cpp:43
void Project(core::Tensor &depth, utility::optional< std::reference_wrapper< core::Tensor >> image_colors, const core::Tensor &points, utility::optional< std::reference_wrapper< const core::Tensor >> colors, const core::Tensor &intrinsics, const core::Tensor &extrinsics, float depth_scale, float depth_max)
Definition: PointCloud.cpp:63
void GetPointMaskWithinOBBCPU(const core::Tensor &points, const core::Tensor &center, const core::Tensor &rotation, const core::Tensor &extent, core::Tensor &mask)
void ProjectCPU(core::Tensor &depth, utility::optional< std::reference_wrapper< core::Tensor >> image_colors, const core::Tensor &points, utility::optional< std::reference_wrapper< const core::Tensor >> colors, const core::Tensor &intrinsics, const core::Tensor &extrinsics, float depth_scale, float depth_max)
void UnprojectCPU(const core::Tensor &depth, utility::optional< std::reference_wrapper< const core::Tensor >> image_colors, core::Tensor &points, utility::optional< std::reference_wrapper< core::Tensor >> colors, const core::Tensor &intrinsics, const core::Tensor &extrinsics, float depth_scale, float depth_max, int64_t stride)
void GetPointMaskWithinAABB(const core::Tensor &points, const core::Tensor &min_bound, const core::Tensor &max_bound, core::Tensor &mask)
Definition: PointCloud.cpp:101
void GetPointMaskWithinOBB(const core::Tensor &points, const core::Tensor &center, const core::Tensor &rotation, const core::Tensor &extent, core::Tensor &mask)
Definition: PointCloud.cpp:126
void Unproject(const core::Tensor &depth, utility::optional< std::reference_wrapper< const core::Tensor >> image_colors, core::Tensor &points, utility::optional< std::reference_wrapper< core::Tensor >> colors, const core::Tensor &intrinsics, const core::Tensor &extrinsics, float depth_scale, float depth_max, int64_t stride)
Definition: PointCloud.cpp:24
void GetPointMaskWithinAABBCPU(const core::Tensor &points, const core::Tensor &min_bound, const core::Tensor &max_bound, core::Tensor &mask)
Generic file read and write utility for python interface.