Home | History | Annotate | Download | only in include
      1 ///////////////////////////////////////////////////////////////////////////////
      2 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      3 //
      4 //  By downloading, copying, installing or using the software you agree to
      5 //  this license.  If you do not agree to this license, do not download,
      6 //  install, copy or use the software.
      7 //
      8 //                           License Agreement
      9 //                For Open Source Computer Vision Library
     10 //
     11 // Copyright (C) 2008, Google, all rights reserved.
     12 // Third party copyrights are property of their respective owners.
     13 //
     14 // Redistribution and use in source and binary forms, with or without
     15 // modification, are permitted provided that the following conditions are met:
     16 //
     17 //  * Redistribution's of source code must retain the above copyright notice,
     18 //     this list of conditions and the following disclaimer.
     19 //
     20 //  * Redistribution's in binary form must reproduce the above copyright notice,
     21 //     this list of conditions and the following disclaimer in the documentation
     22 //     and/or other materials provided with the distribution.
     23 //
     24 //  * The name of Intel Corporation or contributors may not be used to endorse
     25 //     or promote products derived from this software without specific
     26 //     prior written permission.
     27 //
     28 // This software is provided by the copyright holders and contributors "as is"
     29 // and any express or implied warranties, including, but not limited to, the
     30 // implied warranties of merchantability and fitness for a particular purpose
     31 // are disclaimed. In no event shall the Intel Corporation or contributors be
     32 // liable for any direct, indirect, incidental, special, exemplary, or
     33 // consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 
     40 
     41 /////////////////////////////////////////////////////////////////////////////////
     42 //
     43 // Image class which provides a thin layer around an IplImage.  The goals
     44 // of the class design are:
     45 //    1. All the data has explicit ownership to avoid memory leaks
     46 //    2. No hidden allocations or copies for performance.
     47 //    3. Easy access to OpenCV methods (which will access IPP if available)
     48 //    4. Can easily treat external data as an image
     49 //    5. Easy to create images which are subsets of other images
     50 //    6. Fast pixel access which can take advantage of number of channels
     51 //          if known at compile time.
     52 //
     53 // The WImage class is the image class which provides the data accessors.
     54 // The 'W' comes from the fact that it is also a wrapper around the popular
     55 // but inconvenient IplImage class. A WImage can be constructed either using a
     56 // WImageBuffer class which allocates and frees the data,
     57 // or using a WImageView class which constructs a subimage or a view into
     58 // external data.  The view class does no memory management.  Each class
     59 // actually has two versions, one when the number of channels is known at
     60 // compile time and one when it isn't.  Using the one with the number of
     61 // channels specified can provide some compile time optimizations by using the
     62 // fact that the number of channels is a constant.
     63 //
     64 // We use the convention (c,r) to refer to column c and row r with (0,0) being
     65 // the upper left corner.  This is similar to standard Euclidean coordinates
     66 // with the first coordinate varying in the horizontal direction and the second
     67 // coordinate varying in the vertical direction.
     68 // Thus (c,r) is usually in the domain [0, width) X [0, height)
     69 //
     70 // Example usage:
     71 // WImageBuffer3_b  im(5,7);  // Make a 5X7 3 channel image of type uchar
     72 // WImageView3_b  sub_im(im, 2,2, 3,3); // 3X3 submatrix
     73 // vector<float> vec(10, 3.0f);
     74 // WImageView1_f user_im(&vec[0], 2, 5);  // 2X5 image w/ supplied data
     75 //
     76 // im.SetZero();  // same as cvSetZero(im.Ipl())
     77 // *im(2, 3) = 15;  // Modify the element at column 2, row 3
     78 // MySetRand(&sub_im);
     79 //
     80 // // Copy the second row into the first.  This can be done with no memory
     81 // // allocation and will use SSE if IPP is available.
     82 // int w = im.Width();
     83 // im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
     84 //
     85 // // Doesn't care about source of data since using WImage
     86 // void MySetRand(WImage_b* im) { // Works with any number of channels
     87 //   for (int r = 0; r < im->Height(); ++r) {
     88 //     float* row = im->Row(r);
     89 //     for (int c = 0; c < im->Width(); ++c) {
     90 //        for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
     91 //          *row = uchar(rand() & 255);
     92 //        }
     93 //     }
     94 //   }
     95 // }
     96 //
     97 // Functions that are not part of the basic image allocation, viewing, and
     98 // access should come from OpenCV, except some useful functions that are not
     99 // part of OpenCV can be found in wimage_util.h
    100 #ifndef _CV_WIMAGE_H_
    101 #define _CV_WIMAGE_H_
    102 
    103 #include "cxcore.h"
    104 
    105 #ifdef __cplusplus
    106 
    107 namespace cv {
    108 
    109 template <typename T> class WImage;
    110 template <typename T> class WImageBuffer;
    111 template <typename T> class WImageView;
    112 
    113 template<typename T, int C> class WImageC;
    114 template<typename T, int C> class WImageBufferC;
    115 template<typename T, int C> class WImageViewC;
    116 
    117 // Commonly used typedefs.
    118 typedef WImage<uchar>            WImage_b;
    119 typedef WImageView<uchar>        WImageView_b;
    120 typedef WImageBuffer<uchar>      WImageBuffer_b;
    121 
    122 typedef WImageC<uchar, 1>        WImage1_b;
    123 typedef WImageViewC<uchar, 1>    WImageView1_b;
    124 typedef WImageBufferC<uchar, 1>  WImageBuffer1_b;
    125 
    126 typedef WImageC<uchar, 3>        WImage3_b;
    127 typedef WImageViewC<uchar, 3>    WImageView3_b;
    128 typedef WImageBufferC<uchar, 3>  WImageBuffer3_b;
    129 
    130 typedef WImage<float>            WImage_f;
    131 typedef WImageView<float>        WImageView_f;
    132 typedef WImageBuffer<float>      WImageBuffer_f;
    133 
    134 typedef WImageC<float, 1>        WImage1_f;
    135 typedef WImageViewC<float, 1>    WImageView1_f;
    136 typedef WImageBufferC<float, 1>  WImageBuffer1_f;
    137 
    138 typedef WImageC<float, 3>        WImage3_f;
    139 typedef WImageViewC<float, 3>    WImageView3_f;
    140 typedef WImageBufferC<float, 3>  WImageBuffer3_f;
    141 
    142 // There isn't a standard for signed and unsigned short so be more
    143 // explicit in the typename for these cases.
    144 typedef WImage<short>            WImage_16s;
    145 typedef WImageView<short>        WImageView_16s;
    146 typedef WImageBuffer<short>      WImageBuffer_16s;
    147 
    148 typedef WImageC<short, 1>        WImage1_16s;
    149 typedef WImageViewC<short, 1>    WImageView1_16s;
    150 typedef WImageBufferC<short, 1>  WImageBuffer1_16s;
    151 
    152 typedef WImageC<short, 3>        WImage3_16s;
    153 typedef WImageViewC<short, 3>    WImageView3_16s;
    154 typedef WImageBufferC<short, 3>  WImageBuffer3_16s;
    155 
    156 typedef WImage<ushort>            WImage_16u;
    157 typedef WImageView<ushort>        WImageView_16u;
    158 typedef WImageBuffer<ushort>      WImageBuffer_16u;
    159 
    160 typedef WImageC<ushort, 1>        WImage1_16u;
    161 typedef WImageViewC<ushort, 1>    WImageView1_16u;
    162 typedef WImageBufferC<ushort, 1>  WImageBuffer1_16u;
    163 
    164 typedef WImageC<ushort, 3>        WImage3_16u;
    165 typedef WImageViewC<ushort, 3>    WImageView3_16u;
    166 typedef WImageBufferC<ushort, 3>  WImageBuffer3_16u;
    167 
    168 //
    169 // WImage definitions
    170 //
    171 // This WImage class gives access to the data it refers to.  It can be
    172 // constructed either by allocating the data with a WImageBuffer class or
    173 // using the WImageView class to refer to a subimage or outside data.
    174 template<typename T>
    175 class WImage
    176 {
    177 public:
    178     typedef T BaseType;
    179 
    180     // WImage is an abstract class with no other virtual methods so make the
    181     // destructor virtual.
    182     virtual ~WImage() = 0;
    183 
    184     // Accessors
    185     IplImage* Ipl() {return image_; }
    186     const IplImage* Ipl() const {return image_; }
    187     T* ImageData() { return reinterpret_cast<T*>(image_->imageData); }
    188     const T* ImageData() const {
    189         return reinterpret_cast<const T*>(image_->imageData);
    190     }
    191 
    192     int Width() const {return image_->width; }
    193     int Height() const {return image_->height; }
    194 
    195     // WidthStep is the number of bytes to go to the pixel with the next y coord
    196     int WidthStep() const {return image_->widthStep; }
    197 
    198     int Channels() const {return image_->nChannels; }
    199     int ChannelSize() const {return sizeof(T); }  // number of bytes per channel
    200 
    201     // Number of bytes per pixel
    202     int PixelSize() const {return Channels() * ChannelSize(); }
    203 
    204     // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number
    205     // of bits per channel and with the signed bit set.
    206     // This is known at compile time using specializations.
    207     int Depth() const;
    208 
    209     inline const T* Row(int r) const {
    210         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
    211     }
    212 
    213     inline T* Row(int r) {
    214         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
    215     }
    216 
    217     // Pixel accessors which returns a pointer to the start of the channel
    218     inline T* operator() (int c, int r)  {
    219         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
    220             c*Channels();
    221     }
    222 
    223     inline const T* operator() (int c, int r) const  {
    224         return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
    225             c*Channels();
    226     }
    227 
    228     // Copy the contents from another image which is just a convenience to cvCopy
    229     void CopyFrom(const WImage<T>& src) { cvCopy(src.Ipl(), image_); }
    230 
    231     // Set contents to zero which is just a convenient to cvSetZero
    232     void SetZero() { cvSetZero(image_); }
    233 
    234     // Construct a view into a region of this image
    235     WImageView<T> View(int c, int r, int width, int height);
    236 
    237 protected:
    238     // Disallow copy and assignment
    239     WImage(const WImage&);
    240     void operator=(const WImage&);
    241 
    242     explicit WImage(IplImage* img) : image_(img) {
    243         assert(!img || img->depth == Depth());
    244     }
    245 
    246     void SetIpl(IplImage* image) {
    247         assert(!image || image->depth == Depth());
    248         image_ = image;
    249     }
    250 
    251     IplImage* image_;
    252 };
    253 
    254 
    255 
    256 // Image class when both the pixel type and number of channels
    257 // are known at compile time.  This wrapper will speed up some of the operations
    258 // like accessing individual pixels using the () operator.
    259 template<typename T, int C>
    260 class WImageC : public WImage<T>
    261 {
    262 public:
    263     typedef typename WImage<T>::BaseType BaseType;
    264     enum { kChannels = C };
    265 
    266     explicit WImageC(IplImage* img) : WImage<T>(img) {
    267         assert(!img || img->nChannels == Channels());
    268     }
    269 
    270     // Construct a view into a region of this image
    271     WImageViewC<T, C> View(int c, int r, int width, int height);
    272 
    273     // Copy the contents from another image which is just a convenience to cvCopy
    274     void CopyFrom(const WImageC<T, C>& src) {
    275         cvCopy(src.Ipl(), WImage<T>::image_);
    276     }
    277 
    278     // WImageC is an abstract class with no other virtual methods so make the
    279     // destructor virtual.
    280     virtual ~WImageC() = 0;
    281 
    282     int Channels() const {return C; }
    283 
    284 protected:
    285     // Disallow copy and assignment
    286     WImageC(const WImageC&);
    287     void operator=(const WImageC&);
    288 
    289     void SetIpl(IplImage* image) {
    290         assert(!image || image->depth == WImage<T>::Depth());
    291         WImage<T>::SetIpl(image);
    292     }
    293 };
    294 
    295 //
    296 // WImageBuffer definitions
    297 //
    298 // Image class which owns the data, so it can be allocated and is always
    299 // freed.  It cannot be copied but can be explicity cloned.
    300 //
    301 template<typename T>
    302 class WImageBuffer : public WImage<T>
    303 {
    304 public:
    305     typedef typename WImage<T>::BaseType BaseType;
    306 
    307     // Default constructor which creates an object that can be
    308     WImageBuffer() : WImage<T>(0) {}
    309 
    310     WImageBuffer(int width, int height, int nchannels) : WImage<T>(0) {
    311         Allocate(width, height, nchannels);
    312     }
    313 
    314     // Constructor which takes ownership of a given IplImage so releases
    315     // the image on destruction.
    316     explicit WImageBuffer(IplImage* img) : WImage<T>(img) {}
    317 
    318     // Allocate an image.  Does nothing if current size is the same as
    319     // the new size.
    320     void Allocate(int width, int height, int nchannels);
    321 
    322     // Set the data to point to an image, releasing the old data
    323     void SetIpl(IplImage* img) {
    324         ReleaseImage();
    325         WImage<T>::SetIpl(img);
    326     }
    327 
    328     // Clone an image which reallocates the image if of a different dimension.
    329     void CloneFrom(const WImage<T>& src) {
    330         Allocate(src.Width(), src.Height());
    331         CopyFrom(src);
    332     }
    333 
    334     ~WImageBuffer() {
    335         ReleaseImage();
    336     }
    337 
    338     // Release the image if it isn't null.
    339     void ReleaseImage() {
    340         if (WImage<T>::image_) {
    341             IplImage* image = WImage<T>::image_;
    342             cvReleaseImage(&image);
    343             WImage<T>::SetIpl(0);
    344         }
    345     }
    346 
    347     bool IsNull() const {return WImage<T>::image_ == NULL; }
    348 
    349 private:
    350     // Disallow copy and assignment
    351     WImageBuffer(const WImageBuffer&);
    352     void operator=(const WImageBuffer&);
    353 };
    354 
    355 // Like a WImageBuffer class but when the number of channels is known
    356 // at compile time.
    357 template<typename T, int C>
    358 class WImageBufferC : public WImageC<T, C>
    359 {
    360 public:
    361     typedef typename WImage<T>::BaseType BaseType;
    362     enum { kChannels = C };
    363 
    364     // Default constructor which creates an object that can be
    365     WImageBufferC() : WImageC<T, C>(0) {}
    366 
    367     WImageBufferC(int width, int height) : WImageC<T, C>(0) {
    368         Allocate(width, height);
    369     }
    370 
    371     // Constructor which takes ownership of a given IplImage so releases
    372     // the image on destruction.
    373     explicit WImageBufferC(IplImage* img) : WImageC<T, C>(img) {}
    374 
    375     // Allocate an image.  Does nothing if current size is the same as
    376     // the new size.
    377     void Allocate(int width, int height);
    378 
    379     // Set the data to point to an image, releasing the old data
    380     void SetIpl(IplImage* img) {
    381         ReleaseImage();
    382         WImageC<T, C>::SetIpl(img);
    383     }
    384 
    385     // Clone an image which reallocates the image if of a different dimension.
    386     void CloneFrom(const WImageC<T, C>& src) {
    387         Allocate(src.Width(), src.Height());
    388         CopyFrom(src);
    389     }
    390 
    391     ~WImageBufferC() {
    392         ReleaseImage();
    393     }
    394 
    395     // Release the image if it isn't null.
    396     void ReleaseImage() {
    397         if (WImage<T>::image_) {
    398             IplImage* image = WImage<T>::image_;
    399             cvReleaseImage(&image);
    400             WImageC<T, C>::SetIpl(0);
    401         }
    402     }
    403 
    404     bool IsNull() const {return WImage<T>::image_ == NULL; }
    405 
    406 private:
    407     // Disallow copy and assignment
    408     WImageBufferC(const WImageBufferC&);
    409     void operator=(const WImageBufferC&);
    410 };
    411 
    412 //
    413 // WImageView definitions
    414 //
    415 // View into an image class which allows treating a subimage as an image
    416 // or treating external data as an image
    417 //
    418 template<typename T>
    419 class WImageView : public WImage<T>
    420 {
    421 public:
    422     typedef typename WImage<T>::BaseType BaseType;
    423 
    424     // Construct a subimage.  No checks are done that the subimage lies
    425     // completely inside the original image.
    426     WImageView(WImage<T>* img, int c, int r, int width, int height);
    427 
    428     // Refer to external data.
    429     // If not given width_step assumed to be same as width.
    430     WImageView(T* data, int width, int height, int channels, int width_step = -1);
    431 
    432     // Refer to external data.  This does NOT take ownership
    433     // of the supplied IplImage.
    434     WImageView(IplImage* img) : WImage<T>(img) {}
    435 
    436     // Copy constructor
    437     WImageView(const WImage<T>& img) : WImage<T>(0) {
    438         header_ = *(img.Ipl());
    439         WImage<T>::SetIpl(&header_);
    440     }
    441 
    442     WImageView& operator=(const WImage<T>& img) {
    443         header_ = *(img.Ipl());
    444         WImage<T>::SetIpl(&header_);
    445         return *this;
    446     }
    447 
    448 protected:
    449     IplImage header_;
    450 };
    451 
    452 
    453 template<typename T, int C>
    454 class WImageViewC : public WImageC<T, C>
    455 {
    456 public:
    457     typedef typename WImage<T>::BaseType BaseType;
    458     enum { kChannels = C };
    459 
    460     // Default constructor needed for vectors of views.
    461     WImageViewC();
    462 
    463     virtual ~WImageViewC() {}
    464 
    465     // Construct a subimage.  No checks are done that the subimage lies
    466     // completely inside the original image.
    467     WImageViewC(WImageC<T, C>* img,
    468         int c, int r, int width, int height);
    469 
    470     // Refer to external data
    471     WImageViewC(T* data, int width, int height, int width_step = -1);
    472 
    473     // Refer to external data.  This does NOT take ownership
    474     // of the supplied IplImage.
    475     WImageViewC(IplImage* img) : WImageC<T, C>(img) {}
    476 
    477     // Copy constructor which does a shallow copy to allow multiple views
    478     // of same data.  gcc-4.1.1 gets confused if both versions of
    479     // the constructor and assignment operator are not provided.
    480     WImageViewC(const WImageC<T, C>& img) : WImageC<T, C>(0) {
    481         header_ = *(img.Ipl());
    482         WImageC<T, C>::SetIpl(&header_);
    483     }
    484     WImageViewC(const WImageViewC<T, C>& img) : WImageC<T, C>(0) {
    485         header_ = *(img.Ipl());
    486         WImageC<T, C>::SetIpl(&header_);
    487     }
    488 
    489     WImageViewC& operator=(const WImageC<T, C>& img) {
    490         header_ = *(img.Ipl());
    491         WImageC<T, C>::SetIpl(&header_);
    492         return *this;
    493     }
    494     WImageViewC& operator=(const WImageViewC<T, C>& img) {
    495         header_ = *(img.Ipl());
    496         WImageC<T, C>::SetIpl(&header_);
    497         return *this;
    498     }
    499 
    500 protected:
    501     IplImage header_;
    502 };
    503 
    504 
    505 // Specializations for depth
    506 template<>
    507 inline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U; }
    508 template<>
    509 inline int WImage<schar>::Depth() const {return IPL_DEPTH_8S; }
    510 template<>
    511 inline int WImage<short>::Depth() const {return IPL_DEPTH_16S; }
    512 template<>
    513 inline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U; }
    514 template<>
    515 inline int WImage<int>::Depth() const {return IPL_DEPTH_32S; }
    516 template<>
    517 inline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
    518 template<>
    519 inline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
    520 
    521 //
    522 // Pure virtual destructors still need to be defined.
    523 //
    524 template<typename T> inline WImage<T>::~WImage() {}
    525 template<typename T, int C> inline WImageC<T, C>::~WImageC() {}
    526 
    527 //
    528 // Allocate ImageData
    529 //
    530 template<typename T>
    531 inline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
    532 {
    533     if (IsNull() || WImage<T>::Width() != width ||
    534         WImage<T>::Height() != height || WImage<T>::Channels() != nchannels) {
    535         ReleaseImage();
    536         WImage<T>::image_ = cvCreateImage(cvSize(width, height),
    537             WImage<T>::Depth(), nchannels);
    538     }
    539 }
    540 
    541 template<typename T, int C>
    542 inline void WImageBufferC<T, C>::Allocate(int width, int height)
    543 {
    544     if (IsNull() || WImage<T>::Width() != width || WImage<T>::Height() != height) {
    545         ReleaseImage();
    546         WImageC<T, C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(), C));
    547     }
    548 }
    549 
    550 //
    551 // ImageView methods
    552 //
    553 template<typename T>
    554 WImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
    555         : WImage<T>(0)
    556 {
    557     header_ = *(img->Ipl());
    558     header_.imageData = reinterpret_cast<char*>((*img)(c, r));
    559     header_.width = width;
    560     header_.height = height;
    561     WImage<T>::SetIpl(&header_);
    562 }
    563 
    564 template<typename T>
    565 WImageView<T>::WImageView(T* data, int width, int height, int nchannels, int width_step)
    566           : WImage<T>(0)
    567 {
    568     cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), nchannels);
    569     header_.imageData = reinterpret_cast<char*>(data);
    570     if (width_step > 0) {
    571         header_.widthStep = width_step;
    572     }
    573     WImage<T>::SetIpl(&header_);
    574 }
    575 
    576 template<typename T, int C>
    577 WImageViewC<T, C>::WImageViewC(WImageC<T, C>* img, int c, int r, int width, int height)
    578         : WImageC<T, C>(0)
    579 {
    580     header_ = *(img->Ipl());
    581     header_.imageData = reinterpret_cast<char*>((*img)(c, r));
    582     header_.width = width;
    583     header_.height = height;
    584     WImageC<T, C>::SetIpl(&header_);
    585 }
    586 
    587 template<typename T, int C>
    588 WImageViewC<T, C>::WImageViewC() : WImageC<T, C>(0) {
    589     cvInitImageHeader(&header_, cvSize(0, 0), WImage<T>::Depth(), C);
    590     header_.imageData = reinterpret_cast<char*>(0);
    591     WImageC<T, C>::SetIpl(&header_);
    592 }
    593 
    594 template<typename T, int C>
    595 WImageViewC<T, C>::WImageViewC(T* data, int width, int height, int width_step)
    596     : WImageC<T, C>(0)
    597 {
    598     cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), C);
    599     header_.imageData = reinterpret_cast<char*>(data);
    600     if (width_step > 0) {
    601         header_.widthStep = width_step;
    602     }
    603     WImageC<T, C>::SetIpl(&header_);
    604 }
    605 
    606 // Construct a view into a region of an image
    607 template<typename T>
    608 WImageView<T> WImage<T>::View(int c, int r, int width, int height) {
    609     return WImageView<T>(this, c, r, width, height);
    610 }
    611 
    612 template<typename T, int C>
    613 WImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
    614     return WImageViewC<T, C>(this, c, r, width, height);
    615 }
    616 
    617 }  // end of namespace
    618 
    619 #endif // __cplusplus
    620 
    621 #endif  // _CV_WIMAGE_H_
    622