Main MRPT website > C++ reference for MRPT 1.5.7
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-2017, 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/utils/round.h> // round()
13 
14 namespace mrpt {
15 namespace obs {
16 namespace detail {
17  // Auxiliary functions which implement SSE-optimized proyection of 3D point cloud:
18  template <class POINTMAP> void do_project_3d_pointcloud(const int H,const int W,const float *kys,const float *kzs,const mrpt::math::CMatrix &rangeImage, mrpt::utils::PointCloudAdapter<POINTMAP> &pca, std::vector<uint16_t> &idxs_x, std::vector<uint16_t> &idxs_y,const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE, const int DECIM);
19  template <class POINTMAP> void do_project_3d_pointcloud_SSE2(const int H,const int W,const float *kys,const float *kzs,const mrpt::math::CMatrix &rangeImage, mrpt::utils::PointCloudAdapter<POINTMAP> &pca, std::vector<uint16_t> &idxs_x, std::vector<uint16_t> &idxs_y,const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE);
20 
21  template <typename POINTMAP, bool isDepth>
22  inline void range2XYZ(
25  const mrpt::obs::TRangeImageFilterParams& fp, const int H, const int W)
26  {
27  /* range_is_depth = false :
28  * Ky = (r_cx - c)/r_fx
29  * Kz = (r_cy - r)/r_fy
30  *
31  * x(i) = rangeImage(r,c) / sqrt( 1 + Ky^2 + Kz^2 )
32  * y(i) = Ky * x(i)
33  * z(i) = Kz * x(i)
34  */
35  const float r_cx = src_obs.cameraParams.cx();
36  const float r_cy = src_obs.cameraParams.cy();
37  const float r_fx_inv = 1.0f / src_obs.cameraParams.fx();
38  const float r_fy_inv = 1.0f / src_obs.cameraParams.fy();
39  TRangeImageFilter rif(fp);
40  size_t idx = 0;
41  for (int r = 0; r < H; r++)
42  for (int c = 0; c < W; c++)
43  {
44  const float D = src_obs.rangeImage.coeff(r, c);
45  if (rif.do_range_filter(r, c, D))
46  {
47  const float Ky = (r_cx - c) * r_fx_inv;
48  const float Kz = (r_cy - r) * r_fy_inv;
49  pca.setPointXYZ(
50  idx,
51  isDepth ? D : D / std::sqrt(1 + Ky * Ky + Kz * Kz), // x
52  Ky * D, // y
53  Kz * D // z
54  );
55  src_obs.points3D_idxs_x[idx] = c;
56  src_obs.points3D_idxs_y[idx] = r;
57  ++idx;
58  }
59  }
60  pca.resize(idx); // Actual number of valid pts
61  }
62 
63  template <typename POINTMAP, bool isDepth>
64  inline void range2XYZ_LUT(
68  const mrpt::obs::TRangeImageFilterParams& fp, const int H, const int W,
69  const int DECIM = 1)
70  {
71  const size_t WH = W * H;
72  if (src_obs.m_3dproj_lut.prev_camParams != src_obs.cameraParams ||
73  WH != size_t(src_obs.m_3dproj_lut.Kys.size()))
74  {
75  src_obs.m_3dproj_lut.prev_camParams = src_obs.cameraParams;
76  src_obs.m_3dproj_lut.Kys.resize(WH);
77  src_obs.m_3dproj_lut.Kzs.resize(WH);
78 
79  const float r_cx = src_obs.cameraParams.cx();
80  const float r_cy = src_obs.cameraParams.cy();
81  const float r_fx_inv = 1.0f / src_obs.cameraParams.fx();
82  const float r_fy_inv = 1.0f / src_obs.cameraParams.fy();
83 
84  float* kys = &src_obs.m_3dproj_lut.Kys[0];
85  float* kzs = &src_obs.m_3dproj_lut.Kzs[0];
86  for (int r = 0; r < H; r++)
87  for (int c = 0; c < W; c++)
88  {
89  *kys++ = (r_cx - c) * r_fx_inv;
90  *kzs++ = (r_cy - r) * r_fy_inv;
91  }
92  } // end update LUT.
93 
94  ASSERT_EQUAL_(WH, size_t(src_obs.m_3dproj_lut.Kys.size()));
95  ASSERT_EQUAL_(WH, size_t(src_obs.m_3dproj_lut.Kzs.size()));
96  float* kys = &src_obs.m_3dproj_lut.Kys[0];
97  float* kzs = &src_obs.m_3dproj_lut.Kzs[0];
98 
99  if (fp.rangeMask_min)
100  { // sanity check:
101  ASSERT_EQUAL_(fp.rangeMask_min->cols(), src_obs.rangeImage.cols());
102  ASSERT_EQUAL_(fp.rangeMask_min->rows(), src_obs.rangeImage.rows());
103  }
104  if (fp.rangeMask_max)
105  { // sanity check:
106  ASSERT_EQUAL_(fp.rangeMask_max->cols(), src_obs.rangeImage.cols());
107  ASSERT_EQUAL_(fp.rangeMask_max->rows(), src_obs.rangeImage.rows());
108  }
109  #if MRPT_HAS_SSE2
110  // if image width is not 8*N, use standard method
111  if ((W & 0x07) == 0 && pp.USE_SSE2 && DECIM == 1)
113  H, W, kys, kzs, src_obs.rangeImage, pca, src_obs.points3D_idxs_x,
114  src_obs.points3D_idxs_y, fp, pp.MAKE_DENSE);
115  else
116  #endif
118  H, W, kys, kzs, src_obs.rangeImage, pca, src_obs.points3D_idxs_x,
119  src_obs.points3D_idxs_y, fp, pp.MAKE_DENSE, DECIM);
120  }
121 
122  template <class POINTMAP>
124  mrpt::obs::CObservation3DRangeScan& src_obs, POINTMAP& dest_pointcloud,
127  {
128  using namespace mrpt::math;
129 
130  if (!src_obs.hasRangeImage) return;
131 
132  mrpt::utils::PointCloudAdapter<POINTMAP> pca(dest_pointcloud);
133 
134  // ------------------------------------------------------------
135  // Stage 1/3: Create 3D point cloud local coordinates
136  // ------------------------------------------------------------
137  const int W = src_obs.rangeImage.cols();
138  const int H = src_obs.rangeImage.rows();
139  ASSERT_(W != 0 && H != 0);
140  const size_t WH = W * H;
141 
142  if (pp.decimation == 1)
143  {
144  // No decimation: one point per range image pixel
145 
146  // This is to make sure points3D_idxs_{x,y} have the expected sizes
147  src_obs.resizePoints3DVectors(WH);
148  // Reserve memory for 3D points. It will be later resized again to the
149  // actual number of valid points
150  pca.resize(WH);
151  //if (pp.MAKE_DENSE) pca.setDimensions(H, W);
152  if (src_obs.range_is_depth)
153  {
154  // range_is_depth = true
155  // Use cached tables?
156  if (pp.PROJ3D_USE_LUT)
157  range2XYZ_LUT<POINTMAP, true>(pca, src_obs, pp, fp, H, W);
158  else
159  range2XYZ<POINTMAP, true>(pca, src_obs, fp, H, W);
160  }
161  else
162  range2XYZ<POINTMAP, false>(pca, src_obs, fp, H, W);
163  }
164  else
165  {
166  // Decimate range image:
167  const auto DECIM = pp.decimation;
168  ASSERTMSG_(
169  (W % DECIM) == 0 && (H % DECIM == 0),
170  "Width/Height are not an exact multiple of decimation");
171  const int Wd = W / DECIM;
172  const int Hd = H / DECIM;
173  ASSERT_(Wd != 0 && Hd != 0);
174  const size_t WHd = Wd * Hd;
175 
176  src_obs.resizePoints3DVectors(WHd);
177  pca.resize(WHd);
178  //if (pp.MAKE_DENSE) pca.setDimensions(Hd, Wd);
179  ASSERTMSG_(
180  src_obs.range_is_depth && pp.PROJ3D_USE_LUT,
181  "Decimation only available if range_is_depth && PROJ3D_USE_LUT");
182  range2XYZ_LUT<POINTMAP, true>(pca, src_obs, pp, fp, H, W, DECIM);
183  }
184 
185  // -------------------------------------------------------------
186  // Stage 2/3: Project local points into RGB image to get colors
187  // -------------------------------------------------------------
188  if (src_obs.hasIntensityImage)
189  {
190  const int imgW = src_obs.intensityImage.getWidth();
191  const int imgH = src_obs.intensityImage.getHeight();
192  const bool hasColorIntensityImg = src_obs.intensityImage.isColor();
193 
194  const float cx = src_obs.cameraParamsIntensity.cx();
195  const float cy = src_obs.cameraParamsIntensity.cy();
196  const float fx = src_obs.cameraParamsIntensity.fx();
197  const float fy = src_obs.cameraParamsIntensity.fy();
198 
199  // Unless we are in a special case (both depth & RGB images coincide)...
200  const bool isDirectCorresp = src_obs.doDepthAndIntensityCamerasCoincide();
201 
202  // ...precompute the inverse of the pose transformation out of the loop,
203  // store as a 4x4 homogeneous matrix to exploit SSE optimizations below:
205  if (!isDirectCorresp)
206  {
211  R_inv,t_inv);
212 
213  T_inv(3,3)=1;
214  T_inv.block<3,3>(0,0)=R_inv.cast<float>();
215  T_inv.block<3,1>(0,3)=t_inv.cast<float>();
216  }
217 
218  Eigen::Matrix<float,4,1> pt_wrt_color, pt_wrt_depth;
219  pt_wrt_depth[3]=1;
220 
221  mrpt::utils::TColor pCol;
222 
223  // For each local point:
224  const size_t nPts = pca.size();
225  for (size_t i=0;i<nPts;i++)
226  {
227  int img_idx_x, img_idx_y; // projected pixel coordinates, in the RGB image plane
228  bool pointWithinImage = false;
229  if (isDirectCorresp)
230  {
231  pointWithinImage=true;
232  img_idx_x = src_obs.points3D_idxs_x[i];
233  img_idx_y = src_obs.points3D_idxs_y[i];
234  }
235  else
236  {
237  // Project point, which is now in "pca" in local coordinates wrt the depth camera, into the intensity camera:
238  pca.getPointXYZ(i,pt_wrt_depth[0],pt_wrt_depth[1],pt_wrt_depth[2]);
239  pt_wrt_color.noalias() = T_inv*pt_wrt_depth;
240 
241  // Project to image plane:
242  if (pt_wrt_color[2]) {
243  img_idx_x = mrpt::utils::round( cx + fx * pt_wrt_color[0]/pt_wrt_color[2] );
244  img_idx_y = mrpt::utils::round( cy + fy * pt_wrt_color[1]/pt_wrt_color[2] );
245  pointWithinImage=
246  img_idx_x>=0 && img_idx_x<imgW &&
247  img_idx_y>=0 && img_idx_y<imgH;
248  }
249  }
250 
251  if (pointWithinImage)
252  {
253  if (hasColorIntensityImg) {
254  const uint8_t *c= src_obs.intensityImage.get_unsafe(img_idx_x, img_idx_y, 0);
255  pCol.R = c[2];
256  pCol.G = c[1];
257  pCol.B = c[0];
258  }
259  else{
260  uint8_t c= *src_obs.intensityImage.get_unsafe(img_idx_x, img_idx_y, 0);
261  pCol.R = pCol.G = pCol.B = c;
262  }
263  }
264  else
265  {
266  pCol.R = pCol.G = pCol.B = 255;
267  }
268  // Set color:
269  pca.setPointRGBu8(i,pCol.R,pCol.G,pCol.B);
270  } // end for each point
271  } // end if src_obs has intensity image
272 
273  // ...
274 
275  // ------------------------------------------------------------
276  // Stage 3/3: Apply 6D transformations
277  // ------------------------------------------------------------
279  {
280  mrpt::poses::CPose3D transf_to_apply; // Either ROBOTPOSE or ROBOTPOSE(+)SENSORPOSE or SENSORPOSE
282  transf_to_apply = src_obs.sensorPose;
283  if (pp.robotPoseInTheWorld)
284  transf_to_apply.composeFrom(*pp.robotPoseInTheWorld, mrpt::poses::CPose3D(transf_to_apply));
285 
286  const mrpt::math::CMatrixFixedNumeric<float,4,4> HM = transf_to_apply.getHomogeneousMatrixVal().cast<float>();
287  Eigen::Matrix<float,4,1> pt, pt_transf;
288  pt[3]=1;
289 
290  const size_t nPts = pca.size();
291  for (size_t i=0;i<nPts;i++)
292  {
293  pca.getPointXYZ(i,pt[0],pt[1],pt[2]);
294  pt_transf.noalias() = HM*pt;
295  pca.setPointXYZ(i,pt_transf[0],pt_transf[1],pt_transf[2]);
296  }
297  }
298  } // end of project3DPointsFromDepthImageInto
299 
300  // Auxiliary functions which implement (un)projection of 3D point clouds:
301  template <class POINTMAP>
303  const int H, const int W, const float* kys, const float* kzs,
304  const mrpt::math::CMatrix& rangeImage,
306  std::vector<uint16_t>& idxs_x, std::vector<uint16_t>& idxs_y,
307  const mrpt::obs::TRangeImageFilterParams& fp, bool MAKE_DENSE,
308  const int DECIM)
309  {
310  TRangeImageFilter rif(fp);
311  // Preconditions: minRangeMask() has the right size
312  size_t idx = 0;
313  if (DECIM == 1)
314  {
315  for (int r = 0; r < H; r++)
316  for (int c = 0; c < W; c++)
317  {
318  const float D = rangeImage.coeff(r, c);
319  // LUT projection coefs:
320  const auto ky = *kys++, kz = *kzs++;
321  if (!rif.do_range_filter(r, c, D))
322  {
323  if (!MAKE_DENSE) pca.setInvalidPoint(idx++);
324  continue;
325  }
326  pca.setPointXYZ(idx, D /*x*/, ky * D /*y*/, kz * D /*z*/);
327  idxs_x[idx] = c;
328  idxs_y[idx] = r;
329  ++idx;
330  }
331  }
332  else
333  {
334  const int Hd = H / DECIM, Wd = W / DECIM;
335 
336  for (int rd = 0; rd < Hd; rd++)
337  for (int cd = 0; cd < Wd; cd++)
338  {
339  bool valid_pt = false;
340  float min_d = std::numeric_limits<float>::max();
341  for (int rb = 0; rb < DECIM; rb++)
342  for (int cb = 0; cb < DECIM; cb++)
343  {
344  const auto r = rd * DECIM + rb, c = cd * DECIM + cb;
345  const float D = rangeImage.coeff(r, c);
346  if (rif.do_range_filter(r, c, D))
347  {
348  valid_pt = true;
349  if (D < min_d) min_d = D;
350  }
351  }
352  if (!valid_pt)
353  {
354  if (!MAKE_DENSE) pca.setInvalidPoint(idx++);
355  continue;
356  }
357  const auto eq_r = rd * DECIM + DECIM / 2,
358  eq_c = cd * DECIM + DECIM / 2;
359  const auto ky = kys[eq_c + eq_r * W], kz = kzs[eq_c + eq_r * W];
360  pca.setPointXYZ(
361  idx, min_d /*x*/, ky * min_d /*y*/, kz * min_d /*z*/);
362  idxs_x[idx] = eq_c;
363  idxs_y[idx] = eq_r;
364  ++idx;
365  }
366  }
367  pca.resize(idx);
368  }
369 
370  // Auxiliary functions which implement (un)projection of 3D point clouds:
371  template <class POINTMAP>
372  inline void do_project_3d_pointcloud_SSE2(const int H,const int W,const float *kys,const float *kzs,const mrpt::math::CMatrix &rangeImage, mrpt::utils::PointCloudAdapter<POINTMAP> &pca, std::vector<uint16_t> &idxs_x, std::vector<uint16_t> &idxs_y,const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE)
373  {
374  #if MRPT_HAS_SSE2
375  // Preconditions: minRangeMask() has the right size
376  // Use optimized version:
377  const int W_4 = W >> 2; // /=4 , since we process 4 values at a time.
378  size_t idx=0;
379  MRPT_ALIGN16 float xs[4],ys[4],zs[4];
380  const __m128 D_zeros = _mm_set_ps(.0f,.0f,.0f,.0f);
381  const __m128 xormask = (filterParams.rangeCheckBetween) ?
382  _mm_cmpneq_ps(D_zeros,D_zeros) : // want points BETWEEN min and max to be valid
383  _mm_cmpeq_ps(D_zeros,D_zeros); // want points OUTSIDE of min and max to be valid
384  for (int r=0;r<H;r++)
385  {
386  const float *D_ptr = &rangeImage.coeffRef(r,0); // Matrices are 16-aligned
387  const float *Dgt_ptr = !filterParams.rangeMask_min ? NULL : &filterParams.rangeMask_min->coeffRef(r,0);
388  const float *Dlt_ptr = !filterParams.rangeMask_max ? NULL : &filterParams.rangeMask_max->coeffRef(r,0);
389 
390  for (int c=0;c<W_4;c++)
391  {
392  const __m128 D = _mm_load_ps(D_ptr);
393  const __m128 nz_mask = _mm_cmpgt_ps(D, D_zeros);
394  __m128 valid_range_mask;
395  if (!filterParams.rangeMask_min && !filterParams.rangeMask_max)
396  { // No filter: just skip D=0 points
397  valid_range_mask = nz_mask;
398  }
399  else
400  {
401  if (!filterParams.rangeMask_min || !filterParams.rangeMask_max)
402  { // Only one filter
403  if (filterParams.rangeMask_min)
404  {
405  const __m128 Dmin = _mm_load_ps(Dgt_ptr);
406  valid_range_mask = _mm_and_ps(_mm_cmpgt_ps(D, Dmin ), _mm_cmpgt_ps(Dmin, D_zeros));
407  }
408  else
409  {
410  const __m128 Dmax = _mm_load_ps(Dlt_ptr);
411  valid_range_mask = _mm_and_ps(_mm_cmplt_ps(D, Dmax ), _mm_cmpgt_ps(Dmax, D_zeros));
412  }
413  valid_range_mask = _mm_and_ps(valid_range_mask, nz_mask ); // Filter out D=0 points
414  }
415  else
416  {
417  // We have both: D>Dmin and D<Dmax conditions, with XOR to optionally invert the selection:
418  const __m128 Dmin = _mm_load_ps(Dgt_ptr);
419  const __m128 Dmax = _mm_load_ps(Dlt_ptr);
420 
421  const __m128 gt_mask = _mm_cmpgt_ps(D, Dmin );
422  const __m128 lt_mask = _mm_and_ps( _mm_cmplt_ps(D, Dmax), nz_mask ); // skip points at zero
423  valid_range_mask = _mm_and_ps(gt_mask, lt_mask ); // (D>Dmin && D<Dmax)
424  valid_range_mask = _mm_xor_ps(valid_range_mask, xormask );
425  // Add the case of D_min & D_max = 0 (no filtering)
426  valid_range_mask = _mm_or_ps(valid_range_mask, _mm_and_ps(_mm_cmpeq_ps(Dmin,D_zeros),_mm_cmpeq_ps(Dmax,D_zeros)) );
427  // Finally, ensure no invalid ranges get thru:
428  valid_range_mask = _mm_and_ps(valid_range_mask, nz_mask );
429  }
430  }
431  const int valid_range_maski = _mm_movemask_epi8(_mm_castps_si128(valid_range_mask)); // 0x{f|0}{f|0}{f|0}{f|0}
432  if (valid_range_maski!=0) // Any of the 4 values is valid?
433  {
434  const __m128 KY = _mm_load_ps(kys);
435  const __m128 KZ = _mm_load_ps(kzs);
436 
437  _mm_storeu_ps(xs , D);
438  _mm_storeu_ps(ys , _mm_mul_ps(KY,D));
439  _mm_storeu_ps(zs , _mm_mul_ps(KZ,D));
440 
441  for (int q=0;q<4;q++)
442  if ((valid_range_maski & (1<<(q*4))) !=0) {
443  pca.setPointXYZ(idx,xs[q],ys[q],zs[q]);
444  idxs_x[idx]=(c<<2)+q;
445  idxs_y[idx]=r;
446  ++idx;
447  }
448  else if (!MAKE_DENSE)
449  {
450  pca.setInvalidPoint(idx);
451  ++idx;
452  }
453  }
454  else if (!MAKE_DENSE)
455  {
456  for( int q=0; q<4; q++)
457  {
458  pca.setInvalidPoint(idx);
459  ++idx;
460  }
461  }
462  D_ptr+=4;
463  if (Dgt_ptr) Dgt_ptr+=4;
464  if (Dlt_ptr) Dlt_ptr+=4;
465  kys+=4;
466  kzs+=4;
467  }
468  }
469  pca.resize(idx);
470  #endif
471  }
472 
473 } // End of namespace
474 } // End of namespace
475 } // End of namespace
476 #endif
A numeric matrix of compile-time fixed size.
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:31
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 ...
mrpt::utils::TCamera cameraParamsIntensity
Projection parameters of the intensity (graylevel or RGB) camera.
mrpt::utils::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,...
std::vector< uint16_t > points3D_idxs_y
//!< If hasPoints3D=true, the (x,y) pixel coordinates for each (X,Y,Z) point in points3D_x,...
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::utils::CImage intensityImage
If hasIntensityImage=true, a color or gray-level intensity image of the same size than "rangeImage".
static TCached3DProjTables m_3dproj_lut
3D point cloud projection look-up-table
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot.
bool range_is_depth
true: Kinect-like ranges: entries of rangeImage are distances along the +X axis; false: Ranges in ran...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:73
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:176
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
Definition: CPose3D.h:173
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:81
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:595
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
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:898
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
Definition: CImage.cpp:884
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
Definition: CImage.cpp:855
An adapter to different kinds of point cloud object.
Definition: adapters.h:38
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Definition: TCamera.h:154
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:158
double cy() const
Get the value of the principal point y-coordinate (in pixels).
Definition: TCamera.h:156
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:160
const GLubyte * c
Definition: glext.h:5590
GLdouble GLdouble GLdouble r
Definition: glext.h:3618
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:3626
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:26
#define ASSERT_EQUAL_(__A, __B)
Definition: mrpt_macros.h:281
#define ASSERT_(f)
Definition: mrpt_macros.h:278
#define MRPT_ALIGN16
Definition: mrpt_macros.h:138
#define ASSERTMSG_(f, __ERROR_MSG)
Definition: mrpt_macros.h:277
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:20
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 range2XYZ(mrpt::utils::PointCloudAdapter< POINTMAP > &pca, mrpt::obs::CObservation3DRangeScan &src_obs, const mrpt::obs::TRangeImageFilterParams &fp, const int H, const int W)
void project3DPointsFromDepthImageInto(mrpt::obs::CObservation3DRangeScan &src_obs, POINTMAP &dest_pointcloud, const mrpt::obs::T3DPointsProjectionParams &projectParams, const mrpt::obs::TRangeImageFilterParams &filterParams)
void do_project_3d_pointcloud_SSE2(const int H, const int W, const float *kys, const float *kzs, const mrpt::math::CMatrix &rangeImage, mrpt::utils::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(const int H, const int W, const float *kys, const float *kzs, const mrpt::math::CMatrix &rangeImage, mrpt::utils::PointCloudAdapter< POINTMAP > &pca, std::vector< uint16_t > &idxs_x, std::vector< uint16_t > &idxs_y, const mrpt::obs::TRangeImageFilterParams &filterParams, bool MAKE_DENSE, const int DECIM)
void range2XYZ_LUT(mrpt::utils::PointCloudAdapter< POINTMAP > &pca, mrpt::obs::CObservation3DRangeScan &src_obs, const mrpt::obs::T3DPointsProjectionParams &pp, const mrpt::obs::TRangeImageFilterParams &fp, const int H, const int W, const int DECIM=1)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
unsigned char uint8_t
Definition: rptypes.h:43
Used in CObservation3DRangeScan::project3DPointsFromDepthImageInto()
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 you want to preserve the organization of the point cloud
bool USE_SSE2
(Default:true) If possible, use SSE2 optimized code.
uint8_t decimation
(Default:1) If !=1, split the range image in blocks of DxD (D=decimation), and only generates one poi...
const mrpt::poses::CPose3D * robotPoseInTheWorld
(Default: NULL) 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: NULL) If provided, each data range will be tested to be greater-than (rangeMask_min) or les...
const mrpt::math::CMatrix * rangeMask_max
A RGB color - 8bit.
Definition: TColor.h:27



Page generated by Doxygen 1.9.1 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at mar 26 may 2026 13:12:03 CEST