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 
mrpt::img::TCamera cameraParams
Projection parameters of the depth camera.
Mainly for internal use within CObservation3DRangeScan::project3DPointsFromDepthImageInto() ...
#define MRPT_MAX_ALIGN_BYTES
void resizePoints3DVectors(const size_t nPoints)
Use this method instead of resizing all three points3D_x, points3D_y & points3D_z to allow the usage ...
const mrpt::poses::CPose3D * robotPoseInTheWorld
(Default: nullptr) Read takeIntoAccountSensorPoseOnRobot
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:163
An adapter to different kinds of point cloud object.
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:3721
std::vector< uint16_t > points3D_idxs_x
If hasPoints3D=true, the (x,y) pixel coordinates for each (X,Y,Z) point in points3D_x, points3D_y, points3D_z.
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:165
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
const mrpt::math::CMatrix * rangeMask_min
(Default: nullptr) If provided, each data range will be tested to be greater-than (rangeMask_min) or ...
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:892
uint8_t B
Definition: TColor.h:46
uint8_t G
Definition: TColor.h:46
Used in CObservation3DRangeScan::project3DPointsFromDepthImageInto()
mrpt::math::CMatrix rangeImage
If hasRangeImage=true, a matrix of floats with the range data as captured by the camera (in meters) ...
unsigned char uint8_t
Definition: rptypes.h:41
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
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)
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:864
mrpt::poses::CPose3D relativePoseIntensityWRTDepth
Relative pose of the intensity camera wrt the depth camera (which is the coordinates origin for this ...
double cy() const
Get the value of the principal point y-coordinate (in pixels).
Definition: TCamera.h:161
An adapter to different kinds of point cloud object.
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
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
Definition: exceptions.h:153
const GLubyte * c
Definition: glext.h:6313
void project3DPointsFromDepthImageInto(mrpt::obs::CObservation3DRangeScan &src_obs, POINTMAP &dest_pointcloud, const mrpt::obs::T3DPointsProjectionParams &projectParams, const mrpt::obs::TRangeImageFilterParams &filterParams)
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
uint8_t R
Definition: TColor.h:46
bool USE_SSE2
(Default:true) If possible, use SSE2 optimized code.
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Definition: TCamera.h:159
bool MAKE_ORGANIZED
(Default:false) set to true if you want an organized point cloud
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:906
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot.
const mrpt::math::CMatrix * rangeMask_max
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...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
static TCached3DProjTables & get_3dproj_lut()
3D point cloud projection look-up-table
MATRIX44 getHomogeneousMatrixVal() const
Returns the corresponding 4x4 homogeneous transformation matrix for the point(translation) or pose (t...
Definition: CPoseOrPoint.h:275
Used in CObservation3DRangeScan::project3DPointsFromDepthImageInto()
bool hasIntensityImage
true means the field intensityImage contains valid data
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 doDepthAndIntensityCamerasCoincide() const
Return true if relativePoseIntensityWRTDepth equals the pure rotation (0,0,0,-90deg,0,-90deg) (with a small comparison epsilon)
A RGB color - 8bit.
Definition: TColor.h:20
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:230
mrpt::img::TCamera cameraParamsIntensity
Projection parameters of the intensity (graylevel or RGB) camera.
bool MAKE_DENSE
(Default:true) set to false if your point cloud can contain undefined values
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:22
bool range_is_depth
true: Kinect-like ranges: entries of rangeImage are distances along the +X axis; false: Ranges in ran...
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)
bool takeIntoAccountSensorPoseOnRobot
(Default: false) If false, local (sensor-centric) coordinates of points are generated.
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, which checks the coordinates.
Definition: CImage.cpp:491
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.
bool rangeCheckBetween
Only used if both rangeMask_min and rangeMask_max are present.
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020