Main MRPT website > C++ reference
MRPT logo
CImage.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef CImage_H
00029 #define CImage_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/utils/CSerializable.h>
00033 #include <mrpt/math/CMatrix.h>
00034 #include <mrpt/utils/CCanvas.h>
00035 #include <mrpt/utils/TCamera.h>
00036 #include <mrpt/system/os.h>
00037 #include <mrpt/utils/exceptions.h>
00038 
00039 namespace mrpt
00040 {
00041         namespace utils
00042         {
00043                 /** Interpolation methods for images.
00044                   *  Used for OpenCV related operations with images, but also with MRPT native classes.
00045                   * \sa mrpt::utils::CMappedImage, CImage::scaleImage
00046                  * \ingroup mrpt_base_grp
00047                   */
00048                 enum TInterpolationMethod
00049                 {
00050                         IMG_INTERP_NN = 0,
00051                         IMG_INTERP_LINEAR=1,
00052                         IMG_INTERP_CUBIC=2,
00053                         IMG_INTERP_AREA=3
00054                 };
00055 
00056                 /** For use in mrpt::utils::CImage */
00057                 typedef int  TImageChannels;
00058                 #define CH_GRAY  1
00059                 #define CH_RGB   3
00060 
00061                 /** For usage in one of the CImage constructors */
00062                 enum TConstructorFlags_CImage
00063                 {
00064                         UNINITIALIZED_IMAGE = 0,
00065                         FAST_REF_OR_CONVERT_TO_GRAY = 1
00066                 };
00067 
00068                 // This must be added to any CSerializable derived class:
00069                 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE( CImage, mrpt::utils::CSerializable )
00070 
00071                 /** A class for storing images as grayscale or RGB bitmaps.
00072                  *  File I/O is supported in two different ways:
00073                  *              - Binary dump using the CSerializable interface(<< and >> operators), just as most objects
00074                  *          in the MRPT library. This format is not compatible with any standarized image format.
00075                  *              - Saving/loading from files of different formats (bmp,jpg,png,...) using the methods CImage::loadFromFile and CImage::saveToFile.
00076                  *
00077                  *  How to create color/grayscale images:
00078                  *  \code
00079                  *    CImage  img1(width, height,  CH_GRAY );  // Grayscale image (8U1C)
00080                  *    CImage  img2(width, height,  CH_RGB );  // RGB image (8U3C)
00081                  *  \endcode
00082                  *
00083                  * Additional notes:
00084                  *              - The OpenCV "IplImage" format is used internally for compatibility with all OpenCV functions. See CImage::getAsIplImage and CImage::getAs<>(). Example:
00085                  *         \code
00086                  *            CImage  img;
00087                  *            ...
00088                  *            // Call to OpenCV function expecting an "IplImage *" or a "void* arr":
00089                  *            cvFunction( img.getAs<IplImage>(), ... );
00090                  *         \endcode
00091                  *              - Only the unsigned 8-bit storage format for pixels (on each channel) is supported.
00092                  *              - 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.
00093                  *              - To move images from one object to the another, use CImage::copyFastFrom rather than the copy operator =.
00094                  *              - If you are interested in a smart pointer to an image, use:
00095                  *  \code
00096                  *    CImagePtr   myImgPtr = CImagePtr( new CImage(...) );
00097                  *  \endcode
00098                  *              - To set a CImage from an OpenCV "IPLImage*", use the methods:
00099                  *                      - CImage::loadFromIplImage
00100                  *                      - CImage::setFromIplImage
00101                  *                      - CImage::CImage(void *IPL)
00102                  *
00103                  *   Some functions are implemented in MRPT with highly optimized SSE2/SSE3 routines, in suitable platforms and compilers. To
00104                  *   see the list of optimizations refer to \ref sse_optimizations "this page". If optimized versions are not available in some
00105                  *   platform it falls back to default OpenCV methods.
00106                  *
00107                  * For many computer vision functions that use CImage as its image data type, see mrpt::vision.
00108                  *
00109                  * \note This class acts as a wrapper class to a small subset of OpenCV functions. IplImage is the internal storage structure.
00110                  *
00111                  * \sa mrpt::vision, mrpt::vision::CFeatureExtractor, mrpt::vision::CImagePyramid, CSerializable, CCanvas
00112                  * \ingroup mrpt_base_grp
00113                  */
00114                 class BASE_IMPEXP CImage : public mrpt::utils::CSerializable, public CCanvas
00115                 {
00116                         DEFINE_SERIALIZABLE( CImage )
00117                 public:
00118 
00119                         // ================================================================
00120                         /** @name Constructors & destructor
00121                             @{ */
00122 
00123                         /** Default constructor: initialize an 1x1 RGB image. */
00124                         CImage();
00125 
00126                         /** Constructor for a given image size and type.
00127                           *  Examples:
00128                           *   \code
00129                           *    CImage  img1(width, height,  CH_GRAY );  // Grayscale image (8U1C)
00130                           *    CImage  img2(width, height,  CH_RGB );  // RGB image (8U3C)
00131                           *   \endcode
00132                           */
00133                         CImage( unsigned int    width,
00134                                         unsigned int    height,
00135                                         TImageChannels  nChannels = CH_RGB,
00136                                         bool                    originTopLeft = true
00137                                         );
00138 
00139                         /** 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). */
00140                         CImage( const CImage &o );
00141 
00142                         /** Fast constructor that leaves the image uninitialized (the internal IplImage pointer set to NULL).
00143                           *  Use only when you know the image will be soon be assigned another image.
00144                           *  Example of usage:
00145                           *   \code
00146                           *    CImage myImg(UNINITIALIZED_IMAGE);
00147                           *   \endcode
00148                           */
00149                         inline CImage(TConstructorFlags_CImage constructor_flag) : img(NULL),m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
00150                         { }
00151 
00152                         /** 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.
00153                           *   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.
00154                           * Example of usage:
00155                           *   \code
00156                           *     void my_func(const CImage &in_img) {
00157                           *        const CImage gray_img(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
00158                           *        // We can now operate on "gray_img" being sure it's in grayscale.
00159                           *     }
00160                           *   \endcode
00161                           */
00162                         inline CImage(const CImage& other_img, TConstructorFlags_CImage constructor_flag) : img(NULL),m_imgIsReadOnly(false), m_imgIsExternalStorage(false)
00163                         {
00164                                 if( other_img.isColor() ) other_img.grayscale(*this);
00165                                 else this->setFromImageReadOnly(other_img);
00166                         }
00167 
00168                         /** Constructor from an IPLImage*, making a copy of the image.
00169                           * \sa loadFromIplImage, setFromIplImage
00170                           */
00171                         CImage( void *iplImage );
00172 
00173                         /** Explicit constructor from a matrix, interpreted as grayscale intensity values, in the range [0,1] (normalized=true) or [0,255] (normalized=false)
00174                           * \sa setFromMatrix
00175                           */
00176                         template <typename Derived>
00177                         explicit inline CImage(const Eigen::MatrixBase<Derived> &m, bool matrix_is_normalized)
00178                         {
00179                                 this->setFromMatrix(m,matrix_is_normalized);
00180                         }
00181 
00182 
00183                         /** Destructor: */
00184                         virtual ~CImage( );
00185 
00186                         /** @} */
00187                         // ================================================================
00188 
00189 
00190                         /** 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.
00191                           *  The default value of this variable is "false".
00192                           */
00193                         static bool DISABLE_ZIP_COMPRESSION;
00194 
00195 
00196                         // ================================================================
00197                         /** @name Manipulate the image contents or size, various computer-vision methods (image filters, undistortion, etc.)
00198                             @{ */
00199 
00200                         /** Changes the size of the image, erasing previous contents (does NOT scale its current content, for that, see scaleImage).
00201                           *  - nChannels: Can be 3 for RGB images or 1 for grayscale images.
00202                           *  - originTopLeft: Is true if the top-left corner is (0,0). In other case, the reference is the bottom-left corner.
00203                           * \sa scaleImage
00204                           */
00205                         inline void  resize(
00206                                         unsigned int    width,
00207                                         unsigned int    height,
00208                                         TImageChannels  nChannels,
00209                                         bool                    originTopLeft )
00210                         {
00211                                 changeSize(width,height,nChannels,originTopLeft);
00212                         }
00213 
00214                         /** Scales this image to a new size, interpolating as needed.
00215                           * \sa resize, rotateImage
00216                           */
00217                         void scaleImage( unsigned int width, unsigned int height, TInterpolationMethod interp = IMG_INTERP_CUBIC );
00218 
00219                         /** Scales this image to a new size, interpolating as needed, saving the new image in a different output object.
00220                           * \sa resize, rotateImage
00221                           */
00222                         void scaleImage( CImage &out_img, unsigned int width, unsigned int height, TInterpolationMethod interp = IMG_INTERP_CUBIC ) const;
00223 
00224                         /** Rotates the image by the given angle around the given center point, with an optional scale factor.
00225                           * \sa resize, scaleImage
00226                           */
00227                         void rotateImage( double angle_radians, unsigned int center_x, unsigned int center_y, double scale = 1.0 );
00228 
00229                         /** Changes the value of the pixel (x,y).
00230                           *  Pixel coordinates starts at the left-top corner of the image, and start in (0,0).
00231                           *  The meaning of the parameter "color" depends on the implementation: it will usually
00232                           *   be a 24bit RGB value (0x00RRGGBB), but it can also be just a 8bit gray level.
00233                           *  This method must support (x,y) values OUT of the actual image size without neither
00234                           *   raising exceptions, nor leading to memory access errors.
00235                           */
00236                         void  setPixel(int x, int y, size_t color);
00237 
00238                         /** Changes the property of the image stating if the top-left corner (vs. bottom-left) is the coordinate reference.
00239                           */
00240                         void  setOriginTopLeft(bool val);
00241 
00242                         /** Draws a line.
00243                           * \param x0 The starting point x coordinate
00244                           * \param y0 The starting point y coordinate
00245                           * \param x1 The end point x coordinate
00246                           * \param y1 The end point y coordinate
00247                           * \param color The color of the line
00248                           * \param width The desired width of the line (this is IGNORED in this virtual class)
00249                           *  This method may be redefined in some classes implementing this interface in a more appropiate manner.
00250                           */
00251                         virtual void  line(
00252                                 int                             x0,
00253                                 int                             y0,
00254                                 int                             x1,
00255                                 int                             y1,
00256                                 const mrpt::utils::TColor color,
00257                                 unsigned int    width = 1,
00258                                 TPenStyle               penStyle = psSolid);
00259 
00260                         /** Draws a circle of a given radius.
00261                           * \param x The center - x coordinate in pixels.
00262                           * \param y The center - y coordinate in pixels.
00263                           * \param radius The radius - in pixels.
00264                           * \param color The color of the circle.
00265                           * \param width The desired width of the line
00266                           */
00267                         void  drawCircle(
00268                                 int                             x,
00269                                 int                             y,
00270                                 int                             radius,
00271                                 const mrpt::utils::TColor &color = mrpt::utils::TColor(255,255,255),
00272                                 unsigned int    width = 1);
00273 
00274                         void equalizeHistInPlace(); //!< Equalize the image histogram, replacing the original image.
00275                         void equalizeHist( CImage  &outImg ) const; //!< Equalize the image histogram, saving the new image in the given output object.
00276 
00277                         /** Returns a new image scaled down to half its original size.
00278                           * \exception std::exception On odd size
00279                           * \sa scaleDouble, scaleImage, scaleHalfSmooth
00280                           */
00281                         CImage  scaleHalf()const
00282                         {
00283                                 CImage ret(UNINITIALIZED_IMAGE);
00284                                 this->scaleHalf(ret);
00285                                 return ret;
00286                         }
00287 
00288                         //! \overload
00289                         void scaleHalf(CImage &out_image) const;
00290 
00291 
00292                         /** Returns a new image scaled down to half its original size (averaging between every two rows)
00293                           * \exception std::exception On odd size
00294                           * \sa scaleDouble, scaleImage, scaleHalf
00295                           */
00296                         CImage  scaleHalfSmooth()const
00297                         {
00298                                 CImage ret(UNINITIALIZED_IMAGE);
00299                                 this->scaleHalfSmooth(ret);
00300                                 return ret;
00301                         }
00302 
00303                         //! \overload
00304                         void scaleHalfSmooth(CImage &out_image) const;
00305 
00306 
00307                         /** Returns a new image scaled up to double its original size.
00308                           * \exception std::exception On odd size
00309                           * \sa scaleHalf, scaleImage
00310                           */
00311                         CImage  scaleDouble()const
00312                         {
00313                                 CImage ret(UNINITIALIZED_IMAGE);
00314                                 this->scaleDouble(ret);
00315                                 return ret;
00316                         }
00317 
00318                        //! \overload
00319                        void scaleDouble(CImage &out_image) const;
00320 
00321 
00322                         /** Update a part of this image with the "patch" given as argument.
00323                          * The "patch" will be "pasted" at the (col,row) coordinates of this image.
00324                          * \exception std::exception if patch pasted on the pixel (_row, _column) jut out
00325                          * of the image.
00326                          * \sa extract_patch
00327                          */
00328                         void update_patch(const CImage &patch,
00329                                           const unsigned int col,
00330                                           const unsigned int row);
00331 
00332                         /** Extract a patch from this image, saveing it into "patch" (its previous contents will be overwritten).
00333                           *  The patch to extract starts at (col,row) and has the given dimensions.
00334                           * \sa update_patch
00335                           */
00336                         void  extract_patch(
00337                                 CImage  &patch,
00338                                 const unsigned int      col=0,
00339                                 const unsigned int      row=0,
00340                                 const unsigned int      width=1,
00341                                 const unsigned int      height=1 ) const;
00342 
00343                         /** Computes the correlation coefficient (returned as val), between two images
00344                         *       This function use grayscale images only
00345                         *       img1, img2 must be same size
00346                         * (by AJOGD @ DEC-2006)
00347                         */
00348                         float  correlate( const CImage &img2int, int width_init=0, int height_init=0 )const;
00349 
00350                         /**     Computes the correlation between this image and another one, encapsulating the openCV function cvMatchTemplate
00351                         *
00352                         * \param patch_img The "patch" image, which must be equal, or smaller than "this" image. This function supports gray-scale (1 channel only) images.
00353                         * \param u_search_ini The "x" coordinate of the search window.
00354                         * \param v_search_ini The "y" coordinate of the search window.
00355                         * \param u_search_size The width of the search window.
00356                         * \param v_search_size The height of the search window.
00357                         * \param u_max The u coordinate where find the maximun cross correlation value.
00358                         * \param v_max The v coordinate where find the maximun cross correlation value
00359                         * \param max_val The maximun value of cross correlation which we can find
00360                         * \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 )
00361                         *  Note: By default, the search area is the whole (this) image.
00362                         * (by AJOGD @ MAR-2007)
00363                         */
00364                         void  cross_correlation(
00365                                 const CImage    &patch_img,
00366                                 size_t                          &u_max,
00367                                 size_t                          &v_max,
00368                                 double                          &max_val,
00369                                 int                                     u_search_ini=-1,
00370                                 int                                     v_search_ini=-1,
00371                                 int                                     u_search_size=-1,
00372                                 int                                     v_search_size=-1,
00373                                 CImage                          *out_corr_image = NULL
00374                                 )const;
00375 
00376                         /**     Computes the correlation matrix between this image and another one.
00377                         *   This implementation uses the 2D FFT for achieving reduced computation time.
00378                         * \param in_img The "patch" image, which must be equal, or smaller than "this" image. This function supports gray-scale (1 channel only) images.
00379                         * \param u_search_ini The "x" coordinate of the search window.
00380                         * \param v_search_ini The "y" coordinate of the search window.
00381                         * \param u_search_size The width of the search window.
00382                         * \param v_search_size The height of the search window.
00383                         * \param out_corr The output for the correlation matrix, which will be "u_search_size" x "v_search_size"
00384                         * \param biasThisImg This optional parameter is a fixed "bias" value to be substracted to the pixels of "this" image before performing correlation.
00385                         * \param biasInImg This optional parameter is a fixed "bias" value to be substracted to the pixels of "in_img" image before performing correlation.
00386                         *  Note: By default, the search area is the whole (this) image.
00387                         * (by JLBC @ JAN-2006)
00388                         * \sa cross_correlation
00389                         */
00390                         void  cross_correlation_FFT(
00391                                 const CImage    &in_img,
00392                                 math::CMatrixFloat              &out_corr,
00393                                 int                                     u_search_ini=-1,
00394                                 int                                     v_search_ini=-1,
00395                                 int                                     u_search_size=-1,
00396                                 int                                     v_search_size=-1,
00397                                 float                           biasThisImg = 0,
00398                                 float                           biasInImg = 0
00399                                 ) const;
00400 
00401 
00402                         /** Optimize de brightness range of a image without using histogram
00403                         * Only for one channel images.
00404                         */
00405                         void  normalize();
00406 
00407                         /** Flips vertically the image.
00408                           * \sa swapRB
00409                           */
00410                         void flipVertical(bool also_swapRB = false);
00411 
00412                         /** Swaps red and blue channels.
00413                           * \sa flipVertical
00414                           */
00415                         void swapRB();
00416 
00417                         /** Rectify (un-distort) the image according to some camera parameters, and returns an output un-distorted image.
00418                           * \param out_img The output rectified image
00419                           * \param cameraParams The input camera params (containing the intrinsic and distortion parameters of the camera)
00420                           */
00421                         void rectifyImage( CImage &out_img, const mrpt::utils::TCamera &cameraParams) const;
00422 
00423                         /** Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coefficients and returns an output rectified image
00424                           * \param out_img The output rectified image
00425                           * \param cameraMatrix The input camera matrix (containing the intrinsic parameters of the camera): [fx 0 cx; 0 fy cy; 0 0 1]: (fx,fy)  focal length and (cx,cy) principal point coordinates
00426                           * \param distCoeff The (input) distortion coefficients: [k1, k2, p1, p2]:  k1 and k2 (radial) and p1 and p2 (tangential)
00427                           */
00428                         inline void rectifyImage( CImage &out_img, const math::CMatrixDouble33 &cameraMatrix, const vector_double &distCoeff ) const
00429                         {
00430                                 mrpt::utils::TCamera  cam;
00431                                 cam.intrinsicParams = cameraMatrix;
00432                                 cam.setDistortionParamsVector(distCoeff);
00433                                 rectifyImage(out_img,cam);
00434                         }
00435 
00436                         /** Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coefficients, replacing "this" with the rectified image
00437                           * \param cameraParams The input camera params (containing the intrinsic and distortion parameters of the camera)
00438                           */
00439                         void rectifyImageInPlace(const mrpt::utils::TCamera &cameraParams );
00440 
00441                         /** Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coefficients, replacing "this" with the rectified image
00442                           * \param cameraMatrix The input camera matrix (containing the intrinsic parameters of the camera): [fx 0 cx; 0 fy cy; 0 0 1]: (fx,fy)  focal length and (cx,cy) principal point coordinates
00443                           * \param distCoeff The (input) distortion coefficients: [k1, k2, p1, p2]:  k1 and k2 (radial) and p1 and p2 (tangential)
00444                           */
00445                         inline void rectifyImageInPlace( const math::CMatrixDouble33 &cameraMatrix, const vector_double &distCoeff )
00446                         {
00447                                 mrpt::utils::TCamera  cam;
00448                                 cam.intrinsicParams = cameraMatrix;
00449                                 cam.setDistortionParamsVector(distCoeff);
00450                                 rectifyImageInPlace(cam);
00451                         }
00452 
00453                         /** Rectify an image (undistorts and rectification) from a stereo pair according to a pair of precomputed rectification maps
00454                           * \param mapX, mapY   [IN] The pre-computed maps of the rectification (should be computed beforehand)
00455                           * \sa vision::computeStereoRectificationMaps
00456                           */
00457             void rectifyImageInPlace( void *mapX, void *mapY );
00458 
00459                         /** Filter the image with a Median filter with a window size WxW, returning the filtered image in out_img  */
00460                         void filterMedian( CImage &out_img, int W=3 ) const;
00461 
00462                         /** Filter the image with a Median filter with a window size WxH, replacing "this" image by the filtered one. */
00463                         void filterMedianInPlace( int W=3 );
00464 
00465                         /** Filter the image with a Gaussian filter with a window size WxH, returning the filtered image in out_img  */
00466                         void filterGaussianInPlace( int W = 3, int H = 3 );
00467 
00468                         /** Filter the image with a Gaussian filter with a window size WxH, replacing "this" image by the filtered one. */
00469                         void filterGaussian( CImage &out_img, int W = 3, int H = 3) const;
00470 
00471                         /** Draw onto this image the detected corners of a chessboard. The length of cornerCoords must be the product of the two check_sizes.
00472                           *
00473                           * \param cornerCoords [IN] The pixel coordinates of all the corners.
00474                           * \param check_size_x [IN] The number of squares, in the X direction
00475                           * \param check_size_y [IN] The number of squares, in the Y direction
00476                           *
00477                           * \return false if the length of cornerCoords is inconsistent (nothing is drawn then).
00478                           *
00479                           * \sa mrpt::vision::findChessboardCorners
00480                           */
00481                         bool drawChessboardCorners(
00482                                 std::vector<TPixelCoordf>       &cornerCoords,
00483                                 unsigned int  check_size_x,
00484                                 unsigned int  check_size_y );
00485 
00486                         /** 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)
00487                           *
00488                           * \param im1 [IN] The first image.
00489                           * \param im2 [IN] The other image.
00490                           */
00491                         void joinImagesHorz(
00492                                 const CImage &im1,
00493                                 const CImage &im2 );
00494 
00495                         /** Compute the KLT response at a given pixel (x,y) - Only for grayscale images (for efficiency it avoids converting to grayscale internally).
00496                           *  See KLT_response_optimized for more details on the internal optimizations of this method, but this graph shows a general view:
00497                           *  <img src="KLT_response_performance_SSE2.png" >
00498                           */
00499                         float KLT_response(
00500                                 const unsigned int x,
00501                                 const unsigned int y,
00502                                 const unsigned int half_window_size ) const;
00503 
00504                         /** @} */
00505                         // ================================================================
00506 
00507 
00508 
00509                         // ================================================================
00510                         /** @name Copy, move & swap  operations
00511                             @{ */
00512 
00513                         /** Copy operator (if the image is externally stored, the writen image will be such as well).
00514                           * \sa copyFastFrom
00515                           */
00516                         CImage& operator = (const CImage& o);
00517 
00518                         /** Copies from another image, and, if that one is externally stored, the image file will be actually loaded into memory in "this" object.
00519                           * \sa operator =
00520                           */
00521                         void copyFromForceLoad(const CImage &o);
00522 
00523                         /** Moves an image from another object, erasing the origin image in the process (this is much faster than copying)
00524                           * \sa operator =
00525                           */
00526                         void copyFastFrom( CImage &o );
00527 
00528                         void swap(CImage &o); //!< Very efficient swap of two images (just swap the internal pointers)
00529 
00530                         /** @} */
00531                         // ================================================================
00532 
00533 
00534                         // ================================================================
00535                         /** @name Access to image contents (IplImage structure and raw pixels).
00536                             @{ */
00537 
00538                         /** Returns a pointer to an T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers. \sa getAsIplImage */
00539                         template <typename T> inline const T* getAs() const {
00540                                 makeSureImageIsLoaded();
00541                                 return reinterpret_cast<const T*>(img);
00542                         }
00543                         /** Returns a pointer to an T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV's headers. \sa getAsIplImage */
00544                         template <typename T> inline T* getAs(){
00545                                 makeSureImageIsLoaded();
00546                                 return reinterpret_cast<T*>(img);
00547                         }
00548 
00549                         /** Returns a pointer to an OpenCV's IplImage struct containing the image, which is linked to this class: free neigther that pointer nor this class until they are not required anymore, since this class is in charge of freeing the memory buffers inside of the returned image.  \sa getAs */
00550                         inline void*  getAsIplImage() const {
00551                                 makeSureImageIsLoaded();
00552                                 return img;
00553                         }
00554 
00555                         /**  Access to pixels without checking boundaries - Use normally the () operator better, which checks the coordinates.
00556                           \sa CImage::operator()
00557                           */
00558                         unsigned char*  get_unsafe(
00559                                                 unsigned int    col,
00560                                                 unsigned int    row,
00561                                                 unsigned int    channel=0) const;
00562 
00563                         /** Returns the contents of a given pixel at the desired channel, in float format: [0,255]->[0,1]
00564                           *   The coordinate origin is pixel(0,0)=top-left corner of the image.
00565                           * \exception std::exception On pixel coordinates out of bounds
00566                           * \sa operator()
00567                           */
00568                         float  getAsFloat(unsigned int col, unsigned int row, unsigned int channel) const;
00569 
00570                         /** 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]
00571                           *   The coordinate origin is pixel(0,0)=top-left corner of the image.
00572                           * \exception std::exception On pixel coordinates out of bounds
00573                           * \sa operator()
00574                           */
00575                         float  getAsFloat(unsigned int col, unsigned int row) const;
00576 
00577                         /** Returns a pointer to a given pixel information.
00578                          *   The coordinate origin is pixel(0,0)=top-left corner of the image.
00579                          * \exception std::exception On pixel coordinates out of bounds
00580                          */
00581                         unsigned char*  operator()(unsigned int col, unsigned int row, unsigned int channel = 0) const;
00582 
00583                         /** @} */
00584                         // ================================================================
00585 
00586 
00587 
00588                         // ================================================================
00589                         /** @name Query image properties
00590                             @{ */
00591 
00592                         /** Returns the width of the image in pixels
00593                           * \sa getSize
00594                           */
00595                         size_t getWidth() const;
00596 
00597                         /** Returns the height of the image in pixels
00598                           * \sa getSize
00599                           */
00600                         size_t getHeight() const;
00601 
00602                         /** Return the size of the image
00603                           * \sa getWidth, getHeight
00604                           */
00605                         void getSize(TImageSize &s) const;
00606 
00607                         /** Return the size of the image
00608                           * \sa getWidth, getHeight
00609                           */
00610                         inline TImageSize getSize() const {
00611                                 TImageSize  ret;
00612                                 getSize(ret);
00613                                 return ret;
00614                         }
00615 
00616                         /** 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)
00617                           * \sa getSize, get_unsafe
00618                           */
00619                         size_t getRowStride() const;
00620 
00621                         /** Return the maximum pixel value of the image, as a float value in the range [0,1]
00622                           * \sa getAsFloat
00623                           */
00624                         float  getMaxAsFloat() const;
00625 
00626                         /** Returns true if the image is RGB, false if it is grayscale */
00627                         bool  isColor() const;
00628 
00629                         /** Returns true if the coordinates origin is top-left, or false if it is bottom-left  */
00630                         bool  isOriginTopLeft() const;
00631 
00632                         /** Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering. \sa setChannelsOrder, swapRB */
00633                         const char *  getChannelsOrder()const;
00634 
00635                         /** 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 */
00636                         void setChannelsOrder_RGB();
00637                         /** 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 */
00638                         void setChannelsOrder_BGR();
00639 
00640                         /** Returns the number of channels, typically 1 (GRAY) or 3 (RGB)
00641                           * \sa isColor
00642                           */
00643                         TImageChannels getChannelCount() const;
00644 
00645                         /**     Returns the image as a matrix with pixel grayscale values in the range [0,1]
00646                           *  \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,...)
00647                           *  \param x_min The starting "x" coordinate to extract (default=0=the first column)
00648                           *  \param y_min The starting "y" coordinate to extract (default=0=the first row)
00649                           *  \param x_max The final "x" coordinate (inclusive) to extract (default=-1=the last column)
00650                           *  \param y_max The final "y" coordinate (inclusive) to extract (default=-1=the last row)
00651                           * \sa setFromMatrix
00652                           */
00653                         void  getAsMatrix(
00654                                 mrpt::math::CMatrixFloat        &outMatrix,
00655                                 bool            doResize = true,
00656                                 int                     x_min = 0,
00657                                 int                     y_min = 0,
00658                                 int                     x_max = -1,
00659                                 int                     y_max = -1
00660                                 )  const;
00661 
00662                         /**     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.
00663                           */
00664                         void  getAsMatrixTiled( math::CMatrix &outMatrix )  const;
00665 
00666                         /** @} */
00667                         // ================================================================
00668 
00669 
00670                         // ================================================================
00671                         /** @name External storage-mode methods
00672                             @{  */
00673 
00674                         /**  By using this method the image is marked as referenced to an external file, which will be loaded only under demand.
00675                           *   A CImage with external storage does not consume memory until some method trying to access the image is invoked (e.g. getWidth(), isColor(),...)
00676                           *   At any moment, the image can be unloaded from memory again by invoking unload.
00677                           *   An image becomes of type "external storage" only through calling setExternalStorage. This property remains after serializing the object.
00678                           *   File names can be absolute, or relative to the CImage::IMAGES_PATH_BASE directory. Filenames staring with "X:\" or "/" are considered absolute paths.
00679                           *   By calling this method the current contents of the image are NOT saved to that file, because this method can be also called
00680                           *    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)
00681                           *    the proper order of commands should be:
00682                           *   \code
00683                           *   img.saveToFile( fileName );
00684                           *   img.setExternalStorage( fileName );
00685                           *   \endcode
00686                           *
00687                           *   \note Modifications to the memory copy of the image are not automatically saved to disk.
00688                           *  \sa unload, isExternallyStored
00689                           */
00690                         void setExternalStorage( const std::string &fileName ) MRPT_NO_THROWS;
00691 
00692                         static std::string IMAGES_PATH_BASE;            //!< By default, "."  \sa setExternalStorage
00693 
00694                         /** See setExternalStorage(). */
00695                         bool isExternallyStored() const MRPT_NO_THROWS { return m_imgIsExternalStorage; }
00696 
00697                         inline std::string  getExternalStorageFile() const MRPT_NO_THROWS //!< Only if isExternallyStored() returns true. \sa getExternalStorageFileAbsolutePath
00698                         {
00699                                 return m_externalFile;
00700                         }
00701 
00702                         /** Only if isExternallyStored() returns true. \sa getExternalStorageFile */
00703                         void getExternalStorageFileAbsolutePath(std::string &out_path) const;
00704 
00705                         /** Only if isExternallyStored() returns true. \sa getExternalStorageFile */
00706                         inline std::string getExternalStorageFileAbsolutePath() const {
00707                                         std::string tmp;
00708                                         getExternalStorageFileAbsolutePath(tmp);
00709                                         return tmp;
00710                         }
00711 
00712                         /** 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.
00713                           * \unload
00714                           */
00715                         inline void forceLoad() {  makeSureImageIsLoaded(); }
00716 
00717                         /** For external storage image objects only, this method unloads the image from memory (or does nothing if already unloaded).
00718                           *  It does not need to be called explicitly, unless the user wants to save memory for images that will not be used often.
00719                           *  If called for an image without the flag "external storage", it is simply ignored.
00720                           * \sa setExternalStorage, forceLoad
00721                           */
00722                         void unload() MRPT_NO_THROWS;
00723 
00724                         /** @}  */
00725                         // ================================================================
00726 
00727 
00728                         // ================================================================
00729                         /** @name Set, load & save methods
00730                             @{  */
00731 
00732                         /** Reads the image from raw pixels buffer in memory.
00733                           */
00734                         void  loadFromMemoryBuffer( unsigned int width, unsigned int height, bool color, unsigned char *rawpixels, bool swapRedBlue = false );
00735 
00736                         /** Reads a color image from three raw pixels buffers in memory.
00737                           * bytesPerRow is the number of bytes per row per channel, i.e. the row increment.
00738                           */
00739                         void  loadFromMemoryBuffer( unsigned int width, unsigned int height, unsigned int bytesPerRow, unsigned char *red, unsigned char *green, unsigned char *blue );
00740 
00741                         /** Reads the image from a OpenCV IplImage object (making a COPY).
00742                           */
00743                         void  loadFromIplImage( void* iplImage );
00744 
00745                         /** Reads the image from a OpenCV IplImage object (WITHOUT making a copy).
00746                           *   This object will own the memory of the passed object and free the IplImage upon destruction,
00747                           *     so the caller CAN'T free the original object.
00748                           *   This method provides a fast method to grab images from a camera without making a copy of every frame.
00749                           */
00750                         void  setFromIplImage( void* iplImage );
00751 
00752                         /** Reads the image from a OpenCV IplImage object (WITHOUT making a copy) and from now on the image cannot be modified, just read.
00753                           *  When assigning an IPLImage to this object with this method, the IPLImage will NOT be released/freed at this object destructor.
00754                           *   This method provides a fast method to grab images from a camera without making a copy of every frame.
00755                           *  \sa setFromImageReadOnly
00756                           */
00757                         void  setFromIplImageReadOnly( void* iplImage );
00758 
00759                         /** 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).
00760                           *  When assigning an IPLImage to this object with this method, the IPLImage will NOT be released/freed at this object destructor.
00761                           *  \sa setFromIplImageReadOnly
00762                           */
00763                         inline void setFromImageReadOnly( const CImage &other_img ) { setFromIplImageReadOnly(other_img.getAsIplImage() ); }
00764 
00765                         /** Set the image from a matrix, interpreted as grayscale intensity values, in the range [0,1] (normalized=true) or [0,255] (normalized=false)
00766                           * \sa getAsMatrix
00767                           */
00768                         template <typename Derived>
00769                         void setFromMatrix(const Eigen::MatrixBase<Derived> &m, bool matrix_is_normalized=true)
00770                         {
00771                                 MRPT_START
00772                                 makeSureImageIsLoaded();   // For delayed loaded images stored externally
00773                                 ASSERT_(img)
00774                                 const unsigned int lx = m.cols();
00775                                 const unsigned int ly = m.rows();
00776                                 this->changeSize(lx,ly,1,true);
00777                                 if (matrix_is_normalized) {  // Matrix: [0,1]
00778                                         for (unsigned int y=0;y<ly;y++) {
00779                                                 unsigned char *pixels = this->get_unsafe(0,y,0);
00780                                                 for (unsigned int x=0;x<lx;x++)
00781                                                         (*pixels++) = static_cast<unsigned char>( m.get_unsafe(y,x) * 255 );
00782                                         }
00783                                 }
00784                                 else {  // Matrix: [0,255]
00785                                         for (unsigned int y=0;y<ly;y++) {
00786                                                 unsigned char *pixels = this->get_unsafe(0,y,0);
00787                                                 for (unsigned int x=0;x<lx;x++)
00788                                                         (*pixels++) = static_cast<unsigned char>( m.get_unsafe(y,x) );
00789                                         }
00790                                 }
00791                                 MRPT_END
00792                         }
00793 
00794                         /** Reads the image from a binary stream containing a binary jpeg file.
00795                          * \exception std::exception On pixel coordinates out of bounds
00796                           */
00797                         void  loadFromStreamAsJPEG( CStream &in );
00798 
00799                         /** Load image from a file, whose format is determined from the extension (internally uses OpenCV).
00800                          * \param fileName The file to read from.
00801                          * \param isColor Specifies colorness of the loaded image:
00802                          *  - if >0, the loaded image is forced to be color 3-channel image;
00803                          *  - if 0, the loaded image is forced to be grayscale;
00804                          *  - if <0, the loaded image will be loaded as is (with number of channels depends on the file).
00805                          * The supported formats are:
00806                          *
00807                          * - Windows bitmaps - BMP, DIB;
00808                          * - JPEG files - JPEG, JPG, JPE;
00809                          * - Portable Network Graphics - PNG;
00810                          * - Portable image format - PBM, PGM, PPM;
00811                          * - Sun rasters - SR, RAS;
00812                          * - TIFF files - TIFF, TIF.
00813                          *
00814                          * \return False on any error
00815                          * \sa saveToFile, setExternalStorage
00816                          */
00817                         bool  loadFromFile( const std::string& fileName, int isColor = -1  );
00818 
00819                         /** Save the image to a file, whose format is determined from the extension (internally uses OpenCV).
00820                          * \param fileName The file to write to.
00821                          *
00822                          * The supported formats are:
00823                          *
00824                          * - Windows bitmaps - BMP, DIB;
00825                          * - JPEG files - JPEG, JPG, JPE;
00826                          * - Portable Network Graphics - PNG;
00827                          * - Portable image format - PBM, PGM, PPM;
00828                          * - Sun rasters - SR, RAS;
00829                          * - TIFF files - TIFF, TIF.
00830                          *
00831                          * \param jpeg_quality Only for JPEG files, the quality of the compression in the range [0-100]. Larger is better quality but slower.
00832                          * \note jpeg_quality is only effective if MRPT is compiled against OpenCV 1.1.0 or newer.
00833                          * \return False on any error
00834                          * \sa loadFromFile
00835                          */
00836                         bool  saveToFile( const std::string& fileName, int jpeg_quality = 95 ) const;
00837 
00838                         /** Save image to binary stream as a JPEG (.jpg) compresed format.
00839                          * \exception std::exception On number of rows or cols equal to zero, or other errors.
00840                          * \sa saveToJPEG
00841                          */
00842                         void  saveToStreamAsJPEG( CStream               &out  )const;
00843 
00844                         /** @}  */
00845                         // ================================================================
00846 
00847 
00848                         // ================================================================
00849                         /** @name Color/Grayscale conversion
00850                             @{ */
00851 
00852                         /** Returns a grayscale version of the image, or itself if it is already a grayscale image.
00853                           */
00854                         CImage  grayscale() const;
00855 
00856                         /** Returns a grayscale version of the image, or itself if it is already a grayscale image.
00857                           * \sa colorImage
00858                           */
00859                         void grayscale( CImage  &ret ) const;
00860 
00861                         /** Returns a RGB version of the grayscale image, or itself if it is already a RGB image.
00862                           * \sa grayscale
00863                           */
00864                         void colorImage( CImage  &ret ) const;
00865 
00866                         /** Replaces this grayscale image with a RGB version of it.
00867                           * \sa grayscaleInPlace
00868                           */
00869                         void colorImageInPlace();
00870 
00871 
00872                         /** Replaces the image with a grayscale version of it.
00873                           * \sa colorImageInPlace
00874                           */
00875                         void grayscaleInPlace();
00876 
00877                         /** @} */
00878                         // ================================================================
00879 
00880 
00881                 protected:
00882                         /** @name Data members
00883                                 @{ */
00884 
00885                         void    *img;  //!< The internal IplImage pointer to the actual image content.
00886 
00887                         /**  Set to true only when using setFromIplImageReadOnly.
00888                           * \sa setFromIplImageReadOnly  */
00889                         bool    m_imgIsReadOnly;
00890                         /**  Set to true only when using setExternalStorage.
00891                           * \sa setExternalStorage
00892                           */
00893                         mutable bool    m_imgIsExternalStorage;
00894                         mutable std::string     m_externalFile;         //!< The file name of a external storage image.
00895 
00896                         /** @} */
00897 
00898                         /**  Resize the buffers in "img" to accomodate a new image size and/or format.
00899                           */
00900                         void  changeSize(
00901                                         unsigned int    width,
00902                                         unsigned int    height,
00903                                         TImageChannels  nChannels,
00904                                         bool                    originTopLeft );
00905 
00906                         /** Release the internal IPL image, if not NULL or read-only. */
00907                         void releaseIpl(bool thisIsExternalImgUnload = false) MRPT_NO_THROWS;
00908 
00909                         /** Checks if the image is of type "external storage", and if so and not loaded yet, load it. */
00910                         void makeSureImageIsLoaded() const throw (std::exception,utils::CExceptionExternalImageNotFound );
00911 
00912                 }; // End of class
00913 
00914                 typedef CImage CMRPTImage;      //!< Deprecated name.
00915 
00916 
00917         } // end of namespace utils
00918 
00919 } // end of namespace mrpt
00920 
00921 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011