ncutImage.h

00001 #ifndef NCUT_IMAGE_H
00002 #define NCUT_IMAGE_H 1
00003 
00004 #include "TImageSegmentation.h"
00005 #include "CImageSegmentationIndexFile.h"
00006 #include "ncutException.h"
00007 
00008 #include <png.h>
00009 #include <vector>
00010 #include <deque>
00011 #include <iostream>
00012 
00013 #define PNG_IMAGE_DATATYPE png_byte
00014 #define BSI_IMAGE_DATATYPE signed long
00015 
00016 namespace ncut
00017 {
00018 
00019 const PNG_IMAGE_DATATYPE PNG_IMAGE_DATATYPE_MAXVAL = 255;
00020 const PNG_IMAGE_DATATYPE PNG_IMAGE_DATATYPE_MINVAL = 0;
00021 const unsigned int IMAGE_DATATYPE_MAXVAL = 255;
00022 
00029 template <class ELEMENT_TYPE = unsigned char>
00030 class Image
00031 {
00032   public:
00033 
00034     // functions for read & write access to data members ------
00035 
00041     inline ELEMENT_TYPE& val(unsigned int elm)
00042     {return imageData_[elm];};
00049     inline ELEMENT_TYPE& val(unsigned int pxl, unsigned int chl)
00050     {return imageData_[(pxl*nChl_)+chl];};
00051 
00052     // functions for read-only access to data members ------
00053 
00059     inline const ELEMENT_TYPE& val(unsigned int elm) const
00060     {return imageData_[elm];};
00067     inline const ELEMENT_TYPE& val(unsigned int pxl, unsigned int chl) const
00068     {return imageData_[(pxl*nChl_)+chl];};
00073     inline unsigned int width() const
00074     {return width_;};
00079     inline unsigned int height() const
00080     {return height_;};
00085     inline unsigned int nChl() const
00086     {return nChl_;};
00087 
00088     // standard functions ------
00089 
00095     Image();
00106     Image(int width, int height, int nChl);
00107               
00113     Image(const Image& clone);
00114 
00118     virtual ~Image();
00119 
00126     virtual Image& operator=(const Image& clone);
00127 
00128   protected:
00129 
00130     std::vector<ELEMENT_TYPE> imageData_; 
00132     unsigned int width_;
00133     unsigned int height_;
00134     unsigned int nChl_; 
00136 };
00137 
00142 class PNGImage : public Image<PNG_IMAGE_DATATYPE>
00143 {
00144   public:
00145 
00146     // class-specific functions ------
00147 
00156     int load(const char* filename);
00164     int save(const char* filename) const;
00165 
00166     // standard functions ------
00167 
00173     PNGImage();
00179     PNGImage(const PNGImage& clone);
00187     PNGImage(const char* filename);
00188 
00189               
00200     PNGImage(int width, int height, int nChl);
00201 
00205     virtual ~PNGImage();
00206 
00213     virtual PNGImage& operator=(const PNGImage& clone);
00214 };
00215 
00221 class BSIImage : public Image<BSI_IMAGE_DATATYPE>
00222 {
00223   public:
00224 
00225     // functions for read-only access to data members ------
00230     inline unsigned long nSeg() const
00231     {return nSeg_;};
00232 
00233     // class-specific functions ------
00234 
00246     int load(const char* filename, unsigned long modNum = 0);
00247 
00248     // standard functions ------
00249 
00255     BSIImage();
00261     BSIImage(const BSIImage& clone);
00272     BSIImage(const char* filename, unsigned long& modNum);
00273 
00277     virtual ~BSIImage();
00278 
00285     virtual BSIImage& operator=(const BSIImage& clone);
00286 
00287   protected:
00288 
00289     unsigned long nSeg_; 
00290 };
00291 
00299 template <class ELEMENT_TYPE = unsigned char>
00300 class Sequence
00301 {
00302   public:
00303 
00304     // functions for read & write access to data members ------
00305 
00306     virtual Image<ELEMENT_TYPE>* operator[](unsigned long);
00307 
00308     // functions for read-only access to data members ------
00309 
00310     virtual const Image<ELEMENT_TYPE>* operator[](unsigned long) const;
00311 
00316     inline unsigned int width() const
00317     {return width_;};
00322     inline unsigned int height() const
00323     {return height_;};
00328     inline unsigned int nChl() const
00329     {return nChl_;};
00334     inline unsigned int length() const
00335     {return frames_.size();};
00336 
00337     // class-specific functions ------
00338 
00350     virtual int pushThrough(const Image<ELEMENT_TYPE>& frame);
00361     virtual int pushFrame(const Image<ELEMENT_TYPE>& frame);
00368     virtual void popFrame();
00376     virtual int clear();
00377 
00378     // standard functions ------
00379 
00385     Sequence();
00391     Sequence(const Sequence& clone);
00392 
00396     virtual ~Sequence();
00397 
00404     virtual Sequence& operator=(const Sequence& clone);
00405 
00406 
00407   protected:
00408 
00409     std::deque<Image<ELEMENT_TYPE>* > frames_; 
00411     unsigned int width_;
00412     unsigned int height_;
00413     unsigned int nChl_; 
00425     bool validateFrame(const Image<ELEMENT_TYPE>& frame);
00426 };
00427 
00432 class PNGSequence : public Sequence<PNG_IMAGE_DATATYPE>
00433 {
00434   public:
00435 
00436     // functions for read & write access to data members ------
00437 
00438     PNGImage* operator[](unsigned long);
00439 
00440     // functions for read-only access to data members ------
00441 
00442     const PNGImage* operator[](unsigned long) const;
00443 
00444     // class-specific functions ------
00445 
00457     int pushThrough(const Image<PNG_IMAGE_DATATYPE>& frame);
00469     int pushThrough(const PNGImage& frame);
00480     int pushFrame(const Image<PNG_IMAGE_DATATYPE>& frame);
00491     int pushFrame(const PNGImage& frame);
00498     void popFrame();
00508     int save(const char* filename) const;
00509 
00510     // standard functions ------
00511 
00517     PNGSequence();
00523     PNGSequence(const PNGSequence& clone);
00524 
00528     virtual ~PNGSequence();
00529 
00536     virtual PNGSequence& operator=(const PNGSequence& clone);
00537 };
00538 
00543 class BSISequence : public Sequence<BSI_IMAGE_DATATYPE>
00544 {
00545   public:
00546 
00547     // functions for read & write access to data members ------
00548 
00549     BSIImage* operator[](unsigned long);
00550 
00551     // functions for read-only access to data members ------
00552 
00553     const BSIImage* operator[](unsigned long) const;
00554 
00559     inline unsigned long nSeg() const
00560     {return nSeg_;};
00561 
00562     // class-specific functions ------
00563 
00575     int pushThrough(const Image<BSI_IMAGE_DATATYPE>& frame);
00587     int pushThrough(const BSIImage& frame);
00598     int pushFrame(const Image<BSI_IMAGE_DATATYPE>& frame);
00609     int pushFrame(const BSIImage& frame);
00616     void popFrame();
00625     int clear();
00626 
00627     // standard functions ------
00628 
00634     BSISequence();
00640     BSISequence(const BSISequence& clone);
00641 
00645     virtual ~BSISequence();
00646 
00653     virtual BSISequence& operator=(const BSISequence& clone);
00654 
00655   protected:
00656 
00657     unsigned long nSeg_; 
00658 };
00659 
00660 
00661 /* template implementations ------------------------------------------------- */
00662 
00663 template <class ELEMENT_TYPE>
00664 Image<ELEMENT_TYPE>::Image()
00665   : imageData_(), width_(0), height_(0), nChl_(0)
00666 {
00667   return;
00668 }
00669 
00670 template <class ELEMENT_TYPE>
00671 Image<ELEMENT_TYPE>::Image(const Image& clone)
00672   : imageData_(), width_(0), height_(0), nChl_(0)
00673 {
00674   *this = clone;
00675 }
00676 
00677 template <class ELEMENT_TYPE>
00678 Image<ELEMENT_TYPE>::Image(int width, int height, int nChl)
00679   : imageData_(), width_(width), height_(height), nChl_(nChl)
00680 {
00681   imageData_.resize(width_*height_*nChl_);
00682   return;
00683 }
00684 
00685 template <class ELEMENT_TYPE>
00686 Image<ELEMENT_TYPE>::~Image()
00687 {
00688   return;
00689 }
00690 
00691 template <class ELEMENT_TYPE>
00692 Image<ELEMENT_TYPE>& Image<ELEMENT_TYPE>::operator=(const Image& clone)
00693 {
00694   // check for self-assignment
00695   if (this == &clone) return *this;
00696 
00697   // clear old data
00698   if (!imageData_.empty()) imageData_.clear();
00699 
00700   // copy image info from clone
00701   this->width_ = clone.width_;
00702   this->height_ = clone.height_;
00703   this->nChl_ = clone.nChl_;
00704 
00705   // copy image data from the clone
00706   imageData_ = clone.imageData_;
00707 
00708   return *this;
00709 }
00710 
00711 template <class ELEMENT_TYPE>
00712 bool Sequence<ELEMENT_TYPE>::validateFrame(const Image<ELEMENT_TYPE>& frame)
00713 {
00714   if (frames_.empty()) {
00715     width_  = frame.width();
00716     height_ = frame.height();
00717     nChl_   = frame.nChl();
00718   }
00719   else {
00720     if (width_  != frame.width() ||
00721         height_ != frame.height() ||
00722         nChl_   != frame.nChl()) {
00723       return false; // dimensions of all frames must agree
00724     }
00725   }
00726 
00727   return true;
00728 }
00729 
00730 template <class ELEMENT_TYPE>
00731 int Sequence<ELEMENT_TYPE>::pushThrough(const Image<ELEMENT_TYPE>& frame)
00732 {
00733   if (!validateFrame(frame)) {
00734     throw ncutException("frame does not fit into the sequence (wrong format?)");
00735   }
00736 
00737   if (frames_.empty()) {
00738     pushFrame(frame);
00739     return 0;
00740   }
00741 
00742   delete frames_.front();
00743   frames_.pop_front();
00744 
00745   Image<ELEMENT_TYPE> *clone = new Image<ELEMENT_TYPE>(frame);
00746 
00747   frames_.push_back(clone);
00748 
00749   return 0;
00750 }
00751 
00752 template <class ELEMENT_TYPE>
00753 int Sequence<ELEMENT_TYPE>::pushFrame(const Image<ELEMENT_TYPE>& frame)
00754 {
00755   if (!validateFrame(frame)) {
00756     throw ncutException("frame does not fit into the sequence (wrong format?)");
00757   }
00758 
00759   Image<ELEMENT_TYPE> *clone = new Image<ELEMENT_TYPE>(frame);
00760 
00761   frames_.push_back(clone);
00762 
00763   return 0;
00764 }
00765 
00766 template <class ELEMENT_TYPE>
00767 void Sequence<ELEMENT_TYPE>::popFrame()
00768 {
00769   if (!frames_.empty()) {
00770     delete frames_.back();
00771     frames_.pop_back();
00772   }
00773 }
00774 
00775 template <class ELEMENT_TYPE>
00776 int Sequence<ELEMENT_TYPE>::clear()
00777 {
00778   for (unsigned int i=0; i<frames_.size(); i++) {
00779     delete frames_[i];
00780     frames_[i] = NULL;
00781   }
00782   if (!frames_.empty()) frames_.clear();
00783 
00784   width_  = 0;
00785   height_ = 0;
00786   nChl_   = 0;
00787 
00788   return 0;
00789 }
00790 
00791 template <class ELEMENT_TYPE>
00792 Sequence<ELEMENT_TYPE>::Sequence()
00793   : frames_(), width_(0), height_(0), nChl_(0)
00794 {
00795   return;
00796 }
00797 
00798 template <class ELEMENT_TYPE>
00799 Sequence<ELEMENT_TYPE>::Sequence(const Sequence& clone)
00800   : frames_(), width_(0), height_(0), nChl_(0)
00801 {
00802   *this = clone;
00803 }
00804 
00805 template <class ELEMENT_TYPE>
00806 Sequence<ELEMENT_TYPE>::~Sequence()
00807 {
00808   for (unsigned int i=0; i<frames_.size(); i++) {
00809     delete frames_[i];
00810     frames_[i] = NULL;
00811   }
00812   if (!frames_.empty()) frames_.clear();
00813 }
00814 
00815 template <class ELEMENT_TYPE>
00816 Sequence<ELEMENT_TYPE>& Sequence<ELEMENT_TYPE>::operator=(const Sequence& clone)
00817 {
00818   // check for self-assignment
00819   if (this == &clone) return *this;
00820 
00821   // free old memory
00822   for (unsigned int i=0; i<frames_.size(); i++) {
00823     delete frames_[i];
00824     frames_[i] = NULL;
00825   }
00826   if (!frames_.empty()) frames_.clear();
00827 
00828   // copy sequence info from clone
00829   this->width_  = clone.width_;
00830   this->height_ = clone.height_;
00831   this->nChl_   = clone.nChl_;
00832 
00833   // initialize the local structure
00834   frames_.resize(clone.frames_.size());
00835 
00836   // copy the sequence data from the clone
00837   for (unsigned int i=0; i<frames_.size(); i++) {
00838     if (clone.frames_[i] != NULL) {
00839       this->frames_[i] = new Image<ELEMENT_TYPE>(*(clone.frames_[i]));
00840     }
00841     else {
00842       this->frames_[i] = NULL;
00843     }
00844   }
00845 
00846   return *this;
00847 }
00848 
00849 template <class ELEMENT_TYPE>
00850 Image<ELEMENT_TYPE>* Sequence<ELEMENT_TYPE>::
00851   operator[](unsigned long pos)
00852 {
00853   assert(pos < frames_.size()); // alle asserts kommen am ende weg
00854   if(pos >= frames_.size()) pos = frames_.size()-1;
00855 
00856   return frames_[pos];
00857 }
00858 
00859 template <class ELEMENT_TYPE>
00860 const Image<ELEMENT_TYPE>* Sequence<ELEMENT_TYPE>::
00861   operator[](unsigned long pos) const
00862 {
00863   assert(pos < frames_.size()); // alle asserts kommen am ende weg
00864   if(pos >= frames_.size()) pos = frames_.size()-1;
00865 
00866   return frames_[pos];
00867 }
00868 
00869 } // namespace ncut
00870 
00871 #endif // NCUT_IMAGE_H

Generated on Thu Jun 22 14:47:20 2006 for ncut.kdevelop by  doxygen 1.4.6