Open3D (C++ API)  0.13.0
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
PointCloudImpl.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26 
27 #include <atomic>
28 #include <vector>
29 
30 #include "open3d/core/Dispatch.h"
31 #include "open3d/core/Dtype.h"
33 #include "open3d/core/SizeVector.h"
34 #include "open3d/core/Tensor.h"
39 #include "open3d/utility/Console.h"
40 #include "open3d/utility/Timer.h"
41 
42 namespace open3d {
43 namespace t {
44 namespace geometry {
45 namespace kernel {
46 namespace pointcloud {
47 
48 #if defined(__CUDACC__)
49 void UnprojectCUDA
50 #else
51 void UnprojectCPU
52 #endif
53  (const core::Tensor& depth,
55  image_colors,
58  const core::Tensor& intrinsics,
59  const core::Tensor& extrinsics,
60  float depth_scale,
61  float depth_max,
62  int64_t stride) {
63 
64  const bool have_colors = image_colors.has_value();
65  NDArrayIndexer depth_indexer(depth, 2);
66  NDArrayIndexer image_colors_indexer;
67 
69  TransformIndexer ti(intrinsics, pose, 1.0f);
70 
71  // Output
72  int64_t rows_strided = depth_indexer.GetShape(0) / stride;
73  int64_t cols_strided = depth_indexer.GetShape(1) / stride;
74 
75  points = core::Tensor({rows_strided * cols_strided, 3},
77  NDArrayIndexer point_indexer(points, 1);
78  NDArrayIndexer colors_indexer;
79  if (have_colors) {
80  const auto& imcol = image_colors.value().get();
81  image_colors_indexer = NDArrayIndexer{imcol, 2};
82  colors.value().get() =
83  core::Tensor({rows_strided * cols_strided, 3},
84  core::Dtype::Float32, imcol.GetDevice());
85  colors_indexer = NDArrayIndexer(colors.value().get(), 1);
86  }
87 
88  // Counter
89 #if defined(__CUDACC__)
90  core::Tensor count(std::vector<int>{0}, {}, core::Dtype::Int32,
91  depth.GetDevice());
92  int* count_ptr = count.GetDataPtr<int>();
93 #else
94  std::atomic<int> count_atomic(0);
95  std::atomic<int>* count_ptr = &count_atomic;
96 #endif
97 
98  int64_t n = rows_strided * cols_strided;
99 #if defined(__CUDACC__)
100  core::kernel::CUDALauncher launcher;
101 #else
102  core::kernel::CPULauncher launcher;
103 #endif
104 
105  DISPATCH_DTYPE_TO_TEMPLATE(depth.GetDtype(), [&]() {
106  launcher.LaunchGeneralKernel(n, [=] OPEN3D_DEVICE(
107  int64_t workload_idx) {
108  int64_t y = (workload_idx / cols_strided) * stride;
109  int64_t x = (workload_idx % cols_strided) * stride;
110 
111  float d = *depth_indexer.GetDataPtr<scalar_t>(x, y) / depth_scale;
112  if (d > 0 && d < depth_max) {
113  int idx = OPEN3D_ATOMIC_ADD(count_ptr, 1);
114 
115  float x_c = 0, y_c = 0, z_c = 0;
116  ti.Unproject(static_cast<float>(x), static_cast<float>(y), d,
117  &x_c, &y_c, &z_c);
118 
119  float* vertex = point_indexer.GetDataPtr<float>(idx);
120  ti.RigidTransform(x_c, y_c, z_c, vertex + 0, vertex + 1,
121  vertex + 2);
122  if (have_colors) {
123  float* pcd_pixel = colors_indexer.GetDataPtr<float>(idx);
124  float* image_pixel =
125  image_colors_indexer.GetDataPtr<float>(x, y);
126  *pcd_pixel = *image_pixel;
127  *(pcd_pixel + 1) = *(image_pixel + 1);
128  *(pcd_pixel + 2) = *(image_pixel + 2);
129  }
130  }
131  });
132  });
133 #if defined(__CUDACC__)
134  int total_pts_count = count.Item<int>();
135 #else
136  int total_pts_count = (*count_ptr).load();
137 #endif
138 
139 #ifdef __CUDACC__
140  OPEN3D_CUDA_CHECK(cudaDeviceSynchronize());
141 #endif
142  points = points.Slice(0, 0, total_pts_count);
143  if (have_colors) {
144  colors.value().get() =
145  colors.value().get().Slice(0, 0, total_pts_count);
146  }
147 }
148 } // namespace pointcloud
149 } // namespace kernel
150 } // namespace geometry
151 } // namespace t
152 } // namespace open3d
Definition: GeometryIndexer.h:168
Definition: CPULauncher.h:42
Helper class for converting coordinates/indices between 3D/3D, 3D/2D, 2D/3D.
Definition: GeometryIndexer.h:42
#define OPEN3D_CUDA_CHECK(err)
Definition: CUDAUtils.h:59
Device GetDevice() const
Definition: Tensor.cpp:1098
Dtype GetDtype() const
Definition: Tensor.h:1025
#define OPEN3D_DEVICE
Definition: CUDAUtils.h:57
OPEN3D_HOST_DEVICE void Unproject(float u_in, float v_in, float d_in, float *x_out, float *y_out, float *z_out) const
Unproject a 2D uv coordinate with depth to 3D in camera coordinate.
Definition: GeometryIndexer.h:128
#define OPEN3D_ATOMIC_ADD(X, Y)
Definition: GeometryMacros.h:37
static const Dtype Int32
Definition: Dtype.h:46
OPEN3D_HOST_DEVICE void RigidTransform(float x_in, float y_in, float z_in, float *x_out, float *y_out, float *z_out) const
Transform a 3D coordinate in camera coordinate to world coordinate.
Definition: GeometryIndexer.h:79
OPEN3D_HOST_DEVICE T * GetDataPtr(int64_t x) const
Definition: GeometryIndexer.h:324
core::Tensor InverseTransformation(const core::Tensor &T)
TODO(wei): find a proper place for such functionalities.
Definition: Utility.h:36
OPEN3D_HOST_DEVICE int64_t GetShape(int i) const
Definition: GeometryIndexer.h:319
size_t stride
Definition: TriangleMeshBuffers.cpp:183
int count
Definition: FilePCD.cpp:61
static const Dtype Float32
Definition: Dtype.h:42
Definition: Optional.h:54
static void LaunchGeneralKernel(int64_t n, func_t element_kernel)
General kernels with non-conventional indexers.
Definition: CPULauncher.h:176
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)
Definition: PointCloudImpl.h:53
#define DISPATCH_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition: Dispatch.h:49
int points
Definition: FilePCD.cpp:73
Definition: PinholeCameraIntrinsic.cpp:35
Definition: Tensor.h:50