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
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
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
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
00147
00156 int load(const char* filename);
00164 int save(const char* filename) const;
00165
00166
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
00230 inline unsigned long nSeg() const
00231 {return nSeg_;};
00232
00233
00234
00246 int load(const char* filename, unsigned long modNum = 0);
00247
00248
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
00305
00306 virtual Image<ELEMENT_TYPE>* operator[](unsigned long);
00307
00308
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
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
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
00437
00438 PNGImage* operator[](unsigned long);
00439
00440
00441
00442 const PNGImage* operator[](unsigned long) const;
00443
00444
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
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
00548
00549 BSIImage* operator[](unsigned long);
00550
00551
00552
00553 const BSIImage* operator[](unsigned long) const;
00554
00559 inline unsigned long nSeg() const
00560 {return nSeg_;};
00561
00562
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
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
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
00695 if (this == &clone) return *this;
00696
00697
00698 if (!imageData_.empty()) imageData_.clear();
00699
00700
00701 this->width_ = clone.width_;
00702 this->height_ = clone.height_;
00703 this->nChl_ = clone.nChl_;
00704
00705
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;
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
00819 if (this == &clone) return *this;
00820
00821
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
00829 this->width_ = clone.width_;
00830 this->height_ = clone.height_;
00831 this->nChl_ = clone.nChl_;
00832
00833
00834 frames_.resize(clone.frames_.size());
00835
00836
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());
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());
00864 if(pos >= frames_.size()) pos = frames_.size()-1;
00865
00866 return frames_[pos];
00867 }
00868
00869 }
00870
00871 #endif // NCUT_IMAGE_H