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 |