opencv 2.2.0
/usr/src/RPM/BUILD/libopencv2.2-2.2.0/modules/core/include/opencv2/core/wimage.hpp
Go to the documentation of this file.
00001 
00002 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00003 //
00004 //  By downloading, copying, installing or using the software you agree to 
00005 //  this license.  If you do not agree to this license, do not download, 
00006 //  install, copy or use the software.
00007 //
00008 //                           License Agreement
00009 //                For Open Source Computer Vision Library
00010 //
00011 // Copyright (C) 2008, Google, all rights reserved.
00012 // Third party copyrights are property of their respective owners.
00013 //
00014 // Redistribution and use in source and binary forms, with or without 
00015 // modification, are permitted provided that the following conditions are met:
00016 //
00017 //  * Redistribution's of source code must retain the above copyright notice,
00018 //     this list of conditions and the following disclaimer.
00019 //
00020 //  * Redistribution's in binary form must reproduce the above copyright notice,
00021 //     this list of conditions and the following disclaimer in the documentation
00022 //     and/or other materials provided with the distribution.
00023 //
00024 //  * The name of Intel Corporation or contributors may not be used to endorse
00025 //     or promote products derived from this software without specific
00026 //     prior written permission.
00027 //
00028 // This software is provided by the copyright holders and contributors "as is" 
00029 // and any express or implied warranties, including, but not limited to, the 
00030 // implied warranties of merchantability and fitness for a particular purpose 
00031 // are disclaimed. In no event shall the Intel Corporation or contributors be 
00032 // liable for any direct, indirect, incidental, special, exemplary, or 
00033 // consequential damages
00034 // (including, but not limited to, procurement of substitute goods or services;
00035 // loss of use, data, or profits; or business interruption) however caused
00036 // and on any theory of liability, whether in contract, strict liability,
00037 // or tort (including negligence or otherwise) arising in any way out of
00038 // the use of this software, even if advised of the possibility of such damage.
00039 
00040 
00042 //
00043 // Image class which provides a thin layer around an IplImage.  The goals
00044 // of the class design are:
00045 //    1. All the data has explicit ownership to avoid memory leaks
00046 //    2. No hidden allocations or copies for performance.
00047 //    3. Easy access to OpenCV methods (which will access IPP if available)
00048 //    4. Can easily treat external data as an image
00049 //    5. Easy to create images which are subsets of other images
00050 //    6. Fast pixel access which can take advantage of number of channels
00051 //          if known at compile time.
00052 //
00053 // The WImage class is the image class which provides the data accessors.
00054 // The 'W' comes from the fact that it is also a wrapper around the popular
00055 // but inconvenient IplImage class. A WImage can be constructed either using a
00056 // WImageBuffer class which allocates and frees the data,
00057 // or using a WImageView class which constructs a subimage or a view into
00058 // external data.  The view class does no memory management.  Each class
00059 // actually has two versions, one when the number of channels is known at
00060 // compile time and one when it isn't.  Using the one with the number of
00061 // channels specified can provide some compile time optimizations by using the
00062 // fact that the number of channels is a constant.
00063 //
00064 // We use the convention (c,r) to refer to column c and row r with (0,0) being
00065 // the upper left corner.  This is similar to standard Euclidean coordinates
00066 // with the first coordinate varying in the horizontal direction and the second
00067 // coordinate varying in the vertical direction.
00068 // Thus (c,r) is usually in the domain [0, width) X [0, height)
00069 //
00070 // Example usage:
00071 // WImageBuffer3_b  im(5,7);  // Make a 5X7 3 channel image of type uchar
00072 // WImageView3_b  sub_im(im, 2,2, 3,3); // 3X3 submatrix
00073 // vector<float> vec(10, 3.0f);
00074 // WImageView1_f user_im(&vec[0], 2, 5);  // 2X5 image w/ supplied data
00075 //
00076 // im.SetZero();  // same as cvSetZero(im.Ipl())
00077 // *im(2, 3) = 15;  // Modify the element at column 2, row 3
00078 // MySetRand(&sub_im);
00079 //
00080 // // Copy the second row into the first.  This can be done with no memory
00081 // // allocation and will use SSE if IPP is available.
00082 // int w = im.Width();
00083 // im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
00084 //
00085 // // Doesn't care about source of data since using WImage
00086 // void MySetRand(WImage_b* im) { // Works with any number of channels
00087 //   for (int r = 0; r < im->Height(); ++r) {
00088 //     float* row = im->Row(r);
00089 //     for (int c = 0; c < im->Width(); ++c) {
00090 //        for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
00091 //          *row = uchar(rand() & 255);
00092 //        }
00093 //     }
00094 //   }
00095 // }
00096 //
00097 // Functions that are not part of the basic image allocation, viewing, and
00098 // access should come from OpenCV, except some useful functions that are not
00099 // part of OpenCV can be found in wimage_util.h
00100 #ifndef __OPENCV_CORE_WIMAGE_HPP__
00101 #define __OPENCV_CORE_WIMAGE_HPP__
00102 
00103 #include "opencv2/core/core_c.h"
00104 
00105 #ifdef __cplusplus
00106 
00107 namespace cv {
00108 
00109 template <typename T> class WImage;
00110 template <typename T> class WImageBuffer;
00111 template <typename T> class WImageView;
00112 
00113 template<typename T, int C> class WImageC;
00114 template<typename T, int C> class WImageBufferC;
00115 template<typename T, int C> class WImageViewC;
00116 
00117 // Commonly used typedefs.
00118 typedef WImage<uchar>            WImage_b;
00119 typedef WImageView<uchar>        WImageView_b;
00120 typedef WImageBuffer<uchar>      WImageBuffer_b;
00121 
00122 typedef WImageC<uchar, 1>        WImage1_b;
00123 typedef WImageViewC<uchar, 1>    WImageView1_b;
00124 typedef WImageBufferC<uchar, 1>  WImageBuffer1_b;
00125 
00126 typedef WImageC<uchar, 3>        WImage3_b;
00127 typedef WImageViewC<uchar, 3>    WImageView3_b;
00128 typedef WImageBufferC<uchar, 3>  WImageBuffer3_b;
00129 
00130 typedef WImage<float>            WImage_f;
00131 typedef WImageView<float>        WImageView_f;
00132 typedef WImageBuffer<float>      WImageBuffer_f;
00133 
00134 typedef WImageC<float, 1>        WImage1_f;
00135 typedef WImageViewC<float, 1>    WImageView1_f;
00136 typedef WImageBufferC<float, 1>  WImageBuffer1_f;
00137 
00138 typedef WImageC<float, 3>        WImage3_f;
00139 typedef WImageViewC<float, 3>    WImageView3_f;
00140 typedef WImageBufferC<float, 3>  WImageBuffer3_f;
00141 
00142 // There isn't a standard for signed and unsigned short so be more
00143 // explicit in the typename for these cases.
00144 typedef WImage<short>            WImage_16s;
00145 typedef WImageView<short>        WImageView_16s;
00146 typedef WImageBuffer<short>      WImageBuffer_16s;
00147 
00148 typedef WImageC<short, 1>        WImage1_16s;
00149 typedef WImageViewC<short, 1>    WImageView1_16s;
00150 typedef WImageBufferC<short, 1>  WImageBuffer1_16s;
00151 
00152 typedef WImageC<short, 3>        WImage3_16s;
00153 typedef WImageViewC<short, 3>    WImageView3_16s;
00154 typedef WImageBufferC<short, 3>  WImageBuffer3_16s;
00155 
00156 typedef WImage<ushort>            WImage_16u;
00157 typedef WImageView<ushort>        WImageView_16u;
00158 typedef WImageBuffer<ushort>      WImageBuffer_16u;
00159 
00160 typedef WImageC<ushort, 1>        WImage1_16u;
00161 typedef WImageViewC<ushort, 1>    WImageView1_16u;
00162 typedef WImageBufferC<ushort, 1>  WImageBuffer1_16u;
00163 
00164 typedef WImageC<ushort, 3>        WImage3_16u;
00165 typedef WImageViewC<ushort, 3>    WImageView3_16u;
00166 typedef WImageBufferC<ushort, 3>  WImageBuffer3_16u;
00167 
00168 //
00169 // WImage definitions
00170 //
00171 // This WImage class gives access to the data it refers to.  It can be
00172 // constructed either by allocating the data with a WImageBuffer class or
00173 // using the WImageView class to refer to a subimage or outside data.
00174 template<typename T>
00175 class WImage
00176 {
00177 public:
00178     typedef T BaseType;
00179 
00180     // WImage is an abstract class with no other virtual methods so make the
00181     // destructor virtual.
00182     virtual ~WImage() = 0;
00183 
00184     // Accessors
00185     IplImage* Ipl() {return image_; }
00186     const IplImage* Ipl() const {return image_; }
00187     T* ImageData() { return reinterpret_cast<T*>(image_->imageData); }
00188     const T* ImageData() const {
00189         return reinterpret_cast<const T*>(image_->imageData);
00190     }
00191 
00192     int Width() const {return image_->width; }
00193     int Height() const {return image_->height; }
00194 
00195     // WidthStep is the number of bytes to go to the pixel with the next y coord
00196     int WidthStep() const {return image_->widthStep; }
00197 
00198     int Channels() const {return image_->nChannels; }
00199     int ChannelSize() const {return sizeof(T); }  // number of bytes per channel
00200 
00201     // Number of bytes per pixel
00202     int PixelSize() const {return Channels() * ChannelSize(); }
00203 
00204     // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number
00205     // of bits per channel and with the signed bit set.
00206     // This is known at compile time using specializations.
00207     int Depth() const;
00208 
00209     inline const T* Row(int r) const {
00210         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
00211     }
00212 
00213     inline T* Row(int r) {
00214         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
00215     }
00216 
00217     // Pixel accessors which returns a pointer to the start of the channel
00218     inline T* operator() (int c, int r)  {
00219         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
00220             c*Channels();
00221     }
00222 
00223     inline const T* operator() (int c, int r) const  {
00224         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
00225             c*Channels();
00226     }
00227 
00228     // Copy the contents from another image which is just a convenience to cvCopy
00229     void CopyFrom(const WImage<T>& src) { cvCopy(src.Ipl(), image_); }
00230 
00231     // Set contents to zero which is just a convenient to cvSetZero
00232     void SetZero() { cvSetZero(image_); }
00233 
00234     // Construct a view into a region of this image
00235     WImageView<T> View(int c, int r, int width, int height);
00236 
00237 protected:
00238     // Disallow copy and assignment
00239     WImage(const WImage&);
00240     void operator=(const WImage&);
00241 
00242     explicit WImage(IplImage* img) : image_(img) {
00243         assert(!img || img->depth == Depth());
00244     }
00245 
00246     void SetIpl(IplImage* image) {
00247         assert(!image || image->depth == Depth());
00248         image_ = image;
00249     }
00250 
00251     IplImage* image_;
00252 };
00253 
00254 
00255 
00256 // Image class when both the pixel type and number of channels
00257 // are known at compile time.  This wrapper will speed up some of the operations
00258 // like accessing individual pixels using the () operator.
00259 template<typename T, int C>
00260 class WImageC : public WImage<T>
00261 {
00262 public:
00263     typedef typename WImage<T>::BaseType BaseType;
00264     enum { kChannels = C };
00265 
00266     explicit WImageC(IplImage* img) : WImage<T>(img) {
00267         assert(!img || img->nChannels == Channels());
00268     }
00269 
00270     // Construct a view into a region of this image
00271     WImageViewC<T, C> View(int c, int r, int width, int height);
00272 
00273     // Copy the contents from another image which is just a convenience to cvCopy
00274     void CopyFrom(const WImageC<T, C>& src) {
00275         cvCopy(src.Ipl(), WImage<T>::image_);
00276     }
00277 
00278     // WImageC is an abstract class with no other virtual methods so make the
00279     // destructor virtual.
00280     virtual ~WImageC() = 0;
00281 
00282     int Channels() const {return C; }
00283 
00284 protected:
00285     // Disallow copy and assignment
00286     WImageC(const WImageC&);
00287     void operator=(const WImageC&);
00288 
00289     void SetIpl(IplImage* image) {
00290         assert(!image || image->depth == WImage<T>::Depth());
00291         WImage<T>::SetIpl(image);
00292     }
00293 };
00294 
00295 //
00296 // WImageBuffer definitions
00297 //
00298 // Image class which owns the data, so it can be allocated and is always
00299 // freed.  It cannot be copied but can be explicity cloned.
00300 //
00301 template<typename T>
00302 class WImageBuffer : public WImage<T>
00303 {
00304 public:
00305     typedef typename WImage<T>::BaseType BaseType;
00306 
00307     // Default constructor which creates an object that can be
00308     WImageBuffer() : WImage<T>(0) {}
00309 
00310     WImageBuffer(int width, int height, int nchannels) : WImage<T>(0) {
00311         Allocate(width, height, nchannels);
00312     }
00313 
00314     // Constructor which takes ownership of a given IplImage so releases
00315     // the image on destruction.
00316     explicit WImageBuffer(IplImage* img) : WImage<T>(img) {}
00317 
00318     // Allocate an image.  Does nothing if current size is the same as
00319     // the new size.
00320     void Allocate(int width, int height, int nchannels);
00321 
00322     // Set the data to point to an image, releasing the old data
00323     void SetIpl(IplImage* img) {
00324         ReleaseImage();
00325         WImage<T>::SetIpl(img);
00326     }
00327 
00328     // Clone an image which reallocates the image if of a different dimension.
00329     void CloneFrom(const WImage<T>& src) {
00330         Allocate(src.Width(), src.Height(), src.Channels());
00331         CopyFrom(src);
00332     }
00333 
00334     ~WImageBuffer() {
00335         ReleaseImage();
00336     }
00337 
00338     // Release the image if it isn't null.
00339     void ReleaseImage() {
00340         if (WImage<T>::image_) {
00341             IplImage* image = WImage<T>::image_;
00342             cvReleaseImage(&image);
00343             WImage<T>::SetIpl(0);
00344         }
00345     }
00346 
00347     bool IsNull() const {return WImage<T>::image_ == NULL; }
00348 
00349 private:
00350     // Disallow copy and assignment
00351     WImageBuffer(const WImageBuffer&);
00352     void operator=(const WImageBuffer&);
00353 };
00354 
00355 // Like a WImageBuffer class but when the number of channels is known
00356 // at compile time.
00357 template<typename T, int C>
00358 class WImageBufferC : public WImageC<T, C>
00359 {
00360 public:
00361     typedef typename WImage<T>::BaseType BaseType;
00362     enum { kChannels = C };
00363 
00364     // Default constructor which creates an object that can be
00365     WImageBufferC() : WImageC<T, C>(0) {}
00366 
00367     WImageBufferC(int width, int height) : WImageC<T, C>(0) {
00368         Allocate(width, height);
00369     }
00370 
00371     // Constructor which takes ownership of a given IplImage so releases
00372     // the image on destruction.
00373     explicit WImageBufferC(IplImage* img) : WImageC<T, C>(img) {}
00374 
00375     // Allocate an image.  Does nothing if current size is the same as
00376     // the new size.
00377     void Allocate(int width, int height);
00378 
00379     // Set the data to point to an image, releasing the old data
00380     void SetIpl(IplImage* img) {
00381         ReleaseImage();
00382         WImageC<T, C>::SetIpl(img);
00383     }
00384 
00385     // Clone an image which reallocates the image if of a different dimension.
00386     void CloneFrom(const WImageC<T, C>& src) {
00387         Allocate(src.Width(), src.Height());
00388         CopyFrom(src);
00389     }
00390 
00391     ~WImageBufferC() {
00392         ReleaseImage();
00393     }
00394 
00395     // Release the image if it isn't null.
00396     void ReleaseImage() {
00397         if (WImage<T>::image_) {
00398             IplImage* image = WImage<T>::image_;
00399             cvReleaseImage(&image);
00400             WImageC<T, C>::SetIpl(0);
00401         }
00402     }
00403 
00404     bool IsNull() const {return WImage<T>::image_ == NULL; }
00405 
00406 private:
00407     // Disallow copy and assignment
00408     WImageBufferC(const WImageBufferC&);
00409     void operator=(const WImageBufferC&);
00410 };
00411 
00412 //
00413 // WImageView definitions
00414 //
00415 // View into an image class which allows treating a subimage as an image
00416 // or treating external data as an image
00417 //
00418 template<typename T>
00419 class WImageView : public WImage<T>
00420 {
00421 public:
00422     typedef typename WImage<T>::BaseType BaseType;
00423 
00424     // Construct a subimage.  No checks are done that the subimage lies
00425     // completely inside the original image.
00426     WImageView(WImage<T>* img, int c, int r, int width, int height);
00427 
00428     // Refer to external data.
00429     // If not given width_step assumed to be same as width.
00430     WImageView(T* data, int width, int height, int channels, int width_step = -1);
00431 
00432     // Refer to external data.  This does NOT take ownership
00433     // of the supplied IplImage.
00434     WImageView(IplImage* img) : WImage<T>(img) {}
00435 
00436     // Copy constructor
00437     WImageView(const WImage<T>& img) : WImage<T>(0) {
00438         header_ = *(img.Ipl());
00439         WImage<T>::SetIpl(&header_);
00440     }
00441 
00442     WImageView& operator=(const WImage<T>& img) {
00443         header_ = *(img.Ipl());
00444         WImage<T>::SetIpl(&header_);
00445         return *this;
00446     }
00447 
00448 protected:
00449     IplImage header_;
00450 };
00451 
00452 
00453 template<typename T, int C>
00454 class WImageViewC : public WImageC<T, C>
00455 {
00456 public:
00457     typedef typename WImage<T>::BaseType BaseType;
00458     enum { kChannels = C };
00459 
00460     // Default constructor needed for vectors of views.
00461     WImageViewC();
00462 
00463     virtual ~WImageViewC() {}
00464 
00465     // Construct a subimage.  No checks are done that the subimage lies
00466     // completely inside the original image.
00467     WImageViewC(WImageC<T, C>* img,
00468         int c, int r, int width, int height);
00469 
00470     // Refer to external data
00471     WImageViewC(T* data, int width, int height, int width_step = -1);
00472 
00473     // Refer to external data.  This does NOT take ownership
00474     // of the supplied IplImage.
00475     WImageViewC(IplImage* img) : WImageC<T, C>(img) {}
00476 
00477     // Copy constructor which does a shallow copy to allow multiple views
00478     // of same data.  gcc-4.1.1 gets confused if both versions of
00479     // the constructor and assignment operator are not provided.
00480     WImageViewC(const WImageC<T, C>& img) : WImageC<T, C>(0) {
00481         header_ = *(img.Ipl());
00482         WImageC<T, C>::SetIpl(&header_);
00483     }
00484     WImageViewC(const WImageViewC<T, C>& img) : WImageC<T, C>(0) {
00485         header_ = *(img.Ipl());
00486         WImageC<T, C>::SetIpl(&header_);
00487     }
00488 
00489     WImageViewC& operator=(const WImageC<T, C>& img) {
00490         header_ = *(img.Ipl());
00491         WImageC<T, C>::SetIpl(&header_);
00492         return *this;
00493     }
00494     WImageViewC& operator=(const WImageViewC<T, C>& img) {
00495         header_ = *(img.Ipl());
00496         WImageC<T, C>::SetIpl(&header_);
00497         return *this;
00498     }
00499 
00500 protected:
00501     IplImage header_;
00502 };
00503 
00504 
00505 // Specializations for depth
00506 template<>
00507 inline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U; }
00508 template<>
00509 inline int WImage<signed char>::Depth() const {return IPL_DEPTH_8S; }
00510 template<>
00511 inline int WImage<short>::Depth() const {return IPL_DEPTH_16S; }
00512 template<>
00513 inline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U; }
00514 template<>
00515 inline int WImage<int>::Depth() const {return IPL_DEPTH_32S; }
00516 template<>
00517 inline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
00518 template<>
00519 inline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
00520 
00521 //
00522 // Pure virtual destructors still need to be defined.
00523 //
00524 template<typename T> inline WImage<T>::~WImage() {}
00525 template<typename T, int C> inline WImageC<T, C>::~WImageC() {}
00526 
00527 //
00528 // Allocate ImageData
00529 //
00530 template<typename T>
00531 inline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
00532 {
00533     if (IsNull() || WImage<T>::Width() != width ||
00534         WImage<T>::Height() != height || WImage<T>::Channels() != nchannels) {
00535         ReleaseImage();
00536         WImage<T>::image_ = cvCreateImage(cvSize(width, height),
00537             WImage<T>::Depth(), nchannels);
00538     }
00539 }
00540 
00541 template<typename T, int C>
00542 inline void WImageBufferC<T, C>::Allocate(int width, int height)
00543 {
00544     if (IsNull() || WImage<T>::Width() != width || WImage<T>::Height() != height) {
00545         ReleaseImage();
00546         WImageC<T, C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(), C));
00547     }
00548 }
00549 
00550 //
00551 // ImageView methods
00552 //
00553 template<typename T>
00554 WImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
00555         : WImage<T>(0)
00556 {
00557     header_ = *(img->Ipl());
00558     header_.imageData = reinterpret_cast<char*>((*img)(c, r));
00559     header_.width = width;
00560     header_.height = height;
00561     WImage<T>::SetIpl(&header_);
00562 }
00563 
00564 template<typename T>
00565 WImageView<T>::WImageView(T* data, int width, int height, int nchannels, int width_step)
00566           : WImage<T>(0)
00567 {
00568     cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), nchannels);
00569     header_.imageData = reinterpret_cast<char*>(data);
00570     if (width_step > 0) {
00571         header_.widthStep = width_step;
00572     }
00573     WImage<T>::SetIpl(&header_);
00574 }
00575 
00576 template<typename T, int C>
00577 WImageViewC<T, C>::WImageViewC(WImageC<T, C>* img, int c, int r, int width, int height)
00578         : WImageC<T, C>(0)
00579 {
00580     header_ = *(img->Ipl());
00581     header_.imageData = reinterpret_cast<char*>((*img)(c, r));
00582     header_.width = width;
00583     header_.height = height;
00584     WImageC<T, C>::SetIpl(&header_);
00585 }
00586 
00587 template<typename T, int C>
00588 WImageViewC<T, C>::WImageViewC() : WImageC<T, C>(0) {
00589     cvInitImageHeader(&header_, cvSize(0, 0), WImage<T>::Depth(), C);
00590     header_.imageData = reinterpret_cast<char*>(0);
00591     WImageC<T, C>::SetIpl(&header_);
00592 }
00593 
00594 template<typename T, int C>
00595 WImageViewC<T, C>::WImageViewC(T* data, int width, int height, int width_step)
00596     : WImageC<T, C>(0)
00597 {
00598     cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), C);
00599     header_.imageData = reinterpret_cast<char*>(data);
00600     if (width_step > 0) {
00601         header_.widthStep = width_step;
00602     }
00603     WImageC<T, C>::SetIpl(&header_);
00604 }
00605 
00606 // Construct a view into a region of an image
00607 template<typename T>
00608 WImageView<T> WImage<T>::View(int c, int r, int width, int height) {
00609     return WImageView<T>(this, c, r, width, height);
00610 }
00611 
00612 template<typename T, int C>
00613 WImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
00614     return WImageViewC<T, C>(this, c, r, width, height);
00615 }
00616 
00617 }  // end of namespace
00618 
00619 #endif // __cplusplus
00620 
00621 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines