ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
PointCloudCPU.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 namespace cloudViewer {
11 namespace t {
12 namespace geometry {
13 namespace kernel {
14 namespace pointcloud {
15 
16 using std::round;
17 
19  core::Tensor& depth,
20  utility::optional<std::reference_wrapper<core::Tensor>> image_colors,
21  const core::Tensor& points,
22  utility::optional<std::reference_wrapper<const core::Tensor>> colors,
23  const core::Tensor& intrinsics,
24  const core::Tensor& extrinsics,
25  float depth_scale,
26  float depth_max) {
27  const bool has_colors = image_colors.has_value();
28 
29  int64_t n = points.GetLength();
30 
31  const float* points_ptr = points.GetDataPtr<float>();
32  const float* point_colors_ptr =
33  has_colors ? colors.value().get().GetDataPtr<float>() : nullptr;
34 
35  TransformIndexer transform_indexer(intrinsics, extrinsics, 1.0f);
36  NDArrayIndexer depth_indexer(depth, 2);
37 
38  NDArrayIndexer color_indexer;
39  if (has_colors) {
40  color_indexer = NDArrayIndexer(image_colors.value().get(), 2);
41  }
42 
43  core::ParallelFor(core::Device("CPU:0"), n, [&](int64_t workload_idx) {
44  float x = points_ptr[3 * workload_idx + 0];
45  float y = points_ptr[3 * workload_idx + 1];
46  float z = points_ptr[3 * workload_idx + 2];
47 
48  // coordinate in camera (in voxel -> in meter)
49  float xc, yc, zc, u, v;
50  transform_indexer.RigidTransform(x, y, z, &xc, &yc, &zc);
51 
52  // coordinate in image (in pixel)
53  transform_indexer.Project(xc, yc, zc, &u, &v);
54  u = round(u);
55  v = round(v);
56  if (!depth_indexer.InBoundary(u, v) || zc <= 0 || zc > depth_max) {
57  return;
58  }
59 
60  float* depth_ptr = depth_indexer.GetDataPtr<float>(
61  static_cast<int64_t>(u), static_cast<int64_t>(v));
62  float d = zc * depth_scale;
63  // TODO: this can be wrong if ParallelFor is not implemented with
64  // OpenMP.
65 #pragma omp critical(ProjectCPU)
66  {
67  if (*depth_ptr == 0 || *depth_ptr >= d) {
68  *depth_ptr = d;
69 
70  if (has_colors) {
71  float* color_ptr = color_indexer.GetDataPtr<float>(
72  static_cast<int64_t>(u), static_cast<int64_t>(v));
73 
74  color_ptr[0] = point_colors_ptr[3 * workload_idx + 0];
75  color_ptr[1] = point_colors_ptr[3 * workload_idx + 1];
76  color_ptr[2] = point_colors_ptr[3 * workload_idx + 2];
77  }
78  }
79  }
80  });
81 }
82 
83 } // namespace pointcloud
84 } // namespace kernel
85 } // namespace geometry
86 } // namespace t
87 } // namespace cloudViewer
bool has_colors
int points
CLOUDVIEWER_HOST_DEVICE void * GetDataPtr() const
CLOUDVIEWER_HOST_DEVICE bool InBoundary(float x, float y) const
Helper class for converting coordinates/indices between 3D/3D, 3D/2D, 2D/3D.
double colors[3]
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition: ParallelFor.h:111
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)
TArrayIndexer< int64_t > NDArrayIndexer
Generic file read and write utility for python interface.