MRPT  1.9.9
COccupancyGridMap2D_io.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "maps-precomp.h" // Precomp header
11 
12 #include <mrpt/core/round.h> // round()
15 #include <mrpt/math/CMatrixF.h>
16 #include <mrpt/random.h>
18 #include <mrpt/system/os.h>
19 
20 using namespace mrpt;
21 using namespace mrpt::maps;
22 using namespace mrpt::tfest;
23 using namespace mrpt::math;
24 using namespace mrpt::obs;
25 using namespace mrpt::random;
26 using namespace mrpt::poses;
27 using namespace mrpt::img;
28 using namespace mrpt::system;
29 using namespace std;
30 
31 /*---------------------------------------------------------------
32  saveAsBitmapFile
33  ---------------------------------------------------------------*/
35 {
37 
38  CImage img;
39  getAsImage(img);
40  return img.saveToFile(file);
41 
42  MRPT_END
43 }
44 
47 {
48 // Version 3: Change to log-odds. The only change is in the loader, when
49 // translating
50 // from older versions.
51 
52 // Version 2: Save OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS/16BITS
53 #ifdef OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS
54  out << uint8_t(8);
55 #else
56  out << uint8_t(16);
57 #endif
58 
59  out << size_x << size_y << x_min << x_max << y_min << y_max << resolution;
60  ASSERT_(size_x * size_y == map.size());
61 
62 #ifdef OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS
63  out.WriteBuffer(&map[0], sizeof(map[0]) * size_x * size_y);
64 #else
65  out.WriteBufferFixEndianness(&map[0], size_x * size_y);
66 #endif
67 
68  // insertionOptions:
69  out << insertionOptions.mapAltitude << insertionOptions.useMapAltitude
70  << insertionOptions.maxDistanceInsertion
71  << insertionOptions.maxOccupancyUpdateCertainty
72  << insertionOptions.considerInvalidRangesAsFreeSpace
73  << insertionOptions.decimation << insertionOptions.horizontalTolerance;
74 
75  // Likelihood:
76  out << (int32_t)likelihoodOptions.likelihoodMethod
77  << likelihoodOptions.LF_stdHit << likelihoodOptions.LF_zHit
78  << likelihoodOptions.LF_zRandom << likelihoodOptions.LF_maxRange
79  << likelihoodOptions.LF_decimation
80  << likelihoodOptions.LF_maxCorrsDistance
81  << likelihoodOptions.LF_alternateAverageMethod
82  << likelihoodOptions.MI_exponent << likelihoodOptions.MI_skip_rays
83  << likelihoodOptions.MI_ratio_max_distance
84  << likelihoodOptions.rayTracing_useDistanceFilter
85  << likelihoodOptions.rayTracing_decimation
86  << likelihoodOptions.rayTracing_stdHit
87  << likelihoodOptions.consensus_takeEachRange
88  << likelihoodOptions.consensus_pow << likelihoodOptions.OWA_weights
89  << likelihoodOptions.enableLikelihoodCache;
90 
91  // Insertion as 3D:
92  out << genericMapParams; // v6
93 
94  // Version 4:
95  out << insertionOptions.CFD_features_gaussian_size
96  << insertionOptions.CFD_features_median_size;
97 
98  // Version: 5;
99  out << insertionOptions.wideningBeamsWithDistance;
100 }
101 
104 {
105  m_is_empty = false;
106 
107  switch (version)
108  {
109  case 0:
110  case 1:
111  case 2:
112  case 3:
113  case 4:
114  case 5:
115  case 6:
116  {
117 #ifdef OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS
118  const uint8_t MyBitsPerCell = 8;
119 #else
120  const uint8_t MyBitsPerCell = 16;
121 #endif
122 
123  uint8_t bitsPerCellStream;
124 
125  // Version 2: OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS/16BITS
126  if (version >= 2)
127  in >> bitsPerCellStream;
128  else
129  bitsPerCellStream =
130  MyBitsPerCell; // Old versinons: hope it's the same...
131 
132  uint32_t new_size_x, new_size_y;
133  float new_x_min, new_x_max, new_y_min, new_y_max;
134  float new_resolution;
135 
136  // resetFeaturesCache();
137 
138  in >> new_size_x >> new_size_y >> new_x_min >> new_x_max >>
139  new_y_min >> new_y_max >> new_resolution;
140 
141  setSize(
142  new_x_min, new_x_max, new_y_min, new_y_max, new_resolution,
143  0.5);
144 
145  ASSERT_(size_x * size_y == map.size());
146 
147  if (bitsPerCellStream == MyBitsPerCell)
148  {
149 // Perfect:
150 #ifdef OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS
151  in.ReadBuffer(&map[0], sizeof(map[0]) * map.size());
152 #else
153  in.ReadBufferFixEndianness(&map[0], map.size());
154 #endif
155  }
156  else
157  {
158 // We must do a conversion...
159 #ifdef OCCUPANCY_GRIDMAP_CELL_SIZE_8BITS
160  // We are 8-bit, stream is 16-bit
161  ASSERT_(bitsPerCellStream == 16);
162  std::vector<uint16_t> auxMap(map.size());
163  in.ReadBuffer(&auxMap[0], sizeof(auxMap[0]) * auxMap.size());
164 
165  size_t i, N = map.size();
166  auto* ptrTrg = (uint8_t*)&map[0];
167  const auto* ptrSrc = (const uint16_t*)&auxMap[0];
168  for (i = 0; i < N; i++) *ptrTrg++ = (*ptrSrc++) >> 8;
169 #else
170  // We are 16-bit, stream is 8-bit
171  ASSERT_(bitsPerCellStream == 8);
172  std::vector<uint8_t> auxMap(map.size());
173  in.ReadBuffer(&auxMap[0], sizeof(auxMap[0]) * auxMap.size());
174 
175  size_t i, N = map.size();
176  uint16_t* ptrTrg = (uint16_t*)&map[0];
177  const uint8_t* ptrSrc = (const uint8_t*)&auxMap[0];
178  for (i = 0; i < N; i++) *ptrTrg++ = (*ptrSrc++) << 8;
179 #endif
180  }
181 
182  // If we are converting an old dump, convert from probabilities to
183  // log-odds:
184  if (version < 3)
185  {
186  size_t i, N = map.size();
187  cellType* ptr = &map[0];
188  for (i = 0; i < N; i++)
189  {
190  double p = cellTypeUnsigned(*ptr) * (1.0f / 0xFF);
191  if (p < 0) p = 0;
192  if (p > 1) p = 1;
193  *ptr++ = p2l(p);
194  }
195  }
196 
197  // For the precomputed likelihood trick:
198  m_likelihoodCacheOutDated = true;
199 
200  if (version >= 1)
201  {
202  // insertionOptions:
203  in >> insertionOptions.mapAltitude >>
204  insertionOptions.useMapAltitude >>
205  insertionOptions.maxDistanceInsertion >>
206  insertionOptions.maxOccupancyUpdateCertainty >>
207  insertionOptions.considerInvalidRangesAsFreeSpace >>
208  insertionOptions.decimation >>
209  insertionOptions.horizontalTolerance;
210 
211  // Likelihood:
212  int32_t i;
213  in >> i;
214  likelihoodOptions.likelihoodMethod =
215  static_cast<TLikelihoodMethod>(i);
216  in >> likelihoodOptions.LF_stdHit >>
217  likelihoodOptions.LF_zHit >> likelihoodOptions.LF_zRandom >>
218  likelihoodOptions.LF_maxRange >>
219  likelihoodOptions.LF_decimation >>
220  likelihoodOptions.LF_maxCorrsDistance >>
221  likelihoodOptions.LF_alternateAverageMethod >>
222  likelihoodOptions.MI_exponent >>
223  likelihoodOptions.MI_skip_rays >>
224  likelihoodOptions.MI_ratio_max_distance >>
225  likelihoodOptions.rayTracing_useDistanceFilter >>
226  likelihoodOptions.rayTracing_decimation >>
227  likelihoodOptions.rayTracing_stdHit >>
228  likelihoodOptions.consensus_takeEachRange >>
229  likelihoodOptions.consensus_pow >>
230  likelihoodOptions.OWA_weights >>
231  likelihoodOptions.enableLikelihoodCache;
232 
233  // Insertion as 3D:
234  if (version >= 6)
235  in >> genericMapParams;
236  else
237  {
238  bool disableSaveAs3DObject;
239  in >> disableSaveAs3DObject;
240  genericMapParams.enableSaveAs3DObject =
241  !disableSaveAs3DObject;
242  }
243  }
244 
245  if (version >= 4)
246  {
247  in >> insertionOptions.CFD_features_gaussian_size >>
248  insertionOptions.CFD_features_median_size;
249  }
250 
251  if (version >= 5)
252  {
253  in >> insertionOptions.wideningBeamsWithDistance;
254  }
255  }
256  break;
257  default:
259  };
260 }
261 
263  const std::string& file, float res, const TPoint2D& origin)
264 {
265  MRPT_START
266 
267  CImage imgFl;
268  if (!imgFl.loadFromFile(file, 0)) return false;
269 
270  m_is_empty = false;
271  return loadFromBitmap(imgFl, res, origin);
272 
273  MRPT_END
274 }
275 
277  const mrpt::img::CImage& imgFl, float res,
278  const mrpt::math::TPoint2D& origin_)
279 {
280  MRPT_START
281 
282  // For the precomputed likelihood trick:
283  m_likelihoodCacheOutDated = true;
284 
285  size_t bmpWidth = imgFl.getWidth();
286  size_t bmpHeight = imgFl.getHeight();
287 
288  if (size_x != bmpWidth || size_y != bmpHeight)
289  {
290  auto origin = origin_;
291  // Middle of bitmap?
292  if (origin.x == std::numeric_limits<double>::max())
293  {
294  origin = mrpt::math::TPoint2D(
295  imgFl.getWidth() / 2.0, imgFl.getHeight() / 2.0);
296  }
297 
298  // Resize grid:
299  float new_x_max = (imgFl.getWidth() - origin.x) * res;
300  float new_x_min = -origin.x * res;
301  float new_y_max = (imgFl.getHeight() - origin.y) * res;
302  float new_y_min = -origin.y * res;
303 
304  setSize(new_x_min, new_x_max, new_y_min, new_y_max, res);
305  }
306 
307  // And load cells content:
308  for (size_t x = 0; x < bmpWidth; x++)
309  for (size_t y = 0; y < bmpHeight; y++)
310  {
311  float f = imgFl.getAsFloat(x, bmpHeight - 1 - y);
312  f = std::max(0.01f, f);
313  f = std::min(0.99f, f);
314  setCell(x, y, f);
315  }
316 
317  m_is_empty = false;
318  return true;
319 
320  MRPT_END
321 }
322 
323 /*---------------------------------------------------------------
324  saveAsBitmapTwoMapsWithCorrespondences
325  ---------------------------------------------------------------*/
327  const std::string& fileName, const COccupancyGridMap2D* m1,
328  const COccupancyGridMap2D* m2, const TMatchingPairList& corrs)
329 {
330  MRPT_START
331 
332  CImage img1, img2;
333  unsigned int i, n, Ay1, Ay2;
334  unsigned int px, py;
335 
336  // The individual maps:
337  // ---------------------------------------------
338  m1->getAsImage(img1, false);
339  m2->getAsImage(img2, false);
340  unsigned int lx1 = img1.getWidth();
341  unsigned int ly1 = img1.getHeight();
342 
343  unsigned int lx2 = img2.getWidth();
344  unsigned int ly2 = img2.getHeight();
345 
346  // The map with the lowest height has to be vertically aligned:
347  if (ly1 > ly2)
348  {
349  Ay1 = 0;
350  Ay2 = (ly1 - ly2) / 2;
351  }
352  else
353  {
354  Ay2 = 0;
355  Ay1 = (ly2 - ly1) / 2;
356  }
357 
358  // Compute the size of the composite image:
359  // ---------------------------------------------
360  CImage img(lx1 + lx2 + 1, max(ly1, ly2), mrpt::img::CH_RGB);
361  img.filledRectangle(
362  0, 0, img.getWidth() - 1, img.getHeight() - 1,
363  TColor::black()); // background: black
364  img.drawImage(0, Ay1, img1);
365  img.drawImage(lx1 + 1, Ay2, img2);
366 
367  // Draw the features:
368  // ---------------------------------------------
369  n = corrs.size();
370  TColor lineColor = TColor::black();
371  for (i = 0; i < n; i++)
372  {
373  // In M1:
374  px = m1->x2idx(corrs[i].this_x);
375  py = Ay1 + ly1 - 1 - m1->y2idx(corrs[i].this_y);
376  img.rectangle(px - 10, py - 10, px + 10, py + 10, lineColor);
377  img.rectangle(px - 11, py - 11, px + 11, py + 11, lineColor);
378 
379  // In M2:
380  px = lx1 + 1 + m2->x2idx(corrs[i].other_x);
381  py = Ay2 + ly2 - 1 - m2->y2idx(corrs[i].other_y);
382  img.rectangle(px - 10, py - 10, px + 10, py + 10, lineColor);
383  img.rectangle(px - 11, py - 11, px + 11, py + 11, lineColor);
384  }
385 
386  // Draw the correspondences as lines:
387  // ---------------------------------------------
388  for (i = 0; i < n; i++)
389  {
390  lineColor = TColor(
391  static_cast<long>(getRandomGenerator().drawUniform(0, 255.0f)),
392  static_cast<long>(getRandomGenerator().drawUniform(0, 255.0f)),
393  static_cast<long>(getRandomGenerator().drawUniform(0, 255.0f)));
394 
395  img.line(
396  m1->x2idx(corrs[i].this_x),
397  // lx1+1+ m1->x2idx( corrs[i].this_x ),
398  Ay1 + ly1 - 1 - m1->y2idx(corrs[i].this_y),
399  lx1 + 1 + m2->x2idx(corrs[i].other_x),
400  Ay2 + ly2 - 1 - m2->y2idx(corrs[i].other_y), lineColor);
401  } // i
402 
403  return img.saveToFile(fileName.c_str());
404 
405  MRPT_END
406 }
407 
408 /*---------------------------------------------------------------
409  saveAsEMFTwoMapsWithCorrespondences
410  ---------------------------------------------------------------*/
412  const std::string& fileName, const COccupancyGridMap2D* m1,
413  const COccupancyGridMap2D* m2, const TMatchingPairList& corrs)
414 {
415  MRPT_START
416 
417  CEnhancedMetaFile emf(fileName, 1);
418  CImage img1, img2;
419  TColor lineColor;
420  unsigned int i, Ay1, Ay2;
421  unsigned int px, py;
422 
423  lineColor = TColor::red();
424 
425 // The individual maps:
426 // ---------------------------------------------
427 #ifdef _WIN32
428  m1->getAsImage(img1, true);
429  m2->getAsImage(img2, true);
430 #else
431  m1->getAsImage(img1, false); // Linux: emulated EMF is different.
432  m2->getAsImage(img2, false);
433 #endif
434  unsigned int lx1 = img1.getWidth();
435  unsigned int ly1 = img1.getHeight();
436  // unsigned int lx2 = img2.getWidth();
437  unsigned int ly2 = img2.getHeight();
438 
439  // The map with the lowest height has to be vertically aligned:
440  if (ly1 > ly2)
441  {
442  Ay1 = 0;
443  Ay2 = (ly1 - ly2) / 2;
444  }
445  else
446  {
447  Ay2 = 0;
448  Ay1 = (ly2 - ly1) / 2;
449  }
450 
451  // Draw the pair of maps:
452  // ---------------------------------------------
453  emf.drawImage(0, Ay1, img1);
454  emf.drawImage(lx1 + 1, Ay2, img2);
455 
456  // Draw the features:
457  // ---------------------------------------------
458  const unsigned int n = corrs.size();
459  lineColor = TColor::black();
460  for (i = 0; i < n; i++)
461  {
462  // In M1:
463  px = m1->x2idx(corrs[i].this_x);
464  py = Ay1 + ly1 - 1 - m1->y2idx(corrs[i].this_y);
465  emf.rectangle(px - 10, py - 10, px + 10, py + 10, lineColor);
466  emf.rectangle(px - 11, py - 11, px + 11, py + 11, lineColor);
467 
468  // In M2:
469  px = lx1 + 1 + m2->x2idx(corrs[i].other_x);
470  py = Ay2 + ly2 - 1 - m2->y2idx(corrs[i].other_y);
471  emf.rectangle(px - 10, py - 10, px + 10, py + 10, lineColor);
472  emf.rectangle(px - 11, py - 11, px + 11, py + 11, lineColor);
473  }
474 
475  /** /
476  // Draw the correspondences as lines:
477  // ---------------------------------------------
478  for (i=0;i<n;i++)
479  {
480  lineColor =
481  ((unsigned long)RandomUni(0,255.0f)) +
482  (((unsigned long)RandomUni(0,255.0f)) << 8 ) +
483  (((unsigned long)RandomUni(0,255.0f)) << 16 );
484 
485  emf.line(
486  m1->x2idx( corrs[i].this_x ),
487  Ay1+ly1-1- m1->y2idx( corrs[i].this_y ),
488  lx1+1+ m2->x2idx( corrs[i].other_x ),
489  Ay2+ly2-1-m2->y2idx( corrs[i].other_y ),
490  lineColor);
491  } // i
492  / **/
493 
494  // Draw the correspondences as text labels:
495  // ---------------------------------------------
496  char str[100];
497  for (i = 0; i < n; i++)
498  {
499  os::sprintf(str, 100, "%i", i);
500 
501  emf.textOut(
502  m1->x2idx(corrs[i].this_x) - 10,
503  Ay1 + ly1 - 1 - m1->y2idx(corrs[i].this_y) - 25, str,
504  TColor::black());
505 
506  emf.textOut(
507  lx1 + 1 + m2->x2idx(corrs[i].other_x) - 10,
508  Ay2 + ly2 - 1 - m2->y2idx(corrs[i].other_y) - 25, str,
509  TColor::black());
510  } // i
511 
512  return true;
513 
514  MRPT_END
515 }
516 
518  const std::string& filNamePrefix) const
519 {
520  std::string fil(filNamePrefix + std::string(".png"));
521  saveAsBitmapFile(fil);
522 
523  fil = filNamePrefix + std::string("_limits.txt");
524  CMatrixF LIMITS(1, 4);
525  LIMITS(0, 0) = x_min;
526  LIMITS(0, 1) = x_max;
527  LIMITS(0, 2) = y_min;
528  LIMITS(0, 3) = y_max;
529  LIMITS.saveToTextFile(
530  fil, MATRIX_FORMAT_FIXED, false /* add mrpt header */,
531  "% Grid limits: [x_min x_max y_min y_max]\n");
532 }
A namespace of pseudo-random numbers generators of diferent distributions.
This class represents a Windows Enhanced Meta File (EMF) for generating and saving graphics...
#define MRPT_START
Definition: exceptions.h:241
#define min(a, b)
unsigned __int16 uint16_t
Definition: rptypes.h:47
unsigned char red[10]
Definition: PbMapMaker.cpp:810
void saveMetricMapRepresentationToFile(const std::string &filNamePrefix) const override
This virtual method saves the map to a file "filNamePrefix"+< some_file_extension >...
OccGridCellTraits::cellTypeUnsigned cellTypeUnsigned
TLikelihoodMethod
The type for selecting a likelihood computation method.
GLenum GLsizei n
Definition: glext.h:5136
void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running arch...
Definition: CArchive.h:129
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:877
bool loadFromBitmapFile(const std::string &file, float resolution, const mrpt::math::TPoint2D &origin=mrpt::math::TPoint2D(std::numeric_limits< double >::max(), std::numeric_limits< double >::max()))
Load the gridmap from a image in a file (the format can be any supported by CImage::loadFromFile).
STL namespace.
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
Definition: CArchive.cpp:49
static bool saveAsEMFTwoMapsWithCorrespondences(const std::string &fileName, const COccupancyGridMap2D *m1, const COccupancyGridMap2D *m2, const mrpt::tfest::TMatchingPairList &corrs)
Saves a composite image with two gridmaps and numbers for the correspondences between them...
float getAsFloat(unsigned int col, unsigned int row, unsigned int channel) const
Returns the contents of a given pixel at the desired channel, in float format: [0,255]->[0,1] The coordinate origin is pixel(0,0)=top-left corner of the image.
Definition: CImage.cpp:921
void saveToTextFile(const std::string &file, mrpt::math::TMatrixTextFileFormat fileFormat=mrpt::math::MATRIX_FORMAT_ENG, bool appendMRPTHeader=false, const std::string &userHeader=std::string()) const
Saves the vector/matrix to a file compatible with MATLAB/Octave text format.
static bool saveAsBitmapTwoMapsWithCorrespondences(const std::string &fileName, const COccupancyGridMap2D *m1, const COccupancyGridMap2D *m2, const mrpt::tfest::TMatchingPairList &corrs)
Saves a composite image with two gridmaps and lines representing a set of correspondences between the...
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
unsigned char uint8_t
Definition: rptypes.h:44
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:97
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
bool saveAsBitmapFile(const std::string &file) const
Saves the gridmap as a graphical file (BMP,PNG,...).
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:846
GLint GLvoid * img
Definition: glext.h:3769
A list of TMatchingPair.
Definition: TMatchingPair.h:70
This namespace contains representation of robot actions and observations.
bool loadFromBitmap(const mrpt::img::CImage &img, float resolution, const mrpt::math::TPoint2D &origin=mrpt::math::TPoint2D(std::numeric_limits< double >::max(), std::numeric_limits< double >::max()))
Load the gridmap from a image in a file (the format can be any supported by CImage::loadFromFile).
GLsizei const GLchar ** string
Definition: glext.h:4116
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
fixed floating point &#39;f&#39;
A class for storing an occupancy grid map.
void getAsImage(mrpt::img::CImage &img, bool verticalFlip=false, bool forceRGB=false, bool tricolor=false) const
Returns the grid as a 8-bit graylevel image, where each pixel is a cell (output image is RGB only if ...
__int32 int32_t
Definition: rptypes.h:49
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrixF.h:22
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:54
#define MRPT_END
Definition: exceptions.h:245
GLuint in
Definition: glext.h:7391
OccGridCellTraits::cellType cellType
The type of the map cells:
GLenum GLint GLint y
Definition: glext.h:3542
GLuint res
Definition: glext.h:7385
A RGB color - 8bit.
Definition: TColor.h:20
GLenum GLint x
Definition: glext.h:3542
unsigned __int32 uint32_t
Definition: rptypes.h:50
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
Lightweight 2D point.
Definition: TPoint2D.h:31
Functions for estimating the optimal transformation between two frames of references given measuremen...
GLfloat GLfloat p
Definition: glext.h:6398
int x2idx(float x) const
Transform a coordinate value into a cell index.
int sprintf(char *buf, size_t bufSize, const char *format,...) noexcept MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
Definition: os.cpp:191
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:147



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 1de0e027c Sat Sep 14 16:15:22 2019 +0200 at sáb sep 14 16:20:14 CEST 2019