MRPT  1.9.9
CObservation3DRangeScan_project3D_impl.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CObservation3DRangeScan_project3D_impl_H
10 #define CObservation3DRangeScan_project3D_impl_H
11 
12 #include <mrpt/core/round.h> // round()
13 
14 namespace mrpt::obs::detail
15 {
16 // Auxiliary functions which implement SSE-optimized proyection of 3D point
17 // cloud:
18 template <class POINTMAP>
20  const int H, const int W, const float* kys, const float* kzs,
21  const mrpt::math::CMatrix& rangeImage,
23  std::vector<uint16_t>& idxs_x, std::vector<uint16_t>& idxs_y,
24  const mrpt::obs::TRangeImageFilterParams& filterParams, bool MAKE_DENSE);
25 template <class POINTMAP>
27  const int H, const int W, const float* kys, const float* kzs,
28  const mrpt::math::CMatrix& rangeImage,
30  std::vector<uint16_t>& idxs_x, std::vector<uint16_t>& idxs_y,
31  const mrpt::obs::TRangeImageFilterParams& filterParams, bool MAKE_DENSE);
32 
33 template <class POINTMAP>
35  mrpt::obs::CObservation3DRangeScan& src_obs, POINTMAP& dest_pointcloud,
36  const mrpt::obs::T3DPointsProjectionParams& projectParams,
37  const mrpt::obs::TRangeImageFilterParams& filterParams)
38 {
39  using namespace mrpt::math;
40 
41  if (!src_obs.hasRangeImage) return;
42 
43  mrpt::opengl::PointCloudAdapter<POINTMAP> pca(dest_pointcloud);
44 
45  // ------------------------------------------------------------
46  // Stage 1/3: Create 3D point cloud local coordinates
47  // ------------------------------------------------------------
48  const int W = src_obs.rangeImage.cols();
49  const int H = src_obs.rangeImage.rows();
50  ASSERT_(W != 0 && H != 0);
51  const size_t WH = W * H;
52 
53  src_obs.resizePoints3DVectors(WH); // This is to make sure
54  // points3D_idxs_{x,y} have the expected
55  // sizes.
56  pca.resize(WH); // Reserve memory for 3D points. It will be later resized
57  // again to the actual number of valid points
58 
59  if(projectParams.MAKE_ORGANIZED)
60  pca.setDimensions(H,W);
61 
62  if (src_obs.range_is_depth)
63  {
64  // range_is_depth = true
65 
66  // Use cached tables?
67  if (projectParams.PROJ3D_USE_LUT)
68  {
69  // Use LUT:
70  if (src_obs.get_3dproj_lut().prev_camParams !=
71  src_obs.cameraParams ||
72  WH != size_t(src_obs.get_3dproj_lut().Kys.size()))
73  {
74  src_obs.get_3dproj_lut().prev_camParams = src_obs.cameraParams;
75  src_obs.get_3dproj_lut().Kys.resize(WH);
76  src_obs.get_3dproj_lut().Kzs.resize(WH);
77 
78  const float r_cx = src_obs.cameraParams.cx();
79  const float r_cy = src_obs.cameraParams.cy();
80  const float r_fx_inv = 1.0f / src_obs.cameraParams.fx();
81  const float r_fy_inv = 1.0f / src_obs.cameraParams.fy();
82 
83  float* kys = &src_obs.get_3dproj_lut().Kys[0];
84  float* kzs = &src_obs.get_3dproj_lut().Kzs[0];
85  for (int r = 0; r < H; r++)
86  for (int c = 0; c < W; c++)
87  {
88  *kys++ = (r_cx - c) * r_fx_inv;
89  *kzs++ = (r_cy - r) * r_fy_inv;
90  }
91  } // end update LUT.
92 
93  ASSERT_EQUAL_(WH, size_t(src_obs.get_3dproj_lut().Kys.size()));
94  ASSERT_EQUAL_(WH, size_t(src_obs.get_3dproj_lut().Kzs.size()));
95  float* kys = &src_obs.get_3dproj_lut().Kys[0];
96  float* kzs = &src_obs.get_3dproj_lut().Kzs[0];
97 
98  if (filterParams.rangeMask_min)
99  { // sanity check:
101  filterParams.rangeMask_min->cols(),
102  src_obs.rangeImage.cols());
104  filterParams.rangeMask_min->rows(),
105  src_obs.rangeImage.rows());
106  }
107  if (filterParams.rangeMask_max)
108  { // sanity check:
110  filterParams.rangeMask_max->cols(),
111  src_obs.rangeImage.cols());
113  filterParams.rangeMask_max->rows(),
114  src_obs.rangeImage.rows());
115  }
116 #if MRPT_HAS_SSE2
117  if ((W & 0x07) == 0 && projectParams.USE_SSE2)
119  H, W, kys, kzs, src_obs.rangeImage, pca,
120  src_obs.points3D_idxs_x, src_obs.points3D_idxs_y,
121  filterParams, projectParams.MAKE_DENSE);
122  else
124  H, W, kys, kzs, src_obs.rangeImage, pca,
125  src_obs.points3D_idxs_x, src_obs.points3D_idxs_y,
126  filterParams, projectParams.MAKE_DENSE); // if image width
127 // is not 8*N, use
128 // standard method
129 #else
131  H, W, kys, kzs, src_obs.rangeImage, pca,
132  src_obs.points3D_idxs_x, src_obs.points3D_idxs_y, filterParams,
133  projectParams.MAKE_DENSE);
134 #endif
135  }
136  else
137  {
138  // Without LUT:
139  const float r_cx = src_obs.cameraParams.cx();
140  const float r_cy = src_obs.cameraParams.cy();
141  const float r_fx_inv = 1.0f / src_obs.cameraParams.fx();
142  const float r_fy_inv = 1.0f / src_obs.cameraParams.fy();
143  TRangeImageFilter rif(filterParams);
144  size_t idx = 0;
145  for (int r = 0; r < H; r++)
146  for (int c = 0; c < W; c++)
147  {
148  const float D = src_obs.rangeImage.coeff(r, c);
149  if (rif.do_range_filter(r, c, D))
150  {
151  const float Kz = (r_cy - r) * r_fy_inv;
152  const float Ky = (r_cx - c) * r_fx_inv;
153  pca.setPointXYZ(
154  idx,
155  D, // x
156  Ky * D, // y
157  Kz * D // z
158  );
159  src_obs.points3D_idxs_x[idx] = c;
160  src_obs.points3D_idxs_y[idx] = r;
161  ++idx;
162  }
163  }
164  pca.resize(idx); // Actual number of valid pts
165  }
166  }
167  else
168  {
169  /* range_is_depth = false :
170  * Ky = (r_cx - c)/r_fx
171  * Kz = (r_cy - r)/r_fy
172  *
173  * x(i) = rangeImage(r,c) / sqrt( 1 + Ky^2 + Kz^2 )
174  * y(i) = Ky * x(i)
175  * z(i) = Kz * x(i)
176  */
177  const float r_cx = src_obs.cameraParams.cx();
178  const float r_cy = src_obs.cameraParams.cy();
179  const float r_fx_inv = 1.0f / src_obs.cameraParams.fx();
180  const float r_fy_inv = 1.0f / src_obs.cameraParams.fy();
181  TRangeImageFilter rif(filterParams);
182  size_t idx = 0;
183  for (int r = 0; r < H; r++)
184  for (int c = 0; c < W; c++)
185  {
186  const float D = src_obs.rangeImage.coeff(r, c);
187  if (rif.do_range_filter(r, c, D))
188  {
189  const float Ky = (r_cx - c) * r_fx_inv;
190  const float Kz = (r_cy - r) * r_fy_inv;
191  pca.setPointXYZ(
192  idx,
193  D / std::sqrt(1 + Ky * Ky + Kz * Kz), // x
194  Ky * D, // y
195  Kz * D // z
196  );
197  src_obs.points3D_idxs_x[idx] = c;
198  src_obs.points3D_idxs_y[idx] = r;
199  ++idx;
200  }
201  }
202  pca.resize(idx); // Actual number of valid pts
203  }
204 
205  // -------------------------------------------------------------
206  // Stage 2/3: Project local points into RGB image to get colors
207  // -------------------------------------------------------------
208  if (src_obs.hasIntensityImage)
209  {
210  const int imgW = src_obs.intensityImage.getWidth();
211  const int imgH = src_obs.intensityImage.getHeight();
212  const bool hasColorIntensityImg = src_obs.intensityImage.isColor();
213 
214  const float cx = src_obs.cameraParamsIntensity.cx();
215  const float cy = src_obs.cameraParamsIntensity.cy();
216  const float fx = src_obs.cameraParamsIntensity.fx();
217  const float fy = src_obs.cameraParamsIntensity.fy();
218 
219  // Unless we are in a special case (both depth & RGB images coincide)...
220  const bool isDirectCorresp =
222 
223  // ...precompute the inverse of the pose transformation out of the loop,
224  // store as a 4x4 homogeneous matrix to exploit SSE optimizations
225  // below:
227  if (!isDirectCorresp)
228  {
233  src_obs.relativePoseIntensityWRTDepth.m_coords, R_inv, t_inv);
234 
235  T_inv(3, 3) = 1;
236  T_inv.block<3, 3>(0, 0) = R_inv.cast<float>();
237  T_inv.block<3, 1>(0, 3) = t_inv.cast<float>();
238  }
239 
240  Eigen::Matrix<float, 4, 1> pt_wrt_color, pt_wrt_depth;
241  pt_wrt_depth[3] = 1;
242 
243  mrpt::img::TColor pCol;
244 
245  // For each local point:
246  const size_t nPts = pca.size();
247  for (size_t i = 0; i < nPts; i++)
248  {
249  int img_idx_x, img_idx_y; // projected pixel coordinates, in the
250  // RGB image plane
251  bool pointWithinImage = false;
252  if (isDirectCorresp)
253  {
254  pointWithinImage = true;
255  img_idx_x = src_obs.points3D_idxs_x[i];
256  img_idx_y = src_obs.points3D_idxs_y[i];
257  }
258  else
259  {
260  // Project point, which is now in "pca" in local coordinates wrt
261  // the depth camera, into the intensity camera:
262  pca.getPointXYZ(
263  i, pt_wrt_depth[0], pt_wrt_depth[1], pt_wrt_depth[2]);
264  pt_wrt_color = T_inv * pt_wrt_depth;
265 
266  // Project to image plane:
267  if (pt_wrt_color[2])
268  {
269  img_idx_x = mrpt::round(
270  cx + fx * pt_wrt_color[0] / pt_wrt_color[2]);
271  img_idx_y = mrpt::round(
272  cy + fy * pt_wrt_color[1] / pt_wrt_color[2]);
273  pointWithinImage = img_idx_x >= 0 && img_idx_x < imgW &&
274  img_idx_y >= 0 && img_idx_y < imgH;
275  }
276  }
277 
278  if (pointWithinImage)
279  {
280  if (hasColorIntensityImg)
281  {
282  const uint8_t* c = src_obs.intensityImage.get_unsafe(
283  img_idx_x, img_idx_y, 0);
284  pCol.R = c[2];
285  pCol.G = c[1];
286  pCol.B = c[0];
287  }
288  else
289  {
290  uint8_t c = *src_obs.intensityImage.get_unsafe(
291  img_idx_x, img_idx_y, 0);
292  pCol.R = pCol.G = pCol.B = c;
293  }
294  }
295  else
296  {
297  pCol.R = pCol.G = pCol.B = 255;
298  }
299  // Set color:
300  pca.setPointRGBu8(i, pCol.R, pCol.G, pCol.B);
301  } // end for each point
302  } // end if src_obs has intensity image
303 
304  // ...
305 
306  // ------------------------------------------------------------
307  // Stage 3/3: Apply 6D transformations
308  // ------------------------------------------------------------
309  if (projectParams.takeIntoAccountSensorPoseOnRobot ||
310  projectParams.robotPoseInTheWorld)
311  {
312  mrpt::poses::CPose3D transf_to_apply; // Either ROBOTPOSE or
313  // ROBOTPOSE(+)SENSORPOSE or
314  // SENSORPOSE
315  if (projectParams.takeIntoAccountSensorPoseOnRobot)
316  transf_to_apply = src_obs.sensorPose;
317  if (projectParams.robotPoseInTheWorld)
318  transf_to_apply.composeFrom(
319  *projectParams.robotPoseInTheWorld,
320  mrpt::poses::CPose3D(transf_to_apply));
321 
322  const Eigen::Matrix<float, 4, 4> HM =
323  transf_to_apply
325  .cast<float>();
326  Eigen::Matrix<float, 4, 1> pt, pt_transf;
327  pt[3] = 1;
328 
329  const size_t nPts = pca.size();
330  for (size_t i = 0; i < nPts; i++)
331  {
332  pca.getPointXYZ(i, pt[0], pt[1], pt[2]);
333  pt_transf = HM * pt;
334  pca.setPointXYZ(i, pt_transf[0], pt_transf[1], pt_transf[2]);
335  }
336  }
337 } // end of project3DPointsFromDepthImageInto
338 
339 // Auxiliary functions which implement proyection of 3D point clouds:
340 template <class POINTMAP>
342  const int H, const int W, const float* kys, const float* kzs,
343  const mrpt::math::CMatrix& rangeImage,
345  std::vector<uint16_t>& idxs_x, std::vector<uint16_t>& idxs_y,
346  const mrpt::obs::TRangeImageFilterParams& fp, bool MAKE_DENSE)
347 {
348  TRangeImageFilter rif(fp);
349  // Preconditions: minRangeMask() has the right size
350  size_t idx = 0;
351  for (int r = 0; r < H; r++)
352  for (int c = 0; c < W; c++)
353  {
354  const float D = rangeImage.coeff(r, c);
355  if (!rif.do_range_filter(r, c, D))
356  {
357  if (!MAKE_DENSE)
358  {
359  pca.setInvalidPoint(idx);
360  ++idx;
361  }
362  continue;
363  }
364 
365  pca.setPointXYZ(idx, D /*x*/, *kys++ * D /*y*/, *kzs++ * D /*z*/);
366  idxs_x[idx] = c;
367  idxs_y[idx] = r;
368  ++idx;
369  }
370  pca.resize(idx);
371 }
372 
373 // Auxiliary functions which implement proyection of 3D point clouds:
374 template <class POINTMAP>
376  const int H, const int W, const float* kys, const float* kzs,
377  const mrpt::math::CMatrix& rangeImage,
379  std::vector<uint16_t>& idxs_x, std::vector<uint16_t>& idxs_y,
380  const mrpt::obs::TRangeImageFilterParams& filterParams, bool MAKE_DENSE)
381 {
382 #if MRPT_HAS_SSE2
383  // Preconditions: minRangeMask() has the right size
384  // Use optimized version:
385  const int W_4 = W >> 2; // /=4 , since we process 4 values at a time.
386  size_t idx = 0;
387  alignas(MRPT_MAX_ALIGN_BYTES) float xs[4], ys[4], zs[4];
388  const __m128 D_zeros = _mm_set_ps(.0f, .0f, .0f, .0f);
389  const __m128 xormask =
390  (filterParams.rangeCheckBetween)
391  ? _mm_cmpneq_ps(D_zeros, D_zeros)
392  : // want points BETWEEN min and max to be valid
393  _mm_cmpeq_ps(
394  D_zeros,
395  D_zeros); // want points OUTSIDE of min and max to be valid
396  for (int r = 0; r < H; r++)
397  {
398  const float* D_ptr =
399  &rangeImage.coeffRef(r, 0); // Matrices are 16-aligned
400  const float* Dgt_ptr =
401  !filterParams.rangeMask_min
402  ? nullptr
403  : &filterParams.rangeMask_min->coeffRef(r, 0);
404  const float* Dlt_ptr =
405  !filterParams.rangeMask_max
406  ? nullptr
407  : &filterParams.rangeMask_max->coeffRef(r, 0);
408 
409  for (int c = 0; c < W_4; c++)
410  {
411  const __m128 D = _mm_load_ps(D_ptr);
412  const __m128 nz_mask = _mm_cmpgt_ps(D, D_zeros);
413  __m128 valid_range_mask;
414  if (!filterParams.rangeMask_min && !filterParams.rangeMask_max)
415  { // No filter: just skip D=0 points
416  valid_range_mask = nz_mask;
417  }
418  else
419  {
420  if (!filterParams.rangeMask_min || !filterParams.rangeMask_max)
421  { // Only one filter
422  if (filterParams.rangeMask_min)
423  {
424  const __m128 Dmin = _mm_load_ps(Dgt_ptr);
425  valid_range_mask = _mm_and_ps(
426  _mm_cmpgt_ps(D, Dmin), _mm_cmpgt_ps(Dmin, D_zeros));
427  }
428  else
429  {
430  const __m128 Dmax = _mm_load_ps(Dlt_ptr);
431  valid_range_mask = _mm_and_ps(
432  _mm_cmplt_ps(D, Dmax), _mm_cmpgt_ps(Dmax, D_zeros));
433  }
434  valid_range_mask = _mm_and_ps(
435  valid_range_mask, nz_mask); // Filter out D=0 points
436  }
437  else
438  {
439  // We have both: D>Dmin and D<Dmax conditions, with XOR to
440  // optionally invert the selection:
441  const __m128 Dmin = _mm_load_ps(Dgt_ptr);
442  const __m128 Dmax = _mm_load_ps(Dlt_ptr);
443 
444  const __m128 gt_mask = _mm_cmpgt_ps(D, Dmin);
445  const __m128 lt_mask = _mm_and_ps(
446  _mm_cmplt_ps(D, Dmax), nz_mask); // skip points at zero
447  valid_range_mask =
448  _mm_and_ps(gt_mask, lt_mask); // (D>Dmin && D<Dmax)
449  valid_range_mask = _mm_xor_ps(valid_range_mask, xormask);
450  // Add the case of D_min & D_max = 0 (no filtering)
451  valid_range_mask = _mm_or_ps(
452  valid_range_mask, _mm_and_ps(
453  _mm_cmpeq_ps(Dmin, D_zeros),
454  _mm_cmpeq_ps(Dmax, D_zeros)));
455  // Finally, ensure no invalid ranges get thru:
456  valid_range_mask = _mm_and_ps(valid_range_mask, nz_mask);
457  }
458  }
459  const int valid_range_maski = _mm_movemask_epi8(
460  _mm_castps_si128(valid_range_mask)); // 0x{f|0}{f|0}{f|0}{f|0}
461  if (valid_range_maski != 0) // Any of the 4 values is valid?
462  {
463  const __m128 KY = _mm_load_ps(kys);
464  const __m128 KZ = _mm_load_ps(kzs);
465 
466  _mm_storeu_ps(xs, D);
467  _mm_storeu_ps(ys, _mm_mul_ps(KY, D));
468  _mm_storeu_ps(zs, _mm_mul_ps(KZ, D));
469 
470  for (int q = 0; q < 4; q++)
471  if ((valid_range_maski & (1 << (q * 4))) != 0)
472  {
473  pca.setPointXYZ(idx, xs[q], ys[q], zs[q]);
474  idxs_x[idx] = (c << 2) + q;
475  idxs_y[idx] = r;
476  ++idx;
477  }
478  else if (!MAKE_DENSE)
479  {
480  pca.setInvalidPoint(idx);
481  ++idx;
482  }
483  }
484  else if (!MAKE_DENSE)
485  {
486  for (int q = 0; q < 4; q++)
487  {
488  pca.setInvalidPoint(idx);
489  ++idx;
490  }
491  }
492  D_ptr += 4;
493  if (Dgt_ptr) Dgt_ptr += 4;
494  if (Dlt_ptr) Dlt_ptr += 4;
495  kys += 4;
496  kzs += 4;
497  }
498  }
499  pca.resize(idx);
500 #endif
501 }
502 } // namespace mrpt
503 #endif
504 
505 
#define MRPT_MAX_ALIGN_BYTES
unsigned char * get_unsafe(unsigned int col, unsigned int row, unsigned int channel=0) const
Access to pixels without checking boundaries - Use normally the () operator better,...
Definition: CImage.cpp:491
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:892
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:906
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:864
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:163
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:165
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Definition: TCamera.h:159
double cy() const
Get the value of the principal point y-coordinate (in pixels).
Definition: TCamera.h:161
A numeric matrix of compile-time fixed size.
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:23
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement,...
void resizePoints3DVectors(const size_t nPoints)
Use this method instead of resizing all three points3D_x, points3D_y & points3D_z to allow the usage ...
static TCached3DProjTables & get_3dproj_lut()
3D point cloud projection look-up-table
std::vector< uint16_t > points3D_idxs_x
If hasPoints3D=true, the (x,y) pixel coordinates for each (X,Y,Z) point in points3D_x,...
mrpt::img::TCamera cameraParams
Projection parameters of the depth camera.
bool hasIntensityImage
true means the field intensityImage contains valid data
mrpt::poses::CPose3D relativePoseIntensityWRTDepth
Relative pose of the intensity camera wrt the depth camera (which is the coordinates origin for this ...
bool doDepthAndIntensityCamerasCoincide() const
Return true if relativePoseIntensityWRTDepth equals the pure rotation (0,0,0,-90deg,...
mrpt::img::CImage intensityImage
If hasIntensityImage=true, a color or gray-level intensity image of the same size than "rangeImage".
bool hasRangeImage
true means the field rangeImage contains valid data
mrpt::math::CMatrix rangeImage
If hasRangeImage=true, a matrix of floats with the range data as captured by the camera (in meters)
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot.
mrpt::img::TCamera cameraParamsIntensity
Projection parameters of the intensity (graylevel or RGB) camera.
bool range_is_depth
true: Kinect-like ranges: entries of rangeImage are distances along the +X axis; false: Ranges in ran...
An adapter to different kinds of point cloud object.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:87
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:230
mrpt::math::CArrayDouble< 3 > m_coords
The translation vector [x,y,z] access directly or with x(), y(), z() setter/getter methods.
Definition: CPose3D.h:96
void composeFrom(const CPose3D &A, const CPose3D &B)
Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids th...
Definition: CPose3D.cpp:565
MATRIX44 getHomogeneousMatrixVal() const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
Definition: CPoseOrPoint.h:275
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
Definition: exceptions.h:153
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
const GLubyte * c
Definition: glext.h:6313
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:3721
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23
This base provides a set of functions for maths stuff.
void homogeneousMatrixInverse(const MATRIXLIKE1 &M, MATRIXLIKE2 &out_inverse_M)
Efficiently compute the inverse of a 4x4 homogeneous matrix by only transposing the rotation 3x3 part...
void do_project_3d_pointcloud(const int H, const int W, const float *kys, const float *kzs, const mrpt::math::CMatrix &rangeImage, mrpt::opengl::PointCloudAdapter< POINTMAP > &pca, std::vector< uint16_t > &idxs_x, std::vector< uint16_t > &idxs_y, const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE)
void do_project_3d_pointcloud_SSE2(const int H, const int W, const float *kys, const float *kzs, const mrpt::math::CMatrix &rangeImage, mrpt::opengl::PointCloudAdapter< POINTMAP > &pca, std::vector< uint16_t > &idxs_x, std::vector< uint16_t > &idxs_y, const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE)
void project3DPointsFromDepthImageInto(mrpt::obs::CObservation3DRangeScan &src_obs, POINTMAP &dest_pointcloud, const mrpt::obs::T3DPointsProjectionParams &projectParams, const mrpt::obs::TRangeImageFilterParams &filterParams)
unsigned char uint8_t
Definition: rptypes.h:41
A RGB color - 8bit.
Definition: TColor.h:21
uint8_t B
Definition: TColor.h:46
uint8_t G
Definition: TColor.h:46
uint8_t R
Definition: TColor.h:46
Used in CObservation3DRangeScan::project3DPointsFromDepthImageInto()
bool MAKE_ORGANIZED
(Default:false) set to true if you want an organized point cloud
bool PROJ3D_USE_LUT
(Default:true) [Only used when range_is_depth=true] Whether to use a Look-up-table (LUT) to speed up ...
bool takeIntoAccountSensorPoseOnRobot
(Default: false) If false, local (sensor-centric) coordinates of points are generated.
bool MAKE_DENSE
(Default:true) set to false if your point cloud can contain undefined values
bool USE_SSE2
(Default:true) If possible, use SSE2 optimized code.
const mrpt::poses::CPose3D * robotPoseInTheWorld
(Default: nullptr) Read takeIntoAccountSensorPoseOnRobot
Mainly for internal use within CObservation3DRangeScan::project3DPointsFromDepthImageInto()
bool do_range_filter(size_t r, size_t c, const float D) const
Returns true if the point (r,c) with depth D passes all filters.
Used in CObservation3DRangeScan::project3DPointsFromDepthImageInto()
bool rangeCheckBetween
Only used if both rangeMask_min and rangeMask_max are present.
const mrpt::math::CMatrix * rangeMask_min
(Default: nullptr) If provided, each data range will be tested to be greater-than (rangeMask_min) or ...
const mrpt::math::CMatrix * rangeMask_max



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST