Main MRPT website > C++ reference
MRPT logo
CImage.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-2015, 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 CImage_H
10 #define CImage_H
11 
12 #include <mrpt/utils/utils_defs.h>
14 #include <mrpt/math/eigen_frwds.h>
15 #include <mrpt/utils/CCanvas.h>
16 #include <mrpt/utils/TCamera.h>
17 #include <mrpt/utils/exceptions.h>
18 
19 namespace mrpt
20 {
21  namespace utils
22  {
23  /** Interpolation methods for images.
24  * Used for OpenCV related operations with images, but also with MRPT native classes.
25  * \sa mrpt::utils::CMappedImage, CImage::scaleImage
26  * \ingroup mrpt_base_grp
27  */
29  {
34  };
35 
36  /** For use in mrpt::utils::CImage */
37  typedef int TImageChannels;
38  #define CH_GRAY 1
39  #define CH_RGB 3
40 
41  /** For usage in one of the CImage constructors */
43  {
46  };
47 
48  // This must be added to any CSerializable derived class:
50 
51  /** A class for storing images as grayscale or RGB bitmaps.
52  * File I/O is supported as:
53  * - Binary dump using the CSerializable interface(<< and >> operators), just as most objects
54  * in the MRPT library. This format is not compatible with any standarized image format.
55  * - Saving/loading from files of different formats (bmp,jpg,png,...) using the methods CImage::loadFromFile and CImage::saveToFile.
56  * Available formats are all those supported by OpenCV
57  * - Importing from an XPM array (.xpm file format) using CImage::loadFromXPM
58  * - Importing TGA images. See CImage::loadTGA()
59  *
60  * How to create color/grayscale images:
61  * \code
62  * CImage img1(width, height, CH_GRAY ); // Grayscale image (8U1C)
63  * CImage img2(width, height, CH_RGB ); // RGB image (8U3C)
64  * \endcode
65  *
66  * Additional notes:
67  * - The OpenCV "IplImage" format is used internally for compatibility with all OpenCV functions. Use CImage::getAs<IplImage>() to retrieve the internal structure. Example:
68  * \code
69  * CImage img;
70  * ...
71  * // Call to OpenCV function expecting an "IplImage *" or a "void* arr":
72  * cv::Mat cvImg = cv::cvarrToMat( img.getAs<IplImage>() );
73  * cvFunction( img.getAs<IplImage>(), ... );
74  * \endcode
75  * - Only the unsigned 8-bit storage format for pixels (on each channel) is supported.
76  * - An external storage mode can be enabled by calling CImage::setExternalStorage, useful for storing large collections of image objects in memory while loading the image data itself only for the relevant images at any time.
77  * - To move images from one object to the another, use CImage::copyFastFrom rather than the copy operator =.
78  * - If you are interested in a smart pointer to an image, use:
79  * \code
80  * CImagePtr myImgPtr = CImagePtr( new CImage(...) );
81  * \endcode
82  * - To set a CImage from an OpenCV "IPLImage*", use the methods:
83  * - CImage::loadFromIplImage
84  * - CImage::setFromIplImage
85  * - CImage::CImage(void *IPL)
86  *
87  * Some functions are implemented in MRPT with highly optimized SSE2/SSE3 routines, in suitable platforms and compilers. To
88  * see the list of optimizations refer to \ref sse_optimizations "this page". If optimized versions are not available in some
89  * platform it falls back to default OpenCV methods.
90  *
91  * For many computer vision functions that use CImage as its image data type, see mrpt::vision.
92  *
93  * \note This class acts as a wrapper class to a small subset of OpenCV functions. IplImage is the internal storage structure.
94  *
95  * \sa mrpt::vision, mrpt::vision::CFeatureExtractor, mrpt::vision::CImagePyramid, CSerializable, CCanvas
96  * \ingroup mrpt_base_grp
97  */
98  class BASE_IMPEXP CImage : public mrpt::utils::CSerializable, public CCanvas
99  {
101  public:
102 
103  // ================================================================
104  /** @name Constructors & destructor
105  @{ */
106 
107  /** Default constructor: initialize an 1x1 RGB image. */
108  CImage();
109 
110  /** Constructor for a given image size and type.
111  * Examples:
112  * \code
113  * CImage img1(width, height, CH_GRAY ); // Grayscale image (8U1C)
114  * CImage img2(width, height, CH_RGB ); // RGB image (8U3C)
115  * \endcode
116  */
117  CImage( unsigned int width,
118  unsigned int height,
119  TImageChannels nChannels = CH_RGB,
120  bool originTopLeft = true
121  );
122 
123  /** Copy constructor, makes a full copy of the original image contents (unless it was externally stored, in that case, this new image will just point to the same image file). */
124  CImage( const CImage &o );
125 
126  /** Fast constructor that leaves the image uninitialized (the internal IplImage pointer set to NULL).
127  * Use only when you know the image will be soon be assigned another image.
128  * Example of usage:
129  * \code
130  * CImage myImg(UNINITIALIZED_IMAGE);
131  * \endcode
132  */
133  inline CImage(TConstructorFlags_CImage ) : img(NULL),m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
134  { }
135 
136  /** Fast constructor of a grayscale version of another image, making a <b>reference</b> to the original image if it already was in grayscale, or otherwise creating a new grayscale image and converting the original image into it.
137  * It's <b>very important to keep in mind</b> that the original image can't be destroyed before the new object being created with this constructor.
138  * Example of usage:
139  * \code
140  * void my_func(const CImage &in_img) {
141  * const CImage gray_img(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
142  * // We can now operate on "gray_img" being sure it's in grayscale.
143  * }
144  * \endcode
145  */
146  inline CImage(const CImage& other_img, TConstructorFlags_CImage constructor_flag) : img(NULL),m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
147  {
148  MRPT_UNUSED_PARAM(constructor_flag);
149  if( other_img.isColor() ) other_img.grayscale(*this);
150  else this->setFromImageReadOnly(other_img);
151  }
152 
153  /** Constructor from an IPLImage*, making a copy of the image.
154  * \sa loadFromIplImage, setFromIplImage
155  */
156  CImage( void *iplImage );
157 
158  /** Explicit constructor from a matrix, interpreted as grayscale intensity values, in the range [0,1] (normalized=true) or [0,255] (normalized=false)
159  * \sa setFromMatrix
160  */
161  template <typename Derived>
162  explicit inline CImage(const Eigen::MatrixBase<Derived> &m, bool matrix_is_normalized) : img(NULL),m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
163  {
164  this->setFromMatrix(m,matrix_is_normalized);
165  }
166 
167 
168  /** Destructor: */
169  virtual ~CImage( );
170 
171  /** @} */
172  // ================================================================
173 
174  /** @name Serialization format global flags
175  @{ */
176 
177  /** By default, when storing images through the CSerializable interface, grayscale images will be ZIP compressed if they are larger than 16Kb: this flag can be turn on to disable ZIP compression and gain speed versus occupied space.
178  * (Default = false) */
180 
181  /** By default, when storing images through the CSerializable interface, RGB images are JPEG-compressed to save space. If for some reason you prefer storing RAW image data, disable this feature by setting this flag to true.
182  * (Default = false) */
184 
185  /** Unless DISABLE_JPEG_COMPRESSION=true, this sets the JPEG quality (range 1-100) of serialized RGB images.
186  * (Default = 95) */
188 
189  /** @} */
190 
191  // ================================================================
192  /** @name Manipulate the image contents or size, various computer-vision methods (image filters, undistortion, etc.)
193  @{ */
194 
195  /** Changes the size of the image, erasing previous contents (does NOT scale its current content, for that, see scaleImage).
196  * - nChannels: Can be 3 for RGB images or 1 for grayscale images.
197  * - originTopLeft: Is true if the top-left corner is (0,0). In other case, the reference is the bottom-left corner.
198  * \sa scaleImage
199  */
200  inline void resize(
201  unsigned int width,
202  unsigned int height,
203  TImageChannels nChannels,
204  bool originTopLeft )
205  {
206  changeSize(width,height,nChannels,originTopLeft);
207  }
208 
209  /** Scales this image to a new size, interpolating as needed.
210  * \sa resize, rotateImage
211  */
212  void scaleImage( unsigned int width, unsigned int height, TInterpolationMethod interp = IMG_INTERP_CUBIC );
213 
214  /** Scales this image to a new size, interpolating as needed, saving the new image in a different output object.
215  * \sa resize, rotateImage
216  */
217  void scaleImage( CImage &out_img, unsigned int width, unsigned int height, TInterpolationMethod interp = IMG_INTERP_CUBIC ) const;
218 
219  /** Rotates the image by the given angle around the given center point, with an optional scale factor.
220  * \sa resize, scaleImage
221  */
222  void rotateImage( double angle_radians, unsigned int center_x, unsigned int center_y, double scale = 1.0 );
223 
224  /** Changes the value of the pixel (x,y).
225  * Pixel coordinates starts at the left-top corner of the image, and start in (0,0).
226  * The meaning of the parameter "color" depends on the implementation: it will usually
227  * be a 24bit RGB value (0x00RRGGBB), but it can also be just a 8bit gray level.
228  * This method must support (x,y) values OUT of the actual image size without neither
229  * raising exceptions, nor leading to memory access errors.
230  */
231  void setPixel(int x, int y, size_t color);
232 
233  /** Changes the property of the image stating if the top-left corner (vs. bottom-left) is the coordinate reference.
234  */
235  void setOriginTopLeft(bool val);
236 
237  /** Draws a line.
238  * \param x0 The starting point x coordinate
239  * \param y0 The starting point y coordinate
240  * \param x1 The end point x coordinate
241  * \param y1 The end point y coordinate
242  * \param color The color of the line
243  * \param width The desired width of the line (this is IGNORED in this virtual class)
244  * This method may be redefined in some classes implementing this interface in a more appropiate manner.
245  */
246  virtual void line(
247  int x0,
248  int y0,
249  int x1,
250  int y1,
251  const mrpt::utils::TColor color,
252  unsigned int width = 1,
253  TPenStyle penStyle = psSolid);
254 
255  /** Draws a circle of a given radius.
256  * \param x The center - x coordinate in pixels.
257  * \param y The center - y coordinate in pixels.
258  * \param radius The radius - in pixels.
259  * \param color The color of the circle.
260  * \param width The desired width of the line
261  */
262  void drawCircle(
263  int x,
264  int y,
265  int radius,
266  const mrpt::utils::TColor &color = mrpt::utils::TColor(255,255,255),
267  unsigned int width = 1);
268 
269  void equalizeHistInPlace(); //!< Equalize the image histogram, replacing the original image. \note RGB images are first converted to HSV color space, then equalized for brightness (V)
270  void equalizeHist( CImage &outImg ) const; //!< Equalize the image histogram, saving the new image in the given output object. \note RGB images are first converted to HSV color space, then equalized for brightness (V)
271 
272  /** Returns a new image scaled down to half its original size.
273  * \exception std::exception On odd size
274  * \sa scaleDouble, scaleImage, scaleHalfSmooth
275  */
277  {
279  this->scaleHalf(ret);
280  return ret;
281  }
282 
283  //! \overload
284  void scaleHalf(CImage &out_image) const;
285 
286 
287  /** Returns a new image scaled down to half its original size (averaging between every two rows)
288  * \exception std::exception On odd size
289  * \sa scaleDouble, scaleImage, scaleHalf
290  */
292  {
294  this->scaleHalfSmooth(ret);
295  return ret;
296  }
297 
298  //! \overload
299  void scaleHalfSmooth(CImage &out_image) const;
300 
301 
302  /** Returns a new image scaled up to double its original size.
303  * \exception std::exception On odd size
304  * \sa scaleHalf, scaleImage
305  */
307  {
309  this->scaleDouble(ret);
310  return ret;
311  }
312 
313  //! \overload
314  void scaleDouble(CImage &out_image) const;
315 
316 
317  /** Update a part of this image with the "patch" given as argument.
318  * The "patch" will be "pasted" at the (col,row) coordinates of this image.
319  * \exception std::exception if patch pasted on the pixel (_row, _column) jut out
320  * of the image.
321  * \sa extract_patch
322  */
323  void update_patch(const CImage &patch,
324  const unsigned int col,
325  const unsigned int row);
326 
327  /** Extract a patch from this image, saveing it into "patch" (its previous contents will be overwritten).
328  * The patch to extract starts at (col,row) and has the given dimensions.
329  * \sa update_patch
330  */
331  void extract_patch(
332  CImage &patch,
333  const unsigned int col=0,
334  const unsigned int row=0,
335  const unsigned int width=1,
336  const unsigned int height=1 ) const;
337 
338  /** Computes the correlation coefficient (returned as val), between two images
339  * This function use grayscale images only
340  * img1, img2 must be same size
341  * (by AJOGD @ DEC-2006)
342  */
343  float correlate( const CImage &img2int, int width_init=0, int height_init=0 )const;
344 
345  /** Computes the correlation between this image and another one, encapsulating the openCV function cvMatchTemplate
346  *
347  * \param patch_img The "patch" image, which must be equal, or smaller than "this" image. This function supports gray-scale (1 channel only) images.
348  * \param u_search_ini The "x" coordinate of the search window.
349  * \param v_search_ini The "y" coordinate of the search window.
350  * \param u_search_size The width of the search window.
351  * \param v_search_size The height of the search window.
352  * \param u_max The u coordinate where find the maximun cross correlation value.
353  * \param v_max The v coordinate where find the maximun cross correlation value
354  * \param max_val The maximun value of cross correlation which we can find
355  * \param out_corr_image If a !=NULL pointer is provided, it will be saved here the correlation image. The size of the output image is (this_width-patch_width+1, this_height-patch_height+1 )
356  * Note: By default, the search area is the whole (this) image.
357  * (by AJOGD @ MAR-2007)
358  */
359  void cross_correlation(
360  const CImage &patch_img,
361  size_t &u_max,
362  size_t &v_max,
363  double &max_val,
364  int u_search_ini=-1,
365  int v_search_ini=-1,
366  int u_search_size=-1,
367  int v_search_size=-1,
368  CImage *out_corr_image = NULL
369  )const;
370 
371  /** Computes the correlation matrix between this image and another one.
372  * This implementation uses the 2D FFT for achieving reduced computation time.
373  * \param in_img The "patch" image, which must be equal, or smaller than "this" image. This function supports gray-scale (1 channel only) images.
374  * \param u_search_ini The "x" coordinate of the search window.
375  * \param v_search_ini The "y" coordinate of the search window.
376  * \param u_search_size The width of the search window.
377  * \param v_search_size The height of the search window.
378  * \param out_corr The output for the correlation matrix, which will be "u_search_size" x "v_search_size"
379  * \param biasThisImg This optional parameter is a fixed "bias" value to be substracted to the pixels of "this" image before performing correlation.
380  * \param biasInImg This optional parameter is a fixed "bias" value to be substracted to the pixels of "in_img" image before performing correlation.
381  * Note: By default, the search area is the whole (this) image.
382  * (by JLBC @ JAN-2006)
383  * \sa cross_correlation
384  */
386  const CImage &in_img,
387  math::CMatrixFloat &out_corr,
388  int u_search_ini=-1,
389  int v_search_ini=-1,
390  int u_search_size=-1,
391  int v_search_size=-1,
392  float biasThisImg = 0,
393  float biasInImg = 0
394  ) const;
395 
396 
397  /** Optimize the brightness range of an image without using histogram
398  * Only for one channel images.
399  * \sa equalizeHist
400  */
401  void normalize();
402 
403  /** Flips vertically the image.
404  * \sa swapRB
405  */
406  void flipVertical(bool also_swapRB = false);
407 
408  /** Swaps red and blue channels.
409  * \sa flipVertical
410  */
411  void swapRB();
412 
413  /** Rectify (un-distort) the image according to some camera parameters, and returns an output un-distorted image.
414  * \param out_img The output rectified image
415  * \param cameraParams The input camera params (containing the intrinsic and distortion parameters of the camera)
416  * \sa mrpt::vision::CUndistortMap
417  */
418  void rectifyImage( CImage &out_img, const mrpt::utils::TCamera &cameraParams) const;
419 
420  /** Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coefficients, replacing "this" with the rectified image
421  * \param cameraParams The input camera params (containing the intrinsic and distortion parameters of the camera)
422  * \sa mrpt::vision::CUndistortMap
423  */
424  void rectifyImageInPlace(const mrpt::utils::TCamera &cameraParams );
425 
426  /** Rectify an image (undistorts and rectification) from a stereo pair according to a pair of precomputed rectification maps
427  * \param mapX, mapY [IN] The pre-computed maps of the rectification (should be computed beforehand)
428  * \sa mrpt::vision::CStereoRectifyMap, mrpt::vision::computeStereoRectificationMaps
429  */
430  void rectifyImageInPlace( void *mapX, void *mapY );
431 
432  /** Filter the image with a Median filter with a window size WxW, returning the filtered image in out_img */
433  void filterMedian( CImage &out_img, int W=3 ) const;
434 
435  /** Filter the image with a Median filter with a window size WxH, replacing "this" image by the filtered one. */
436  void filterMedianInPlace( int W=3 );
437 
438  /** Filter the image with a Gaussian filter with a window size WxH, returning the filtered image in out_img */
439  void filterGaussianInPlace( int W = 3, int H = 3 );
440 
441  /** Filter the image with a Gaussian filter with a window size WxH, replacing "this" image by the filtered one. */
442  void filterGaussian( CImage &out_img, int W = 3, int H = 3) const;
443 
444  /** Draw onto this image the detected corners of a chessboard. The length of cornerCoords must be the product of the two check_sizes.
445  *
446  * \param cornerCoords [IN] The pixel coordinates of all the corners.
447  * \param check_size_x [IN] The number of squares, in the X direction
448  * \param check_size_y [IN] The number of squares, in the Y direction
449  *
450  * \return false if the length of cornerCoords is inconsistent (nothing is drawn then).
451  *
452  * \sa mrpt::vision::findChessboardCorners
453  */
454  bool drawChessboardCorners(
455  std::vector<TPixelCoordf> &cornerCoords,
456  unsigned int check_size_x,
457  unsigned int check_size_y,
458  unsigned int lines_width = 1,
459  unsigned int circles_radius = 4
460  );
461 
462  /** Joins two images side-by-side horizontally. Both images must have the same number of rows and be of the same type (i.e. depth and color mode)
463  *
464  * \param im1 [IN] The first image.
465  * \param im2 [IN] The other image.
466  */
467  void joinImagesHorz(
468  const CImage &im1,
469  const CImage &im2 );
470 
471  /** Compute the KLT response at a given pixel (x,y) - Only for grayscale images (for efficiency it avoids converting to grayscale internally).
472  * See KLT_response_optimized for more details on the internal optimizations of this method, but this graph shows a general view:
473  * <img src="KLT_response_performance_SSE2.png" >
474  */
475  float KLT_response(
476  const unsigned int x,
477  const unsigned int y,
478  const unsigned int half_window_size ) const;
479 
480  /** @} */
481  // ================================================================
482 
483 
484 
485  // ================================================================
486  /** @name Copy, move & swap operations
487  @{ */
488 
489  /** Copy operator (if the image is externally stored, the writen image will be such as well).
490  * \sa copyFastFrom
491  */
492  CImage& operator = (const CImage& o);
493 
494  /** Copies from another image, and, if that one is externally stored, the image file will be actually loaded into memory in "this" object.
495  * \sa operator =
496  * \exception CExceptionExternalImageNotFound If the external image couldn't be loaded.
497  */
498  void copyFromForceLoad(const CImage &o);
499 
500  /** Moves an image from another object, erasing the origin image in the process (this is much faster than copying)
501  * \sa operator =
502  */
503  void copyFastFrom( CImage &o );
504 
505  void swap(CImage &o); //!< Very efficient swap of two images (just swap the internal pointers)
506 
507  /** @} */
508  // ================================================================
509 
510 
511  // ================================================================
512  /** @name Access to image contents (IplImage structure and raw pixels).
513  @{ */
514 
515  /** Returns a pointer to a const T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers. */
516  template <typename T> inline const T* getAs() const {
517  makeSureImageIsLoaded();
518  return static_cast<const T*>(img);
519  }
520  /** Returns a pointer to a T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers. */
521  template <typename T> inline T* getAs(){
522  makeSureImageIsLoaded();
523  return static_cast<T*>(img);
524  }
525 
526  /** Access to pixels without checking boundaries - Use normally the () operator better, which checks the coordinates.
527  \sa CImage::operator()
528  */
529  unsigned char* get_unsafe(
530  unsigned int col,
531  unsigned int row,
532  unsigned int channel=0) const;
533 
534  /** Returns the contents of a given pixel at the desired channel, in float format: [0,255]->[0,1]
535  * The coordinate origin is pixel(0,0)=top-left corner of the image.
536  * \exception std::exception On pixel coordinates out of bounds
537  * \sa operator()
538  */
539  float getAsFloat(unsigned int col, unsigned int row, unsigned int channel) const;
540 
541  /** Returns the contents of a given pixel (for gray-scale images, in color images the gray scale equivalent is computed for the pixel), in float format: [0,255]->[0,1]
542  * The coordinate origin is pixel(0,0)=top-left corner of the image.
543  * \exception std::exception On pixel coordinates out of bounds
544  * \sa operator()
545  */
546  float getAsFloat(unsigned int col, unsigned int row) const;
547 
548  /** Returns a pointer to a given pixel information.
549  * The coordinate origin is pixel(0,0)=top-left corner of the image.
550  * \exception std::exception On pixel coordinates out of bounds
551  */
552  unsigned char* operator()(unsigned int col, unsigned int row, unsigned int channel = 0) const;
553 
554  /** @} */
555  // ================================================================
556 
557 
558 
559  // ================================================================
560  /** @name Query image properties
561  @{ */
562 
563  /** Returns the width of the image in pixels
564  * \sa getSize
565  */
566  size_t getWidth() const;
567 
568  /** Returns the height of the image in pixels
569  * \sa getSize
570  */
571  size_t getHeight() const;
572 
573  /** Return the size of the image
574  * \sa getWidth, getHeight
575  */
576  void getSize(TImageSize &s) const;
577 
578  /** Return the size of the image
579  * \sa getWidth, getHeight
580  */
581  inline TImageSize getSize() const {
582  TImageSize ret;
583  getSize(ret);
584  return ret;
585  }
586 
587  /** Returns the row stride of the image: this is the number of *bytes* between two consecutive rows. You can access the pointer to the first row with get_unsafe(0,0)
588  * \sa getSize, get_unsafe
589  */
590  size_t getRowStride() const;
591 
592  /** Return the maximum pixel value of the image, as a float value in the range [0,1]
593  * \sa getAsFloat
594  */
595  float getMaxAsFloat() const;
596 
597  /** Returns true if the image is RGB, false if it is grayscale */
598  bool isColor() const;
599 
600  /** Returns true if the coordinates origin is top-left, or false if it is bottom-left */
601  bool isOriginTopLeft() const;
602 
603  /** Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering. \sa setChannelsOrder, swapRB */
604  const char * getChannelsOrder()const;
605 
606  /** Marks the channel ordering in a color image as "RGB" (this doesn't actually modify the image data, just the format description) \sa getChannelsOrder, swapRB */
607  void setChannelsOrder_RGB();
608  /** Marks the channel ordering in a color image as "BGR" (this doesn't actually modify the image data, just the format description) \sa getChannelsOrder, swapRB */
609  void setChannelsOrder_BGR();
610 
611  /** Returns the number of channels, typically 1 (GRAY) or 3 (RGB)
612  * \sa isColor
613  */
614  TImageChannels getChannelCount() const;
615 
616  /** Returns the image as a matrix with pixel grayscale values in the range [0,1]. Matrix indexes in this order: M(row,column)
617  * \param doResize If set to true (default), the output matrix will be always the size of the image at output. If set to false, the matrix will be enlarged to the size of the image, but it will not be cropped if it has room enough (useful for FFT2D,...)
618  * \param x_min The starting "x" coordinate to extract (default=0=the first column)
619  * \param y_min The starting "y" coordinate to extract (default=0=the first row)
620  * \param x_max The final "x" coordinate (inclusive) to extract (default=-1=the last column)
621  * \param y_max The final "y" coordinate (inclusive) to extract (default=-1=the last row)
622  * \sa setFromMatrix
623  */
624  void getAsMatrix(
625  mrpt::math::CMatrixFloat &outMatrix,
626  bool doResize = true,
627  int x_min = 0,
628  int y_min = 0,
629  int x_max = -1,
630  int y_max = -1
631  ) const;
632 
633  /** Returns the image as RGB matrices with pixel values in the range [0,1]. Matrix indexes in this order: M(row,column)
634  * \param doResize If set to true (default), the output matrix will be always the size of the image at output. If set to false, the matrix will be enlarged to the size of the image, but it will not be cropped if it has room enough (useful for FFT2D,...)
635  * \param x_min The starting "x" coordinate to extract (default=0=the first column)
636  * \param y_min The starting "y" coordinate to extract (default=0=the first row)
637  * \param x_max The final "x" coordinate (inclusive) to extract (default=-1=the last column)
638  * \param y_max The final "y" coordinate (inclusive) to extract (default=-1=the last row)
639  * \sa setFromRGBMatrices
640  */
641  void getAsRGBMatrices(
642  mrpt::math::CMatrixFloat &outMatrixR,
643  mrpt::math::CMatrixFloat &outMatrixG,
644  mrpt::math::CMatrixFloat &outMatrixB,
645  bool doResize = true,
646  int x_min = 0,
647  int y_min = 0,
648  int x_max = -1,
649  int y_max = -1
650  ) const;
651 
652  /** Returns the image as a matrix, where the image is "tiled" (repeated) the required number of times to fill the entire size of the matrix on input.
653  */
654  void getAsMatrixTiled( math::CMatrix &outMatrix ) const;
655 
656  /** @} */
657  // ================================================================
658 
659 
660  // ================================================================
661  /** @name External storage-mode methods
662  @{ */
663 
664  /** By using this method the image is marked as referenced to an external file, which will be loaded only under demand.
665  * A CImage with external storage does not consume memory until some method trying to access the image is invoked (e.g. getWidth(), isColor(),...)
666  * At any moment, the image can be unloaded from memory again by invoking unload.
667  * An image becomes of type "external storage" only through calling setExternalStorage. This property remains after serializing the object.
668  * File names can be absolute, or relative to the CImage::IMAGES_PATH_BASE directory. Filenames staring with "X:\" or "/" are considered absolute paths.
669  * By calling this method the current contents of the image are NOT saved to that file, because this method can be also called
670  * to let the object know where to load the image in case its contents are required. Thus, for saving images in this format (not when loading)
671  * the proper order of commands should be:
672  * \code
673  * img.saveToFile( fileName );
674  * img.setExternalStorage( fileName );
675  * \endcode
676  *
677  * \note Modifications to the memory copy of the image are not automatically saved to disk.
678  * \sa unload, isExternallyStored
679  */
680  void setExternalStorage( const std::string &fileName ) MRPT_NO_THROWS;
681 
682  static std::string IMAGES_PATH_BASE; //!< By default, "." \sa setExternalStorage
683 
684  /** See setExternalStorage(). */
685  bool isExternallyStored() const MRPT_NO_THROWS { return m_imgIsExternalStorage; }
686 
687  inline std::string getExternalStorageFile() const MRPT_NO_THROWS //!< Only if isExternallyStored() returns true. \sa getExternalStorageFileAbsolutePath
688  {
689  return m_externalFile;
690  }
691 
692  /** Only if isExternallyStored() returns true. \sa getExternalStorageFile */
693  void getExternalStorageFileAbsolutePath(std::string &out_path) const;
694 
695  /** Only if isExternallyStored() returns true. \sa getExternalStorageFile */
696  inline std::string getExternalStorageFileAbsolutePath() const {
697  std::string tmp;
698  getExternalStorageFileAbsolutePath(tmp);
699  return tmp;
700  }
701 
702  /** For external storage image objects only, this method makes sure the image is loaded in memory. Note that usually images are loaded on-the-fly on first access and there's no need to call this.
703  * \unload
704  */
705  inline void forceLoad() const { makeSureImageIsLoaded(); }
706 
707  /** For external storage image objects only, this method unloads the image from memory (or does nothing if already unloaded).
708  * It does not need to be called explicitly, unless the user wants to save memory for images that will not be used often.
709  * If called for an image without the flag "external storage", it is simply ignored.
710  * \sa setExternalStorage, forceLoad
711  */
712  void unload() const MRPT_NO_THROWS;
713 
714  /** @} */
715  // ================================================================
716 
717 
718  // ================================================================
719  /** @name Set, load & save methods
720  @{ */
721 
722  /** Reads the image from raw pixels buffer in memory.
723  */
724  void loadFromMemoryBuffer( unsigned int width, unsigned int height, bool color, unsigned char *rawpixels, bool swapRedBlue = false );
725 
726  /** Reads a color image from three raw pixels buffers in memory.
727  * bytesPerRow is the number of bytes per row per channel, i.e. the row increment.
728  */
729  void loadFromMemoryBuffer( unsigned int width, unsigned int height, unsigned int bytesPerRow, unsigned char *red, unsigned char *green, unsigned char *blue );
730 
731  /** Reads the image from a OpenCV IplImage object (making a COPY).
732  */
733  void loadFromIplImage( void* iplImage );
734 
735  /** Reads the image from a OpenCV IplImage object (WITHOUT making a copy).
736  * This object will own the memory of the passed object and free the IplImage upon destruction,
737  * so the caller CAN'T free the original object.
738  * This method provides a fast method to grab images from a camera without making a copy of every frame.
739  */
740  void setFromIplImage( void* iplImage );
741 
742  /** Reads the image from a OpenCV IplImage object (WITHOUT making a copy) and from now on the image cannot be modified, just read.
743  * When assigning an IPLImage to this object with this method, the IPLImage will NOT be released/freed at this object destructor.
744  * This method provides a fast method to grab images from a camera without making a copy of every frame.
745  * \sa setFromImageReadOnly
746  */
747  void setFromIplImageReadOnly( void* iplImage );
748 
749  /** Sets the internal IplImage pointer to that of another given image, WITHOUT making a copy, and from now on the image cannot be modified in this object (it will be neither freed, so the memory responsibility will still be of the original image object).
750  * When assigning an IPLImage to this object with this method, the IPLImage will NOT be released/freed at this object destructor.
751  * \sa setFromIplImageReadOnly
752  */
753  inline void setFromImageReadOnly( const CImage &other_img ) { setFromIplImageReadOnly(const_cast<void*>(other_img.getAs<void>()) ); }
754 
755  /** Set the image from a matrix, interpreted as grayscale intensity values, in the range [0,1] (normalized=true) or [0,255] (normalized=false)
756  * Matrix indexes are assumed to be in this order: M(row,column)
757  * \sa getAsMatrix
758  */
759  template <typename Derived>
760  void setFromMatrix(const Eigen::MatrixBase<Derived> &m, bool matrix_is_normalized=true)
761  {
762  MRPT_START
763  const unsigned int lx = m.cols();
764  const unsigned int ly = m.rows();
765  this->changeSize(lx,ly,1,true);
766  if (matrix_is_normalized) { // Matrix: [0,1]
767  for (unsigned int y=0;y<ly;y++) {
768  unsigned char *pixels = this->get_unsafe(0,y,0);
769  for (unsigned int x=0;x<lx;x++)
770  (*pixels++) = static_cast<unsigned char>( m.get_unsafe(y,x) * 255 );
771  }
772  }
773  else { // Matrix: [0,255]
774  for (unsigned int y=0;y<ly;y++) {
775  unsigned char *pixels = this->get_unsafe(0,y,0);
776  for (unsigned int x=0;x<lx;x++)
777  (*pixels++) = static_cast<unsigned char>( m.get_unsafe(y,x) );
778  }
779  }
780  MRPT_END
781  }
782 
783  /** Set the image from RGB matrices, given the pixels in the range [0,1] (normalized=true) or [0,255] (normalized=false)
784  * Matrix indexes are assumed to be in this order: M(row,column)
785  * \sa getAsRGBMatrices
786  */
787  template <typename Derived>
788  void setFromRGBMatrices(const Eigen::MatrixBase<Derived> &m_r, const Eigen::MatrixBase<Derived> &m_g, const Eigen::MatrixBase<Derived> &m_b, bool matrix_is_normalized=true)
789  {
790  MRPT_START
791  makeSureImageIsLoaded(); // For delayed loaded images stored externally
792  ASSERT_(img);
793  ASSERT_((m_r.size() == m_g.size())&&(m_r.size() == m_b.size()));
794  const unsigned int lx = m_r.cols();
795  const unsigned int ly = m_r.rows();
796  this->changeSize(lx,ly,3,true);
797  this->setChannelsOrder_RGB();
798 
799  if (matrix_is_normalized) { // Matrix: [0,1]
800  for (unsigned int y=0;y<ly;y++) {
801  unsigned char *pixels = this->get_unsafe(0,y,0);
802  for (unsigned int x=0;x<lx;x++)
803  {
804  (*pixels++) = static_cast<unsigned char>( m_r.get_unsafe(y,x) * 255 );
805  (*pixels++) = static_cast<unsigned char>( m_g.get_unsafe(y,x) * 255 );
806  (*pixels++) = static_cast<unsigned char>( m_b.get_unsafe(y,x) * 255 );
807  }
808  }
809  }
810  else { // Matrix: [0,255]
811  for (unsigned int y=0;y<ly;y++) {
812  unsigned char *pixels = this->get_unsafe(0,y,0);
813  for (unsigned int x=0;x<lx;x++)
814  {
815  (*pixels++) = static_cast<unsigned char>( m_r.get_unsafe(y,x) );
816  (*pixels++) = static_cast<unsigned char>( m_g.get_unsafe(y,x) );
817  (*pixels++) = static_cast<unsigned char>( m_b.get_unsafe(y,x) );
818  }
819  }
820  }
821  MRPT_END
822  }
823 
824  /** Reads the image from a binary stream containing a binary jpeg file.
825  * \exception std::exception On pixel coordinates out of bounds
826  */
827  void loadFromStreamAsJPEG( CStream &in );
828 
829  /** Load image from a file, whose format is determined from the extension (internally uses OpenCV).
830  * \param fileName The file to read from.
831  * \param isColor Specifies colorness of the loaded image:
832  * - if >0, the loaded image is forced to be color 3-channel image;
833  * - if 0, the loaded image is forced to be grayscale;
834  * - if <0, the loaded image will be loaded as is (with number of channels depends on the file).
835  * The supported formats are:
836  *
837  * - Windows bitmaps - BMP, DIB;
838  * - JPEG files - JPEG, JPG, JPE;
839  * - Portable Network Graphics - PNG;
840  * - Portable image format - PBM, PGM, PPM;
841  * - Sun rasters - SR, RAS;
842  * - TIFF files - TIFF, TIF.
843  *
844  * \return False on any error
845  * \sa saveToFile, setExternalStorage,loadFromXPM, loadTGA
846  */
847  bool loadFromFile( const std::string& fileName, int isColor = -1 );
848 
849  /** Loads a TGA true-color RGBA image as two CImage objects, one for the RGB channels plus a separate gray-level image with A channel.
850  * \return true on success
851  */
852  static bool loadTGA(const std::string& fileName, mrpt::utils::CImage &out_RGB, mrpt::utils::CImage &out_alpha);
853 
854  /** Loads the image from an XPM array, as #include'd from a ".xpm" file.
855  * \param[in] swap_rb Swaps red/blue channels from loaded image. *Seems* to be always needed, so it's enabled by default.
856  * \sa loadFromFile
857  * \return false on any error */
858  bool loadFromXPM( const char** xpm_array, bool swap_rb = true );
859 
860  /** Save the image to a file, whose format is determined from the extension (internally uses OpenCV).
861  * \param fileName The file to write to.
862  *
863  * The supported formats are:
864  *
865  * - Windows bitmaps - BMP, DIB;
866  * - JPEG files - JPEG, JPG, JPE;
867  * - Portable Network Graphics - PNG;
868  * - Portable image format - PBM, PGM, PPM;
869  * - Sun rasters - SR, RAS;
870  * - TIFF files - TIFF, TIF.
871  *
872  * \param jpeg_quality Only for JPEG files, the quality of the compression in the range [0-100]. Larger is better quality but slower.
873  * \note jpeg_quality is only effective if MRPT is compiled against OpenCV 1.1.0 or newer.
874  * \return False on any error
875  * \sa loadFromFile
876  */
877  bool saveToFile( const std::string& fileName, int jpeg_quality = 95 ) const;
878 
879  /** Save image to binary stream as a JPEG (.jpg) compressed format.
880  * \exception std::exception On number of rows or cols equal to zero or other errors.
881  * \sa saveToJPEG
882  */
883  void saveToStreamAsJPEG(mrpt::utils::CStream &out, const int jpeg_quality = 95 ) const;
884 
885  /** @} */
886  // ================================================================
887 
888 
889  // ================================================================
890  /** @name Color/Grayscale conversion
891  @{ */
892 
893  /** Returns a grayscale version of the image, or itself if it is already a grayscale image.
894  */
895  CImage grayscale() const;
896 
897  /** Returns a grayscale version of the image, or itself if it is already a grayscale image.
898  * \sa colorImage
899  */
900  void grayscale( CImage &ret ) const;
901 
902  /** Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
903  * \sa grayscale
904  */
905  void colorImage( CImage &ret ) const;
906 
907  /** Replaces this grayscale image with a RGB version of it.
908  * \sa grayscaleInPlace
909  */
910  void colorImageInPlace();
911 
912 
913  /** Replaces the image with a grayscale version of it.
914  * \sa colorImageInPlace
915  */
916  void grayscaleInPlace();
917 
918  /** @} */
919  // ================================================================
920 
921 
922  protected:
923  /** @name Data members
924  @{ */
925 
926  void *img; //!< The internal IplImage pointer to the actual image content.
927 
928  /** Set to true only when using setFromIplImageReadOnly.
929  * \sa setFromIplImageReadOnly */
931  /** Set to true only when using setExternalStorage.
932  * \sa setExternalStorage
933  */
935  mutable std::string m_externalFile; //!< The file name of a external storage image.
936 
937  /** @} */
938 
939  /** Resize the buffers in "img" to accomodate a new image size and/or format.
940  */
941  void changeSize(
942  unsigned int width,
943  unsigned int height,
944  TImageChannels nChannels,
945  bool originTopLeft );
946 
947  /** Release the internal IPL image, if not NULL or read-only. */
948  void releaseIpl(bool thisIsExternalImgUnload = false) MRPT_NO_THROWS;
949 
950  /** Checks if the image is of type "external storage", and if so and not loaded yet, load it. */
951  void makeSureImageIsLoaded() const throw (std::exception,utils::CExceptionExternalImageNotFound );
952 
953  }; // End of class
954  DEFINE_SERIALIZABLE_POST_CUSTOM_BASE( CImage, mrpt::utils::CSerializable )
955 
956  } // end of namespace utils
957 
958 } // end of namespace mrpt
959 
960 #endif
TConstructorFlags_CImage
For usage in one of the CImage constructors.
Definition: CImage.h:42
CImage(const Eigen::MatrixBase< Derived > &m, bool matrix_is_normalized)
Explicit constructor from a matrix, interpreted as grayscale intensity values, in the range [0...
Definition: CImage.h:162
CImage scaleHalf() const
Returns a new image scaled down to half its original size.
Definition: CImage.h:276
std::string m_externalFile
The file name of a external storage image.
Definition: CImage.h:935
CImage scaleHalfSmooth() const
Returns a new image scaled down to half its original size (averaging between every two rows) On odd s...
Definition: CImage.h:291
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:35
bool m_imgIsReadOnly
Set to true only when using setFromIplImageReadOnly.
Definition: CImage.h:930
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:98
void resize(unsigned int width, unsigned int height, TImageChannels nChannels, bool originTopLeft)
Changes the size of the image, erasing previous contents (does NOT scale its current content...
Definition: CImage.h:200
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:37
static std::string IMAGES_PATH_BASE
By default, ".".
Definition: CImage.h:682
std::string getExternalStorageFile() const MRPT_NO_THROWS
< Only if isExternallyStored() returns true.
Definition: CImage.h:687
#define MRPT_NO_THROWS
Used after member declarations.
STL namespace.
TImageSize getSize() const
Return the size of the image.
Definition: CImage.h:581
int TImageChannels
For use in mrpt::utils::CImage.
Definition: CImage.h:37
static bool DISABLE_JPEG_COMPRESSION
By default, when storing images through the CSerializable interface, RGB images are JPEG-compressed t...
Definition: CImage.h:183
CImage(const CImage &other_img, TConstructorFlags_CImage constructor_flag)
Fast constructor of a grayscale version of another image, making a reference to the original image if...
Definition: CImage.h:146
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
CImage grayscale() const
Returns a grayscale version of the image, or itself if it is already a grayscale image.
void forceLoad() const
For external storage image objects only, this method makes sure the image is loaded in memory...
Definition: CImage.h:705
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define CH_RGB
Definition: CImage.h:39
A RGB color - 8bit.
Definition: TColor.h:25
#define DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE(class_name, base_name)
This declaration must be inserted in all CSerializable classes definition, before the class declarati...
static int SERIALIZATION_JPEG_QUALITY
Unless DISABLE_JPEG_COMPRESSION=true, this sets the JPEG quality (range 1-100) of serialized RGB imag...
Definition: CImage.h:187
bool isExternallyStored() const MRPT_NO_THROWS
See setExternalStorage().
Definition: CImage.h:685
void setFromRGBMatrices(const Eigen::MatrixBase< Derived > &m_r, const Eigen::MatrixBase< Derived > &m_g, const Eigen::MatrixBase< Derived > &m_b, bool matrix_is_normalized=true)
Set the image from RGB matrices, given the pixels in the range [0,1] (normalized=true) or [0...
Definition: CImage.h:788
std::string getExternalStorageFileAbsolutePath() const
Only if isExternallyStored() returns true.
Definition: CImage.h:696
void setFromMatrix(const Eigen::MatrixBase< Derived > &m, bool matrix_is_normalized=true)
Set the image from a matrix, interpreted as grayscale intensity values, in the range [0...
Definition: CImage.h:760
TInterpolationMethod
Interpolation methods for images.
Definition: CImage.h:28
#define MRPT_START
void normalize(Scalar valMin, Scalar valMax)
Scales all elements such as the minimum & maximum values are shifted to the given values...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define DEFINE_SERIALIZABLE(class_name)
This declaration must be inserted in all CSerializable classes definition, within the class declarati...
CImage scaleDouble() const
Returns a new image scaled up to double its original size.
Definition: CImage.h:306
const T * getAs() const
Returns a pointer to a const T* containing the image - the idea is to call like "img.getAs()" so we can avoid here including OpenCV's headers.
Definition: CImage.h:516
#define DEFINE_SERIALIZABLE_POST_CUSTOM_BASE(class_name, base_name)
#define ASSERT_(f)
This virtual class defines the interface of any object accepting drawing primitives on it...
Definition: CCanvas.h:40
bool m_imgIsExternalStorage
Set to true only when using setExternalStorage.
Definition: CImage.h:934
T * getAs()
Returns a pointer to a T* containing the image - the idea is to call like "img.getAs()" so ...
Definition: CImage.h:521
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:30
Used in mrpt::utils::CImage.
Definition: exceptions.h:27
void * img
The internal IplImage pointer to the actual image content.
Definition: CImage.h:926
EIGEN_STRONG_INLINE Scalar get_unsafe(const size_t row, const size_t col) const
Read-only access to one element (Use with caution, bounds are not checked!)
Definition: eigen_plugins.h:82
Structure to hold the parameters of a pinhole camera model.
Definition: TCamera.h:31
void BASE_IMPEXP cross_correlation_FFT(const CMatrixFloat &A, const CMatrixFloat &B, CMatrixFloat &out_corr)
Correlation of two matrixes using 2D FFT.
static bool DISABLE_ZIP_COMPRESSION
By default, when storing images through the CSerializable interface, grayscale images will be ZIP com...
Definition: CImage.h:179



Page generated by Doxygen 1.8.9.1 for MRPT 1.3.0 SVN: at Sun Sep 13 03:55:12 UTC 2015