ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
UniformTSDFVolume.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 <Helper.h>
11 #include <Parallel.h>
12 #include <VoxelGrid.h>
13 #include <ecvHObjectCaster.h>
14 
15 #include <iostream>
16 #include <thread>
17 #include <unordered_map>
18 
20 
21 namespace cloudViewer {
22 namespace pipelines {
23 namespace integration {
24 
26  double length,
27  int resolution,
28  double sdf_trunc,
29  TSDFVolumeColorType color_type,
30  const Eigen::Vector3d &origin /* = Eigen::Vector3d::Zero()*/)
31  : TSDFVolume(length / (double)resolution, sdf_trunc, color_type),
32  origin_(origin),
33  length_(length),
34  resolution_(resolution),
35  voxel_num_(resolution * resolution * resolution) {
36  voxels_.resize(voxel_num_);
37 }
38 
40 
41 void UniformTSDFVolume::Reset() { voxels_.clear(); }
42 
45  const camera::PinholeCameraIntrinsic &intrinsic,
46  const Eigen::Matrix4d &extrinsic) {
47  // This function goes through the voxels, and scan convert the relative
48  // depth/color value into the voxel.
49  // The following implementation is a highly optimized version.
50  if ((image.depth_.num_of_channels_ != 1) ||
51  (image.depth_.bytes_per_channel_ != 4) ||
53  image.color_.num_of_channels_ != 3) ||
55  image.color_.bytes_per_channel_ != 1) ||
57  image.color_.num_of_channels_ != 1) ||
59  image.color_.bytes_per_channel_ != 4)) {
61  "[UniformTSDFVolume::Integrate] Unsupported image format.");
62  }
63  if ((image.depth_.width_ != intrinsic.width_) ||
64  (image.depth_.height_ != intrinsic.height_)) {
66  "[UniformTSDFVolume::Integrate] depth image size is ({} x {}), "
67  "but got ({} x {}) from intrinsic.",
68  image.depth_.width_, image.depth_.height_, intrinsic.width_,
69  intrinsic.height_);
70  }
72  (image.color_.width_ != intrinsic.width_ ||
73  image.color_.height_ != intrinsic.height_)) {
75  "[UniformTSDFVolume::Integrate] color image size is ({} x {}), "
76  "but got ({} x {}) from intrinsic.",
77  image.color_.width_, image.color_.height_, intrinsic.width_,
78  intrinsic.height_);
79  }
80 
81  auto depth2cameradistance =
83  intrinsic);
85  *depth2cameradistance);
86 }
87 
88 std::shared_ptr<ccPointCloud> UniformTSDFVolume::ExtractPointCloud() {
89  auto pointcloud = std::make_shared<ccPointCloud>();
90  double half_voxel_length = voxel_length_ * 0.5;
91  for (int x = 1; x < resolution_ - 1; x++) {
92  for (int y = 1; y < resolution_ - 1; y++) {
93  for (int z = 1; z < resolution_ - 1; z++) {
94  Eigen::Vector3i idx0(x, y, z);
95  float w0 = voxels_[IndexOf(idx0)].weight_;
96  float f0 = voxels_[IndexOf(idx0)].tsdf_;
97  const Eigen::Vector3d &c0 = voxels_[IndexOf(idx0)].color_;
98 
99  if (!(w0 != 0.0f && f0 < 0.98f && f0 >= -0.98f)) {
100  continue;
101  }
102  Eigen::Vector3d p0(half_voxel_length + voxel_length_ * x,
103  half_voxel_length + voxel_length_ * y,
104  half_voxel_length + voxel_length_ * z);
105  for (int i = 0; i < 3; i++) {
106  Eigen::Vector3d p1 = p0;
107  p1(i) += voxel_length_;
108  Eigen::Vector3i idx1 = idx0;
109  idx1(i) += 1;
110  if (idx1(i) < resolution_ - 1) {
111  float w1 = voxels_[IndexOf(idx1)].weight_;
112  float f1 = voxels_[IndexOf(idx1)].tsdf_;
113  const Eigen::Vector3d &c1 =
114  voxels_[IndexOf(idx1)].color_;
115  if (w1 != 0.0f && f1 < 0.98f && f1 >= -0.98f &&
116  f0 * f1 < 0) {
117  float r0 = std::fabs(f0);
118  float r1 = std::fabs(f1);
119  Eigen::Vector3d p = p0;
120  p(i) = (p0(i) * r1 + p1(i) * r0) / (r0 + r1);
121  pointcloud->addEigenPoint(p + origin_);
122  if (!pointcloud->hasColors()) {
123  if (!pointcloud->reserveTheRGBTable()) {
124  assert(false);
125  }
126  }
128  pointcloud->addEigenColor(
129  ((c0 * r1 + c1 * r0) / (r0 + r1) /
130  255.0f)
131  .cast<double>());
132  } else if (color_type_ ==
134  pointcloud->addEigenColor(
135  ((c0 * r1 + c1 * r0) / (r0 + r1))
136  .cast<double>());
137  }
138  // has_normal
139  if (!pointcloud->hasNormals() &&
140  !pointcloud->reserveTheNormsTable()) {
141  assert(false);
142  }
143  pointcloud->addEigenNorm(GetNormalAt(p));
144  }
145  }
146  }
147  }
148  }
149  }
150 
151  return pointcloud;
152 }
153 
154 std::shared_ptr<ccMesh> UniformTSDFVolume::ExtractTriangleMesh() {
155  // implementation of marching cubes, based on
156  // http://paulbourke.net/geometry/polygonise/
157  ccPointCloud *baseVertices = new ccPointCloud("vertices");
158  assert(baseVertices);
159  baseVertices->setEnabled(false);
160  // DGM: no need to lock it as it is only used by one mesh!
161  baseVertices->setLocked(false);
162  auto mesh = std::make_shared<ccMesh>(baseVertices);
163  mesh->addChild(baseVertices);
164 
165  double half_voxel_length = voxel_length_ * 0.5;
166  // Map of "edge_index = (x, y, z, 0) + edge_shift" to "global vertex index"
167  std::unordered_map<
169  std::equal_to<Eigen::Vector4i>,
170  Eigen::aligned_allocator<std::pair<const Eigen::Vector4i, int>>>
171  edgeindex_to_vertexindex;
172  int edge_to_index[12];
173 
174  ccPointCloud *cloud =
175  ccHObjectCaster::ToPointCloud(mesh->getAssociatedCloud());
176  assert(cloud);
177 
178  for (int x = 0; x < resolution_ - 1; x++) {
179  for (int y = 0; y < resolution_ - 1; y++) {
180  for (int z = 0; z < resolution_ - 1; z++) {
181  int cube_index = 0;
182  float f[8];
183  Eigen::Vector3d c[8];
184  for (int i = 0; i < 8; i++) {
185  Eigen::Vector3i idx = Eigen::Vector3i(x, y, z) + shift[i];
186 
187  if (voxels_[IndexOf(idx)].weight_ == 0.0f) {
188  cube_index = 0;
189  break;
190  } else {
191  f[i] = voxels_[IndexOf(idx)].tsdf_;
192  if (f[i] < 0.0f) {
193  cube_index |= (1 << i);
194  }
196  c[i] = voxels_[IndexOf(idx)].color_.cast<double>() /
197  255.0;
199  c[i] = voxels_[IndexOf(idx)].color_.cast<double>();
200  }
201  }
202  }
203  if (cube_index == 0 || cube_index == 255) {
204  continue;
205  }
206  for (int i = 0; i < 12; i++) {
207  if (edge_table[cube_index] & (1 << i)) {
208  Eigen::Vector4i edge_index =
209  Eigen::Vector4i(x, y, z, 0) + edge_shift[i];
210  if (edgeindex_to_vertexindex.find(edge_index) ==
211  edgeindex_to_vertexindex.end()) {
212  edge_to_index[i] = (int)cloud->size();
213  edgeindex_to_vertexindex[edge_index] =
214  (int)cloud->size();
215  Eigen::Vector3d pt(
216  half_voxel_length +
217  voxel_length_ * edge_index(0),
218  half_voxel_length +
219  voxel_length_ * edge_index(1),
220  half_voxel_length +
221  voxel_length_ * edge_index(2));
222  double f0 = std::abs((double)f[edge_to_vert[i][0]]);
223  double f1 = std::abs((double)f[edge_to_vert[i][1]]);
224  pt(edge_index(3)) += f0 * voxel_length_ / (f0 + f1);
225  cloud->addEigenPoint(pt + origin_);
227  const auto &c0 = c[edge_to_vert[i][0]];
228  const auto &c1 = c[edge_to_vert[i][1]];
229  if (!cloud->hasColors()) {
230  if (!cloud->reserveTheRGBTable()) {
231  assert(false);
232  }
233  }
234  cloud->addEigenColor((f1 * c0 + f0 * c1) /
235  (f0 + f1));
236  }
237  } else {
238  edge_to_index[i] =
239  edgeindex_to_vertexindex.find(edge_index)
240  ->second;
241  }
242  }
243  }
244  for (int i = 0; tri_table[cube_index][i] != -1; i += 3) {
245  mesh->addTriangle(Eigen::Vector3i(
246  edge_to_index[tri_table[cube_index][i]],
247  edge_to_index[tri_table[cube_index][i + 2]],
248  edge_to_index[tri_table[cube_index][i + 1]]));
249  }
250  }
251  }
252  }
253 
254  // do some cleaning
255  {
256  baseVertices->shrinkToFit();
257  mesh->shrinkToFit();
258  NormsIndexesTableType *normals = mesh->getTriNormsTable();
259  if (normals) {
260  normals->shrink_to_fit();
261  }
262  }
263  return mesh;
264 }
265 
266 std::shared_ptr<ccPointCloud> UniformTSDFVolume::ExtractVoxelPointCloud()
267  const {
268  auto voxel = std::make_shared<ccPointCloud>();
269  double half_voxel_length = voxel_length_ * 0.5;
270  // const float *p_tsdf = (const float *)tsdf_.data();
271  // const float *p_weight = (const float *)weight_.data();
272  // const float *p_color = (const float *)color_.data();
273  for (int x = 0; x < resolution_; x++) {
274  for (int y = 0; y < resolution_; y++) {
275  for (int z = 0; z < resolution_; z++) {
276  Eigen::Vector3d pt(half_voxel_length + voxel_length_ * x,
277  half_voxel_length + voxel_length_ * y,
278  half_voxel_length + voxel_length_ * z);
279  int ind = IndexOf(x, y, z);
280  if (voxels_[ind].weight_ != 0.0f &&
281  voxels_[ind].tsdf_ < 0.98f &&
282  voxels_[ind].tsdf_ >= -0.98f) {
283  voxel->addEigenPoint(pt + origin_);
284  double c = (voxels_[ind].tsdf_ + 1.0) * 0.5;
285  if (!voxel->hasColors() && !voxel->reserveTheRGBTable()) {
286  assert(false);
287  }
288  voxel->addEigenColor(Eigen::Vector3d(c, c, c));
289  }
290  }
291  }
292  }
293  return voxel;
294 }
295 
296 std::shared_ptr<geometry::VoxelGrid> UniformTSDFVolume::ExtractVoxelGrid()
297  const {
298  auto voxel_grid = std::make_shared<geometry::VoxelGrid>();
299  voxel_grid->voxel_size_ = voxel_length_;
300  voxel_grid->origin_ = origin_;
301 
302  std::vector<std::pair<Eigen::Vector3i, geometry::Voxel>> valid_voxels;
303 
304 #ifdef _WIN32
305 #pragma omp parallel for schedule(static) \
306  num_threads(utility::EstimateMaxThreads())
307 #else
308 #pragma omp parallel for collapse(2) schedule(static) \
309  num_threads(utility::EstimateMaxThreads())
310 #endif
311  for (int x = 0; x < resolution_; x++) {
312  for (int y = 0; y < resolution_; y++) {
313  std::vector<std::pair<Eigen::Vector3i, geometry::Voxel>>
314  local_voxels;
315 
316  for (int z = 0; z < resolution_; z++) {
317  const int ind = IndexOf(x, y, z);
318  const float w = voxels_[ind].weight_;
319  const float f = voxels_[ind].tsdf_;
320  if (w != 0.0f && f < 0.98f && f >= -0.98f) {
321  double c = (f + 1.0) * 0.5;
322  Eigen::Vector3d color = Eigen::Vector3d(c, c, c);
323  Eigen::Vector3i index = Eigen::Vector3i(x, y, z);
324  local_voxels.emplace_back(index,
325  geometry::Voxel(index, color));
326  }
327  }
328 
329 #pragma omp critical
330  {
331  valid_voxels.insert(valid_voxels.end(), local_voxels.begin(),
332  local_voxels.end());
333  }
334  }
335  }
336 
337  for (const auto &voxel_pair : valid_voxels) {
338  voxel_grid->voxels_[voxel_pair.first] = voxel_pair.second;
339  }
340 
341  return voxel_grid;
342 }
343 
344 std::vector<Eigen::Vector2d> UniformTSDFVolume::ExtractVolumeTSDF() const {
345  std::vector<Eigen::Vector2d> sharedvoxels_;
346  sharedvoxels_.resize(voxel_num_);
347 
348 #ifdef _OPENMP
349 #ifdef _WIN32
350 #pragma omp parallel for schedule(static) \
351  num_threads(utility::EstimateMaxThreads())
352 #else
353 #pragma omp parallel for collapse(2) schedule(static) \
354  num_threads(utility::EstimateMaxThreads())
355 #endif
356 #endif
357  for (int x = 0; x < resolution_; x++) {
358  for (int y = 0; y < resolution_; y++) {
359  for (int z = 0; z < resolution_; z++) {
360  const int ind = IndexOf(x, y, z);
361  const float f = voxels_[ind].tsdf_;
362  const float w = voxels_[ind].weight_;
363  sharedvoxels_[ind] = Eigen::Vector2d(f, w);
364  }
365  }
366  }
367  return sharedvoxels_;
368 }
369 
370 std::vector<Eigen::Vector3d> UniformTSDFVolume::ExtractVolumeColor() const {
371  std::vector<Eigen::Vector3d> sharedcolors_;
372  sharedcolors_.resize(voxel_num_);
373 #ifdef _OPENMP
374 #ifdef _WIN32
375 #pragma omp parallel for schedule(static) \
376  num_threads(utility::EstimateMaxThreads())
377 #else
378 #pragma omp parallel for collapse(2) schedule(static) \
379  num_threads(utility::EstimateMaxThreads())
380 #endif
381 #endif
382  for (int x = 0; x < resolution_; x++) {
383  for (int y = 0; y < resolution_; y++) {
384  for (int z = 0; z < resolution_; z++) {
385  const int ind = IndexOf(x, y, z);
386  sharedcolors_[ind] = voxels_[ind].color_;
387  }
388  }
389  }
390  return sharedcolors_;
391 }
392 
394  const std::vector<Eigen::Vector2d> &sharedvoxels) {
395 #ifdef _OPENMP
396 #ifdef _WIN32
397 #pragma omp parallel for schedule(static) \
398  num_threads(utility::EstimateMaxThreads())
399 #else
400 #pragma omp parallel for collapse(2) schedule(static) \
401  num_threads(utility::EstimateMaxThreads())
402 #endif
403 #endif
404  for (int x = 0; x < resolution_; x++) {
405  for (int y = 0; y < resolution_; y++) {
406  for (int z = 0; z < resolution_; z++) {
407  const int ind = IndexOf(x, y, z);
408  voxels_[ind].tsdf_ = sharedvoxels[ind](0);
409  voxels_[ind].weight_ = sharedvoxels[ind](1);
410  }
411  }
412  }
413 }
414 
416  const std::vector<Eigen::Vector3d> &sharedcolors) {
417 #ifdef _OPENMP
418 #ifdef _WIN32
419 #pragma omp parallel for schedule(static) \
420  num_threads(utility::EstimateMaxThreads())
421 #else
422 #pragma omp parallel for collapse(2) schedule(static) \
423  num_threads(utility::EstimateMaxThreads())
424 #endif
425 #endif
426  for (int x = 0; x < resolution_; x++) {
427  for (int y = 0; y < resolution_; y++) {
428  for (int z = 0; z < resolution_; z++) {
429  const int ind = IndexOf(x, y, z);
430  voxels_[ind].color_ = sharedcolors[ind];
431  }
432  }
433  }
434 }
435 
437  const geometry::RGBDImage &image,
438  const camera::PinholeCameraIntrinsic &intrinsic,
439  const Eigen::Matrix4d &extrinsic,
440  const geometry::Image &depth_to_camera_distance_multiplier) {
441  const float fx = static_cast<float>(intrinsic.GetFocalLength().first);
442  const float fy = static_cast<float>(intrinsic.GetFocalLength().second);
443  const float cx = static_cast<float>(intrinsic.GetPrincipalPoint().first);
444  const float cy = static_cast<float>(intrinsic.GetPrincipalPoint().second);
445  const Eigen::Matrix4f extrinsic_f = extrinsic.cast<float>();
446  const float voxel_length_f = static_cast<float>(voxel_length_);
447  const float half_voxel_length_f = voxel_length_f * 0.5f;
448  const float sdf_trunc_f = static_cast<float>(sdf_trunc_);
449  const float sdf_trunc_inv_f = 1.0f / sdf_trunc_f;
450  const Eigen::Matrix4f extrinsic_scaled_f = extrinsic_f * voxel_length_f;
451  const float safe_width_f = intrinsic.width_ - 0.0001f;
452  const float safe_height_f = intrinsic.height_ - 0.0001f;
453 
454 #ifdef _OPENMP
455 #ifdef _WIN32
456 #pragma omp parallel for schedule(static) \
457  num_threads(utility::EstimateMaxThreads())
458 #else
459 #pragma omp parallel for collapse(2) schedule(static) \
460  num_threads(utility::EstimateMaxThreads())
461 #endif
462 #endif
463  for (int x = 0; x < resolution_; x++) {
464  for (int y = 0; y < resolution_; y++) {
465  Eigen::Vector4f pt_3d_homo(float(half_voxel_length_f +
466  voxel_length_f * x + origin_(0)),
467  float(half_voxel_length_f +
468  voxel_length_f * y + origin_(1)),
469  float(half_voxel_length_f + origin_(2)),
470  1.f);
471  Eigen::Vector4f pt_camera = extrinsic_f * pt_3d_homo;
472  for (int z = 0; z < resolution_; z++,
473  pt_camera(0) += extrinsic_scaled_f(0, 2),
474  pt_camera(1) += extrinsic_scaled_f(1, 2),
475  pt_camera(2) += extrinsic_scaled_f(2, 2)) {
476  // Skip if negative depth after projection
477  if (pt_camera(2) <= 0) {
478  continue;
479  }
480  // Skip if x-y coordinate not in range
481  float u_f = pt_camera(0) * fx / pt_camera(2) + cx + 0.5f;
482  float v_f = pt_camera(1) * fy / pt_camera(2) + cy + 0.5f;
483  if (!(u_f >= 0.0001f && u_f < safe_width_f && v_f >= 0.0001f &&
484  v_f < safe_height_f)) {
485  continue;
486  }
487  // Skip if negative depth in depth image
488  int u = (int)u_f;
489  int v = (int)v_f;
490  float d = *image.depth_.PointerAt<float>(u, v);
491  if (d <= 0.0f) {
492  continue;
493  }
494 
495  int v_ind = IndexOf(x, y, z);
496  float sdf =
497  (d - pt_camera(2)) *
498  (*depth_to_camera_distance_multiplier.PointerAt<float>(
499  u, v));
500  if (sdf > -sdf_trunc_f) {
501  // integrate
502  float tsdf = std::min(1.0f, sdf * sdf_trunc_inv_f);
503  voxels_[v_ind].tsdf_ =
504  (voxels_[v_ind].tsdf_ * voxels_[v_ind].weight_ +
505  tsdf) /
506  (voxels_[v_ind].weight_ + 1.0f);
508  const uint8_t *rgb =
509  image.color_.PointerAt<uint8_t>(u, v, 0);
510  Eigen::Vector3d rgb_f(rgb[0], rgb[1], rgb[2]);
511  voxels_[v_ind].color_ =
512  (voxels_[v_ind].color_ *
513  voxels_[v_ind].weight_ +
514  rgb_f) /
515  (voxels_[v_ind].weight_ + 1.0f);
517  const float *intensity =
518  image.color_.PointerAt<float>(u, v, 0);
519  voxels_[v_ind].color_ =
520  (voxels_[v_ind].color_.array() *
521  voxels_[v_ind].weight_ +
522  (*intensity)) /
523  (voxels_[v_ind].weight_ + 1.0f);
524  }
525  voxels_[v_ind].weight_ += 1.0f;
526  }
527  }
528  }
529  }
530 }
531 
532 Eigen::Vector3d UniformTSDFVolume::GetNormalAt(const Eigen::Vector3d &p) {
533  Eigen::Vector3d n;
534  const double half_gap = 0.99 * voxel_length_;
535  for (int i = 0; i < 3; i++) {
536  Eigen::Vector3d p0 = p;
537  p0(i) -= half_gap;
538  Eigen::Vector3d p1 = p;
539  p1(i) += half_gap;
540  n(i) = GetTSDFAt(p1) - GetTSDFAt(p0);
541  }
542  return n.normalized();
543 }
544 
545 double UniformTSDFVolume::GetTSDFAt(const Eigen::Vector3d &p) {
546  Eigen::Vector3i idx;
547  Eigen::Vector3d p_grid = p / voxel_length_ - Eigen::Vector3d(0.5, 0.5, 0.5);
548  for (int i = 0; i < 3; i++) {
549  idx(i) = (int)std::floor(p_grid(i));
550  }
551  Eigen::Vector3d r = p_grid - idx.cast<double>();
552 
553  double tsdf = 0;
554  tsdf += (1 - r(0)) * (1 - r(1)) * (1 - r(2)) *
555  voxels_[IndexOf(idx + Eigen::Vector3i(0, 0, 0))].tsdf_;
556  tsdf += (1 - r(0)) * (1 - r(1)) * r(2) *
557  voxels_[IndexOf(idx + Eigen::Vector3i(0, 0, 1))].tsdf_;
558  tsdf += (1 - r(0)) * r(1) * (1 - r(2)) *
559  voxels_[IndexOf(idx + Eigen::Vector3i(0, 1, 0))].tsdf_;
560  tsdf += (1 - r(0)) * r(1) * r(2) *
561  voxels_[IndexOf(idx + Eigen::Vector3i(0, 1, 1))].tsdf_;
562  tsdf += r(0) * (1 - r(1)) * (1 - r(2)) *
563  voxels_[IndexOf(idx + Eigen::Vector3i(1, 0, 0))].tsdf_;
564  tsdf += r(0) * (1 - r(1)) * r(2) *
565  voxels_[IndexOf(idx + Eigen::Vector3i(1, 0, 1))].tsdf_;
566  tsdf += r(0) * r(1) * (1 - r(2)) *
567  voxels_[IndexOf(idx + Eigen::Vector3i(1, 1, 0))].tsdf_;
568  tsdf += r(0) * r(1) * r(2) *
569  voxels_[IndexOf(idx + Eigen::Vector3i(1, 1, 1))].tsdf_;
570  return tsdf;
571 }
572 
573 } // namespace integration
574 } // namespace pipelines
575 } // namespace cloudViewer
std::shared_ptr< core::Tensor > image
math::float4 color
Array of compressed 3D normals (single index)
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
virtual void setLocked(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:117
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void addEigenColor(const Eigen::Vector3d &color)
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
bool hasColors() const override
Returns whether colors are enabled or not.
void shrinkToFit()
Removes unused capacity.
void addEigenPoint(const Eigen::Vector3d &point)
unsigned size() const override
Definition: PointCloudTpl.h:38
Contains the pinhole camera intrinsic parameters.
std::pair< double, double > GetFocalLength() const
Returns the focal length in a tuple of X-axis and Y-axis focal lengths.
std::pair< double, double > GetPrincipalPoint() const
The Image class stores image with customizable width, height, num of channels and bytes per channel.
Definition: Image.h:33
static std::shared_ptr< Image > CreateDepthToCameraDistanceMultiplierFloatImage(const camera::PinholeCameraIntrinsic &intrinsic)
T * PointerAt(int u, int v) const
Function to access the raw data of a single-channel Image.
RGBDImage is for a pair of registered color and depth images,.
Definition: RGBDImage.h:27
Base Voxel class, containing grid id and color.
Definition: VoxelGrid.h:38
Base class of the Truncated Signed Distance Function (TSDF) volume.
Definition: TSDFVolume.h:43
double sdf_trunc_
Truncation value for signed distance function (SDF).
Definition: TSDFVolume.h:78
double voxel_length_
Length of the voxel in meters.
Definition: TSDFVolume.h:76
TSDFVolumeColorType color_type_
Color type of the TSDF volume.
Definition: TSDFVolume.h:80
std::shared_ptr< geometry::VoxelGrid > ExtractVoxelGrid() const
Debug function to extract the voxel data VoxelGrid.
void IntegrateWithDepthToCameraDistanceMultiplier(const geometry::RGBDImage &image, const camera::PinholeCameraIntrinsic &intrinsic, const Eigen::Matrix4d &extrinsic, const geometry::Image &depth_to_camera_distance_multiplier)
std::shared_ptr< ccMesh > ExtractTriangleMesh() override
Function to extract a triangle mesh, using the marching cubes algorithm. (https://en....
std::shared_ptr< ccPointCloud > ExtractVoxelPointCloud() const
Debug function to extract the voxel data into a VoxelGrid.
void Integrate(const geometry::RGBDImage &image, const camera::PinholeCameraIntrinsic &intrinsic, const Eigen::Matrix4d &extrinsic) override
Function to integrate an RGB-D image into the volume.
std::shared_ptr< ccPointCloud > ExtractPointCloud() override
Function to extract a point cloud with normals.
std::vector< Eigen::Vector2d > ExtractVolumeTSDF() const
Debug function to extract the volume TSDF data into a vector array.
void InjectVolumeTSDF(const std::vector< Eigen::Vector2d > &sharedvoxels)
Debug function to inject voxel TSDF data into the volume.
std::vector< Eigen::Vector3d > ExtractVolumeColor() const
Debug function to extract the volume color data into a vector array.
void InjectVolumeColor(const std::vector< Eigen::Vector3d > &sharedcolors)
Debug function to inject voxel Color data into the volume.
UniformTSDFVolume(double length, int resolution, double sdf_trunc, TSDFVolumeColorType color_type, const Eigen::Vector3d &origin=Eigen::Vector3d::Zero())
void Reset() override
Function to reset the TSDFVolume.
double normals[3]
#define LogError(...)
Definition: Logging.h:60
__host__ __device__ float length(float2 v)
Definition: cutil_math.h:1162
__host__ __device__ float2 fabs(float2 v)
Definition: cutil_math.h:1254
int min(int a, int b)
Definition: cutil_math.h:53
__host__ __device__ int2 abs(int2 v)
Definition: cutil_math.h:1267
Helper functions for the ml ops.
MiniVec< float, N > floor(const MiniVec< float, N > &a)
Definition: MiniVec.h:75
Generic file read and write utility for python interface.
Eigen::Matrix< Index, 3, 1 > Vector3i
Definition: knncpp.h:30
Eigen::Matrix< Index, 4, 1 > Vector4i
Definition: knncpp.h:31