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