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
00012
00013
00014
00015
00016 class Parabelzentrum {
00017
00018
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
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
00068 template <typename TBild, typename TFunctor, typename TBorder>
00069 void execute_hubbel (const TBild &hubbelbild, region_t ®ion, 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
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
00095 if (region(y,x)) return true;
00096
00097 if (hub(y,x)<threshold) return true;
00098
00099 return false;
00100 }
00101 };
00102
00103 struct maxborder {
00104
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
00111 if (region(y,x)) return true;
00112
00113 if (hub(y,x)>threshold) return true;
00114
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
00123 if (region(y,x)) return true;
00124
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 ®ion, 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("");
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
00256 return x*v2.x+y*v2.y;
00257 }
00258
00259 vec2d operator * (double s) {
00260
00261 return vec2d(x*s, y*s);
00262 }
00263
00264 vec2d operator / (double s) {
00265
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
00279
00280
00281
00282 vec2d r=P2-P1;
00283
00284
00285 int stepend, stepinc;
00286
00287
00288
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
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
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