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
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
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
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
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;
00344
00345
00347
00353 class bild16 : public bild16_base {
00354 static const std::streamoff HIS_START;
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;
00365 unsigned short HeaderSize;
00366 unsigned short HeaderVersion;
00367 unsigned long FileSize;
00368 unsigned short ImageHeaderSize;
00369 unsigned short ULX;
00370 unsigned short ULY;
00371 unsigned short BRX;
00372 unsigned short BRY;
00373 unsigned short NrOfFrames;
00374 unsigned short Correction;
00375 double IntegrationTime;
00376 unsigned short TypeOfNumbers;
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
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
00547 double sf1, double sf2
00548
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
00572 double sb1, double sb2, double sb3, double sb4
00573
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;
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);
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);
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