opencv 2.2.0
|
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