stdalgorithm.hpp

Go to the documentation of this file.
00001 #ifndef STDALGORITHM_HPP
00002 #define STDALGORITHM_HPP
00003 
00004 #include "imgclass.hpp"
00005 #include "kube-gustavson-fft.hpp"
00006 #include "matrixutil.hpp"
00007 #include "minmaxheap.hpp"
00008 #include <vector>
00009 #include <cmath>
00010 
00011 /* contains algorithms not in imgclass, but very useful.
00012    I don't think it is adviseable to have functions that 
00013    merely operate on a const bildfloat as member functions in bildfloat,
00014    like for example out-place FFT or searching for extrema */
00015 
00016 class Parabelzentrum {
00017   // Funktor, der die Mitte einer Punktmenge=Oberfläche über
00018   // den Parabelfit bestimmt
00019   const bildfloat& bild;
00020   int pktzahl;
00021   int pktmax;
00022   double **R;
00023   double *f;
00024   
00025   static const int order; 
00026   double x_cent, y_cent;
00027   double x_estimate, y_estimate;
00028   double s_xcent, s_ycent;
00029   minheap <double> xmax, ymax;
00030   maxheap <double> xmin, ymin;
00031 public:
00032   double *koeff;
00033   double *errors;
00034   double *rel_errors;
00035   Parabelzentrum(const bildfloat& bild_, int pktmax_);
00036   ~Parabelzentrum();
00037   void estimate(double x, double y);
00038   void operator() (int x, int y);
00039   void clear();
00040   bool fit();
00041   double x();
00042   double y();
00043   double height();
00044 
00045   // statistische Fehler
00046   double s_x() {return s_xcent; }
00047   double s_y() { return s_ycent; }
00048   double s_height();
00049 };
00050 
00051 inline double Parabelzentrum::x() { return x_cent+x_estimate; }
00052 
00053 inline double Parabelzentrum::y() { return y_cent+y_estimate; }
00054 
00055 inline double Parabelzentrum::height() { 
00056   return koeff[0]-SQR(koeff[1])/(4*koeff[3])-SQR(koeff[2])/(4*koeff[4]); 
00057 }
00058 
00059 inline double Parabelzentrum::s_height() {
00060   double errsum=SQR(errors[0]);
00061   errsum+=SQR(SQR(koeff[1])/(4*koeff[3]))*(2*SQR(rel_errors[1])+SQR(rel_errors[3]));
00062   errsum+=SQR(SQR(koeff[2])/(4*koeff[4]))*(2*SQR(rel_errors[2])+SQR(rel_errors[4]));
00063   return sqrt(errsum);
00064 }  
00065   
00066 
00067 /* call the functor for every point filled */
00068 template <typename TBild, typename TFunctor, typename TBorder>
00069 void execute_hubbel (const TBild &hubbelbild, region_t &region, int x, int y, const TBorder &border, TFunctor &fun) {
00070   
00071   if (region(y,x)) return;
00072   int xmin=x; int xmax=x;
00073   while (!border(hubbelbild, region, xmin-1, y)) xmin--;
00074   while (!border(hubbelbild, region, xmax+1, y)) xmax++;
00075   for (int x=xmin; x<=xmax; x++) {
00076     region(y,x)=true;
00077     fun(x,y);
00078   }  
00079   
00080   
00081   for (int x=xmin; x<=xmax; x++) {
00082     if (!border(hubbelbild, region, x,y-1)) execute_hubbel(hubbelbild, region, x,y-1, border, fun);
00083     if (!border(hubbelbild, region, x,y+1)) execute_hubbel(hubbelbild, region, x,y+1, border, fun);
00084   }
00085 }  
00086 
00087 struct minborder {
00088   // minimum height for inner region
00089   float threshold;
00090   minborder (float thresh) : threshold(thresh) {}
00091   
00092   bool operator ()  (const bildfloat& hub, const region_t& region, int x, int y) const {
00093     if ((x<1) || (y<1) || (x>=region.SIZEX-1) || (y>=region.SIZEY-1)) return true;
00094     // point outside the field or near border
00095     if (region(y,x)) return true;
00096     // already filled
00097     if (hub(y,x)<threshold) return true;
00098     // smaller than minimum height
00099     return false;
00100   }  
00101 };  
00102 
00103 struct maxborder {
00104   // maximum height for inner region
00105   float threshold;
00106   maxborder (float thresh) : threshold(thresh) {}
00107   
00108   bool operator ()  (const bildfloat& hub, const region_t& region, int x, int y) const {
00109     if ((x<1) || (y<1) || (x>=region.SIZEX-1) || (y>=region.SIZEY-1)) return true;
00110     // point outside the field or near border
00111     if (region(y,x)) return true;
00112     // already filled
00113     if (hub(y,x)>threshold) return true;
00114     // greater than maximum height
00115     return false;
00116   }  
00117 }; 
00118 
00119 struct valleyborder {
00120   bool operator () (const bildfloat& hub, const region_t& region, int x, int y) const {
00121     if ((x<1) || (y<1) || (x>=region.SIZEX-1) || (y>=region.SIZEY-1)) return true;
00122     // point outside the field or near border
00123     if (region(y,x)) return true;
00124     // already filled
00125   #define LOCALMIN(y1,x1,y2,x2) if ((hub(y,x)<=hub(y1,x1)) && (hub(y,x) <= hub(y2,x2))) return true 
00126     LOCALMIN(y,x-1, y,x+1);
00127     LOCALMIN(y+1,x,y-1,x); 
00128     LOCALMIN(y+1,x+1, y-1,x-1);
00129     LOCALMIN(y-1,x+1, y+1, x-1);
00130     return false;
00131   }  
00132 };
00133 
00134 template <typename TFunctor>
00135 void execute_region (const region_t &region, TFunctor &fun) {
00136   MAP(region)
00137     if (region(y,x)) fun(x,y);
00138 }
00139 
00140 
00141 struct countfunc {
00142   int sum;
00143   countfunc() : sum(0) {}
00144   void operator () (int x, int y) {sum++; }
00145   int operator() () const {return sum; }
00146 };  
00147 
00148 struct hydrosum {
00149   bildfloat &heightfield;
00150   float sum;
00151   hydrosum(bildfloat& rb) : heightfield(rb), sum(0.0) {}
00152   void operator () (int x, int y) { sum+= SQR(heightfield(y,x)); }
00153   float operator() () const {return sum; }
00154 };  
00155 
00156 struct azimuth_average {
00157   int anz;
00158   std::vector<double> rsumme;
00159   std::vector<int> ranzahl;
00160   bildfloat &heightfield;
00161   float x_centr, y_centr;
00162   
00163   azimuth_average(bildfloat& rb, float x_centr_, float y_centr_, int anz_) : 
00164     anz(anz_), rsumme(anz_), ranzahl(anz_), heightfield(rb), x_centr(x_centr_), y_centr(y_centr_) 
00165   {
00166          for (int i=0; i<anz; i++) {
00167            ranzahl[i]=0;
00168            rsumme[i]=0.0;
00169          }  
00170    }
00171     
00172   void operator () (int x, int y)
00173   { 
00174      int dist=static_cast<int>(sqrt(SQR(x-x_centr)+SQR(y-y_centr)));
00175      if (dist<anz) {
00176        ranzahl[dist]++;
00177        rsumme[dist]+=heightfield(y,x);
00178      }  
00179   }
00180   float operator() (int dist) const {
00181     if ((dist<anz) && (ranzahl[dist]!=0)) return rsumme[dist]/ranzahl[dist];
00182     return nanf(""); // falls die Entfernung nicht aufgetaucht ist
00183   }
00184 }; 
00185 
00186 
00187 template <typename T>
00188 struct minmaxpos {
00189   T val;
00190   int x, y;
00191   minmaxpos(const T& v, int x_, int y_) : val(v), x(x_), y(y_) {}
00192   minmaxpos() : val (0), x(0), y(0) {}
00193   bool operator > (const minmaxpos& v2) const { return val > v2.val; }
00194   bool operator < (const minmaxpos& v2) const { return val < v2.val; }
00195 };
00196 
00197 template <typename T>
00198 struct getmax : public minheap< minmaxpos <T> > {
00199   const bildfloat& rb;
00200   getmax(const bildfloat& bfl, int n=1) : minheap< minmaxpos <T> > (n), rb(bfl) {}
00201   void  operator () (int x, int y) { put(minmaxpos<T>(rb(y,x),x,y)); }
00202   const minmaxpos<T>  operator () () const { return minheap < minmaxpos <T> >::operator() (); }
00203 };
00204 
00205 template <typename T>
00206 struct getmin : public maxheap< minmaxpos <T> > {
00207   const bildfloat& rb;
00208   getmin(const bildfloat& bfl, int n=1) : maxheap< minmaxpos <T> > (n), rb(bfl) {}
00209   void  operator () (int x, int y) { put(minmaxpos<T>(rb(y,x),x,y)); }
00210   const minmaxpos<T>  operator () () const { return maxheap < minmaxpos <T> >::operator() (); }
00211 };
00212 
00213 
00214 typedef imgbase<512, 512, COMPLEX> bildcomplex_base;
00215 
00216 class bildcomplex : public bildcomplex_base {
00217 public:
00218   bildcomplex() : bildcomplex_base() { }
00219   bildcomplex(const bildfloat &realvalue);
00220   bildcomplex(const bildfloat& real, const bildfloat& imag);
00221   void decompose(bildfloat& real, bildfloat& imag);
00222   
00223   bildcomplex& FFT_forward();
00224   bildcomplex& FFT_backward();
00225   bildcomplex& Hamming_window(float width=220, float xm=256, float ym=256);
00226   bildcomplex& Hamming_unwindow(float width=220, float xm=256, float ym=256);
00227 
00228 
00229   bildfloat& norm(bildfloat& ret);
00230 };  
00231 
00232 typedef std::pair<float, float> Point;
00233 
00234 typedef std::vector<Point> cell;
00235 
00236 struct vec2d {
00237   double x, y;
00238 
00239   vec2d(double x_, double y_): x(x_), y(y_) {}
00240   vec2d operator - (const vec2d & subtr) const {
00241     return vec2d(x-subtr.x, y-subtr.y);
00242   }
00243 
00244   vec2d operator + (const vec2d & summand) {
00245     return vec2d(x+summand.x, y+summand.y);
00246   }
00247 
00248   vec2d& operator /= (double div) {
00249     x/=div;
00250     y/=div;
00251     return *this;
00252   }
00253 
00254   double operator * (const vec2d& v2) {
00255     // dot product
00256     return x*v2.x+y*v2.y;
00257   }
00258 
00259   vec2d operator * (double s) {
00260     // S-Multiplikation
00261     return vec2d(x*s, y*s);
00262   }
00263   
00264   vec2d operator / (double s) {
00265     // S-Multiplikation
00266     return vec2d(x/s, y/s);
00267   }  
00268 };
00269 
00270 inline double abs(const vec2d& v) {
00271   return sqrt(v.x*v.x+v.y*v.y);
00272 }  
00273 
00274 
00275 template <typename TFunctor>
00276 void line_iterate(const vec2d& P1, const vec2d& P2, TFunctor& fun) 
00277 {
00278   // call a functor for each point on a straight line between P1 and P2
00279   // could be optimized by Bresenham algorithm
00280   // however, premature optimization is the root of all evil
00281   
00282   vec2d r=P2-P1;
00283   // r ist Richtungsvektor der Geraden
00284   
00285   int stepend, stepinc;
00286   
00287   // r ist Richtungsvektor der gesuchten Geraden
00288   //cerr<<"Richtungsvektor "<<r.x<<", "<<r.y<<endl;
00289   if (abs(r.x) >abs(r.y)) {
00290      stepend=abs(r.x);
00291      r/=abs(r.x);
00292   } else {
00293      stepend=abs(r.y);
00294      r/=abs(r.y);
00295   }
00296 
00297   // Normierung, so dass immer ein Schritt entlang x oder y gemacht wird 
00298 
00299   for (int step=0; step<=stepend; step++) {
00300     fun(floor(r.x*step+P1.x+0.5), floor(r.y*step+P1.y+0.5));
00301   }  
00302 }
00303 
00304 struct mean_avg {
00305   const bildfloat& rb;
00306   double sum;
00307   double sqrsum;
00308   int pktzahl;
00309   mean_avg(const bildfloat& bild) : rb(bild), sum(0.0), sqrsum(0.0), pktzahl(0) {}
00310   void operator () (int x, int y) {
00311     // cerr<<".bild.display create rectangle "<<x<<" "<<y<<" "<<x<<" "<<y<<" -fill green -outline green -tag bound"<<endl;
00312     sum+=rb(y,x);
00313     sqrsum+=SQR(rb(y,x));
00314     pktzahl++;
00315   }
00316 };  
00317 
00318 struct surface {
00319   double surf;
00320   const bildfloat& rb;
00321   surface(const bildfloat& rb_) : surf(0.0), rb(rb_) {}
00322   void operator () (int x, int y) {
00323     double dx=(rb(y,   x+1)-rb(y,x-1))/(2*rb.pix_size);
00324     double dy=(rb(y+1, x) - rb(y-1, x))/(2*rb.pix_size);
00325     surf+=sqrt(1.0+SQR(dx)+SQR(dy));
00326   }  
00327   double operator() () { return surf; }
00328 };
00329 
00330 
00331 bool pnpoly(int npol, float *xp, float *yp, float x, float y);
00332 
00333 class Voronoischnitt {
00334    const bildfloat& rb;
00335    float xmitte, ymitte;
00336    cell zelle;
00337    float *xp, *yp;
00338    int npol;
00339    vec2d r;
00340  public:
00341    Voronoischnitt(bildfloat &bfl, float xmitte_, float ymitte_, const char *vorofile);
00342    ~Voronoischnitt();
00343    void compute_schnitt(int nr);
00344    float boundary_average();
00345    double stddev;
00346    bool contains(float x, float y);
00347    vec2d direction();
00348    float mindist, maxdist;
00349 };
00350 
00351 
00352 #endif

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