Renesas / opencv-lib

Dependents:   RZ_A2M_Mbed_samples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wimage.hpp Source File

wimage.hpp

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