imgclass.hpp

Go to the documentation of this file.
00001 #ifndef imgclass_hpp
00002 #define imgclass_hpp
00003 
00004 #include <iostream>
00005 #include <valarray>
00006 #include <string>
00007 #include <sstream>
00008 #include "matrixutil.hpp"
00009 #include "vc6compat.h"
00010 
00012 #define TRACE(x) 
00013 #define TRACEX(x,y)
00014 
00016 
00031 #define STHROW(msg) { \
00032          std::ostringstream err;\
00033          err<<msg; \
00034          throw err.str(); }
00035 
00036 #define THROWSPEC throw(std::string)
00037 
00038 
00040 
00055 #define MAP(img) for (int y=0; y<img.SIZEY; y++) \
00056                   for (int x=0; x<img.SIZEX; x++)
00057 
00059 
00061 #define MAP_CIRCLE(img, radius) MAP(img) \
00062                      if (SQR(x-img.SIZEX/2)+ SQR(y-img.SIZEY/2) <= SQR(radius))
00063 
00065 
00067 #define MAP_REGION(region) MAP(region) if (region(y,x)) 
00068 
00070 
00072 #define MAP_CIRCLE_XY(img, radius, xm, ym) \
00073                for (int y=ym-radius; y<=ym+radius; y++) \
00074                   for (int x=xm-radius; x<=xm+radius; x++) \
00075                      if ((x>=0) && (x<img.SIZEX) && (y>=0) && (y<img.SIZEY)) \
00076                       if (SQR(x-xm)+ SQR(y-ym) <= SQR(radius))
00077 
00078 
00080 
00083 #define MAPF(img, Functor) MAP(img) { Functor(img(y,x)); }
00084 
00086 
00089 #define MAPFXY(img, Functor) MAP(img) { Functor(x, y, img(y,x)); }
00090 
00091 /* bequemes Iterieren über ein Bild */
00092 
00093 
00095  template <typename T> inline T SQR (T x) {
00096     return x * x;
00097   } 
00098  
00100 
00110   template < int s_x, int s_y, typename T > 
00111   class imgbase {
00112   public:
00114 
00123     typedef T data_t;
00124 
00126     const int SIZEX;
00127 
00129     const int SIZEY;
00130     
00131     imgbase ();  
00132     imgbase (const imgbase& im);
00133     ~imgbase (); 
00135 
00138     T& operator  () (int y, int x) { return bild[y][x]; }
00140     const T & operator  () (int y, int x) const { return bild[y][x]; }
00141 
00143     imgbase<s_x, s_y, T>& operator =  (const imgbase<s_x, s_y, T>& what); 
00145     imgbase<s_x, s_y, T>& operator /= (const imgbase<s_x, s_y, T>& what); 
00147     imgbase<s_x, s_y, T>& operator /= (const T& what);
00149     imgbase<s_x, s_y, T>& operator *= (const imgbase<s_x, s_y, T>& what); 
00151     imgbase<s_x, s_y, T>& operator *= (const T& what);
00153     imgbase<s_x, s_y, T>& operator -= (const imgbase<s_x, s_y, T>& what);
00155     imgbase<s_x, s_y, T>& operator -= (const T& what);
00157     imgbase<s_x, s_y, T>& operator += (const imgbase<s_x, s_y, T>& what);
00159     imgbase<s_x, s_y, T>& operator += (const T& what);
00160   protected:
00161     data_t ** bild; 
00162   };
00163 
00164 
00166 
00168   template < int s_x, int s_y, typename T >
00169   imgbase<s_x, s_y, T>::imgbase () : 
00170      SIZEX (s_x), SIZEY (s_y) {
00171     // reserve memory for bild
00172      reserve_2D(bild, s_x, s_y);  
00173   }
00174 
00175 
00177 
00180   template < int s_x, int s_y, typename T >
00181   imgbase<s_x, s_y, T>::imgbase (const imgbase &im) : 
00182      SIZEX (s_x), SIZEY (s_y) {
00183     // reserve memory for bild
00184     reserve_2D(bild, s_x, s_y);  
00185     operator = (im);  
00186    }
00187   
00189 
00191   template < int s_x, int s_y, typename T >
00192   imgbase<s_x, s_y, T>::~imgbase () {
00193     // release memory
00194     delete_2D(bild);
00195   }
00196   
00211   template < int s_x, int s_y, typename T >
00212   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator = (const imgbase<s_x, s_y, T>& what)
00213   {
00214      MAP(what)
00215         bild[y][x]=what(y,x);
00216     return *this;       
00217   }     
00218   
00219 
00223   template < int s_x, int s_y, typename T >
00224   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator /= (const imgbase<s_x, s_y, T>& what)
00225   {
00226     MAP(what) {
00227         T val=what(y,x);
00228         if (val!=0) bild[y][x]/=val;
00229       } 
00230     return *this;       
00231   }     
00232   
00235   template < int s_x, int s_y, typename T >
00236   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator *= (const imgbase<s_x, s_y, T>& what)
00237   {
00238     MAP(what) {
00239         T val=what(y,x);
00240         bild[y][x]*=val;
00241       } 
00242     return *this;       
00243   }     
00244 
00245 
00248   template < int s_x, int s_y, typename T >
00249   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator -= (const imgbase<s_x, s_y, T>& what)
00250   {
00251     MAP((*this)) {
00252         T val=what(y,x);
00253         bild[y][x]-=val;
00254       } 
00255     return *this;       
00256   }     
00257 
00260   template < int s_x, int s_y, typename T >
00261   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator /= (const T& what)
00262   {
00263     MAP((*this)) {
00264         if (what!=0) bild[y][x]/=what;
00265       } 
00266     return *this;       
00267   }     
00268    
00271   template < int s_x, int s_y, typename T >
00272   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator *= (const T& what)
00273   {
00274     MAP((*this)) {
00275         bild[y][x]*=what;
00276       } 
00277     return *this;       
00278   }
00279 
00282   template < int s_x, int s_y, typename T >
00283   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator -= (const T& what)
00284   {
00285     MAP((*this)) {
00286         bild[y][x]-=what;
00287       } 
00288     return *this;       
00289   }     
00290 
00291 
00294   template < int s_x, int s_y, typename T >
00295   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator += (const imgbase<s_x, s_y, T>& what)
00296   {
00297      MAP(what) {
00298         T val=what(y,x);
00299         bild[y][x]+=val;
00300       } 
00301     return *this;       
00302   }     
00303  
00306   template < int s_x, int s_y, typename T >
00307   imgbase<s_x, s_y, T>& imgbase<s_x, s_y, T>::operator += (const T& what)
00308   {
00309      MAP((*this)) {
00310         bild[y][x]+=what;
00311       } 
00312     return *this;       
00313   }     
00314 
00315   
00330   template < int s_x, int s_y, typename T >
00331   T average(const imgbase<s_x, s_y, T> &img) {
00332      T temp=0;
00333      for (int y=0; y< s_y; y++)
00334        for (int x=0; x< s_x; x++)
00335          temp += img(y,x);
00336      return temp/(s_x*s_y);      
00337   }   
00338     
00339 
00341   typedef imgbase<512,512,unsigned short> bild16_base;
00342   
00343   class bildfloat; // forward declaration
00344                    // because of dependencies 
00345   
00347 
00353   class bild16 : public bild16_base {
00354     static const std::streamoff HIS_START;  // 0-100 header des His-files
00355   public:
00357     static const data_t intensity_max;
00359     static const data_t intensity_min;
00360 
00362   #pragma pack(push,1)          // stellt sicher, dass structur groesse auf 1 byte genau bestimmt wird
00363     typedef struct {
00364       unsigned short FileID;    //1
00365       unsigned short HeaderSize;
00366       unsigned short HeaderVersion;
00367       unsigned long FileSize;
00368       unsigned short ImageHeaderSize;   //5
00369       unsigned short ULX;
00370       unsigned short ULY;
00371       unsigned short BRX;
00372       unsigned short BRY;
00373       unsigned short NrOfFrames;        //10
00374       unsigned short Correction;
00375       double IntegrationTime;
00376       unsigned short TypeOfNumbers;     //13
00377     }  header_t;
00378   
00379   #pragma pack(pop) // stellt alten Wert wieder her
00380       
00381       bild16(const char *fname=NULL) THROWSPEC;
00382       bild16(unsigned short *data) THROWSPEC;
00383       ~bild16();
00384       header_t* file_header;
00386       void write_pgm16 (const char *name) const;
00388       void write_pgm8 (const char *name) const;
00390       void write_pgm8_bounds (const char *name, bild16::data_t low, bild16::data_t high) const;
00392       bild16& read_his (const char *name) THROWSPEC;
00394       void write_his (const char *name) const;
00396       bild16& read_pgm(const char *name) THROWSPEC;
00398       bild16& og_correct(const bild16& offset, const bild16& gain);
00400       bild16& drawx(int x, int y1, int y2) THROWSPEC;
00402       bild16& drawy(int y, int x1, int x2) THROWSPEC;
00404       bild16& kreuz(int x, int y) THROWSPEC;
00406       void fromfloat(const bildfloat &bf, float max=1.0);
00408       bild16& operator = (const bild16& b) {
00409         bild16_base::operator = (b);
00410         *file_header=*(b.file_header);
00411         return *this;
00412       } 
00413   };
00414 
00416 
00429    class rawfloat {
00430    public: 
00431      rawfloat (const float& f): f_ (f) {}
00432    private:
00433      static float dummy;
00434      const float& f_;
00435      friend std::ostream& operator << (std::ostream& os, const rawfloat& r) {
00436        
00437        return os.write (reinterpret_cast <const char *>(&(r.f_)), sizeof (r.f_));
00438      }
00439   };
00440   
00442 
00458   class irawfloat {
00459    public: 
00460      irawfloat (float& f) : f_(f) {}
00461    private:
00462      float& f_;
00463      
00464      friend std::istream& operator >> (std::istream& is, const irawfloat& r) { 
00465        return is.read(reinterpret_cast<char *>(&(r.f_)), sizeof(r.f_)); 
00466      }
00467   };
00468   
00470 
00488   class eichkurve {
00489     public:
00490       eichkurve();
00491       virtual ~eichkurve();
00493       double operator() (bild16::data_t val) const;
00495       virtual double eichfun(double x) const=0;
00497       virtual double deichfun_dx(double x) const=0;
00499 
00502       virtual double initguess(bild16::data_t val) const=0;
00504       void table_write(const char *name) const;
00505     protected:
00506       static const char magic[];
00507       double *lookup;
00508       double fsolve(bild16::data_t val, double hmin, double hmax) const;
00509       void   table_init(double hmin, double hmax);
00510       // Newton-Raphson-Verfahren
00511   };
00512   
00530   inline double eichkurve::operator() (bild16::data_t val) const 
00531   {
00532     return lookup[val];
00533   }
00534   
00536 
00543   class expkurve : public eichkurve {
00544     public:
00545       expkurve (double sA, double sg1, double sg2, double sg3,
00546                 // Abschwächungskoeffizienten
00547                 double sf1, double sf2
00548                 // Mischparameter
00549               );
00550       double eichfun(double x) const;
00551       double deichfun_dx(double x) const;
00552       double initguess(bild16::data_t val) const;
00553               
00554     private:
00555       double A, g1, g2, g3, f1, f2;
00556   };
00557 
00558 
00560 
00568   class exp4kurve : public eichkurve {
00569     public:
00570       exp4kurve (double sA, double sa1, double sa2, double sa3,
00571                 // rel. Anteile
00572                 double sb1, double sb2, double sb3, double sb4
00573                 // charakteristische Tiefen
00574               );
00575       double eichfun(double x) const;
00576       double deichfun_dx(double x) const;
00577       double initguess(bild16::data_t val) const;
00578               
00579     private:
00580       double A, a1, a2, a3, b1, b2, b3, b4;
00581   };
00582 
00583   
00585 
00609   class tablekurve : public eichkurve {
00610     public:
00611       tablekurve (const char *fname) THROWSPEC;
00612       double eichfun(double x) const;
00613       double deichfun_dx(double x) const;
00614       double initguess(bild16::data_t val) const;
00615   };
00616 
00618 
00636   class flatkurve : public eichkurve {
00637     public:
00638       flatkurve (bool normalize_=true);
00639       virtual double eichfun(double x) const;
00640       virtual double deichfun_dx(double x) const;
00641       virtual double initguess(bild16::data_t val) const;
00642     private:
00643       bool normalize;
00644   };
00645 
00646 
00648   typedef imgbase<512,512,bool> region_base;
00650 
00654   typedef region_base region_t; //später vielleicht abgeleitet
00655 
00656   class QRfit;
00657   
00659   typedef imgbase<512, 512, float> bildfloat_base;
00660 
00662 
00667   class bildfloat : public bildfloat_base {
00668     public:
00670       bildfloat();
00672       bildfloat(const bild16& aufnahme, const eichkurve& ek);
00674       bildfloat(const bild16& aufnahme);
00676       bildfloat(const region_t& regio);
00678       bildfloat(const char* name);
00679       ~bildfloat();
00681       static const float pix_size;
00683       void write_gnuplot (const char *name) const;
00685       bildfloat& read_gnuplot (const char *name) THROWSPEC;
00686       
00688       bildfloat& from_bild16(const bild16& aufnahme, const eichkurve& ek);
00690       bildfloat& from_bild16(const bild16& aufnahme);
00692       bildfloat& apply_eichkurve(const eichkurve& ek);
00694       bildfloat& convolve (const float * kernel, int sx, int sy, bool normalize=true) const THROWSPEC;
00696       bildfloat& gaussian(float radius); //Glätten durch Faltung mit einer Gaußglocke
00698       void shutter_detect(int  &y0, int &y1, float thresh, int radius) const;
00700       bildfloat& shutter_correct(int y0, int y1, float shadefactor);
00702       bildfloat& gamma_correct(const bildfloat& gammabild);
00704       bildfloat& bquad_correct(const bildfloat& bquadbild);
00706       bildfloat& polyfit_correct(const QRfit& korrektor);
00708       bildfloat& badpix_correct (const bild16& bpmap, bild16::data_t threshold=bild16::intensity_max/2);
00710       bildfloat& mask(const region_t& reg); // set all points not in reg to NaN
00711   };    
00712   
00715   inline bildfloat::bildfloat() : bildfloat_base() { }
00716   
00718   inline bildfloat::bildfloat(const char *name) : bildfloat_base() 
00719   { 
00720     read_gnuplot(name);
00721   }
00722   
00725   inline bildfloat::bildfloat(const bild16& aufnahme, const eichkurve& ek) : bildfloat_base() 
00726   { 
00727     from_bild16(aufnahme, ek); 
00728   }
00729   
00732   inline bildfloat::bildfloat(const bild16& aufnahme) : bildfloat_base() 
00733   { 
00734     from_bild16(aufnahme); 
00735   }
00736   
00737 
00738   inline bildfloat::~bildfloat()  { }
00739 
00740   typedef std::valarray<float> lut;
00741   typedef imgbase<512, 512, lut> interpol_base;
00742   
00744 
00746   class interpol : public interpol_base {
00747    public: 
00748     interpol(bild16 * refbilder, float* refw, int nrefimg);
00749     interpol(const char *fname);
00750     void write(const char *fname);
00751     void read (const char *fname) throw (const char*);
00752     float operator() (int y, int x, float val);
00753     const lut& operator() (int y, int x) const { return interpol_base::operator()(y,x); }
00754     
00755    private:
00756     static const char magic[];
00757     int nref;
00758     lut refwerte;
00759     lut& operator() (int y, int x) { return interpol_base::operator() (y,x); }
00760   };
00761   
00763 
00773 class QRfit : public interpol_base {
00774  public:
00776   QRfit(bild16 *refbilder, float *refw, int nrefimg, int order_=4);
00778   QRfit(const char *fname);
00779   ~QRfit();
00781   void write(const char *fname) const;
00783   void read (const char *fname) THROWSPEC;
00784 
00786   float operator() (int y, int x, float val) const;
00788   const lut& operator() (int y, int x) const { return interpol_base::operator()(y,x); }
00790   float get_coeff(int x, int y, int n) const;
00791  private:
00792   int nref, order;
00793   lut refwerte;
00794   lut& operator() (int y, int x) { return interpol_base::operator() (y,x); }
00795 
00797   void polyfit(double *bildwerte);
00798   double **R;
00799   double *d, *b, *koeff;
00800   static const char magic[];
00801 };
00802 
00803  
00804 #endif

Generated on Fri Jul 24 12:49:17 2009 for Xgrayimg Library by  doxygen 1.5.5