00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef POL_LOCATOR_GEN_H
00012 #define POL_LOCATOR_GEN_H
00013
00014 #include <boost/numeric/ublas/vector.hpp>
00015 #include <cmath>
00016 #include <cstdarg>
00017 #include "pol_match.h"
00018
00019
00020 #define DISTANCE_ERROR 5
00021 #define ANGLE_ERROR 10.0 * 0.0174533
00022 namespace mimas {
00023 class poss_centroid
00024 {
00025 public:
00026 typedef boost::numeric::ublas::vector< double > Vector;
00027 Vector posn;
00028 double posn_weight;
00029 angle ang;
00030 double angle_weight;
00031
00032 double entry_weight;
00033
00034 static double* posn_gauss;
00035 static double* angle_gauss;
00036 static int posn_gauss_size;
00037 static int angle_gauss_size;
00038
00039 poss_centroid()
00040 {
00041 posn_weight = angle_weight = 1.0;
00042 entry_weight=0.0;
00043 }
00044
00045 double consistent( poss_centroid *other )
00046 {
00047
00048
00049
00050
00051
00052 double dist;
00053
00054 dist = norm_2(other->posn - posn);
00055 if (dist>DISTANCE_ERROR)
00056 return 0;
00057
00058
00059
00060
00061 angle adiff;
00062 adiff = other->ang - ang;
00063 if (adiff> ANGLE_ERROR | adiff< -ANGLE_ERROR)
00064 return 0;
00065
00066
00067
00068 double weight=0,w1,w2;
00069
00070 getWeights( other, &w1, &w2 );
00071 weight = w1*w2;
00072 std::cout << "weight=" << weight<< std::endl;
00073 return weight;
00074 }
00075
00076 void getWeights( poss_centroid *other, double *w1, double *w2 )
00077 {
00078
00079 double posn_diff;
00080 int ipd;
00081
00082 posn_diff = norm_2(posn - other->posn);
00083 ipd = (int)posn_diff;
00084 if (ipd< posn_gauss_size)
00085 *w1 = posn_gauss[ipd];
00086
00087 else
00088 *w1 = 0;
00089
00090 double angle_diff;
00091 int iad;
00092
00093 angle_diff = (double)(ang - other->ang);
00094 if (angle_diff<0) angle_diff=-angle_diff;
00095 iad = (int)angle_diff;
00096 if (iad< angle_gauss_size)
00097 *w2 = angle_gauss[iad];
00098
00099 else
00100 *w2 = 0;
00101
00102 std::cout << "ipd=" << ipd << " and iad=" << iad << std::endl;
00103 std::cout << "angle_gauss=" << angle_gauss[iad] << std::endl;
00104 std::cout << "dist_gauss=" << posn_gauss[ipd] << std::endl;
00105
00106
00107 }
00108
00109 void update( poss_centroid *other )
00110 {
00111
00112
00113
00114
00115 double w1,w2;
00116 std::cout << "Update" << std::endl;
00117 getWeights( other, &w1, &w2 );
00118 w1*=other->entry_weight;
00119 w2*=other->entry_weight;
00120
00121
00122
00123 posn = (posn * posn_weight) + (other->posn*w1);
00124 posn_weight+=w1;
00125 posn= posn/ posn_weight;
00126
00127 ang= (ang * angle_weight) + (other->ang*w2);
00128 angle_weight+= w2;
00129 ang= ang / angle_weight;
00130
00131
00132
00133 entry_weight= posn_weight* angle_weight;
00134 }
00135 };
00136
00137 typedef std::list< poss_centroid * > poss_centroid_list;
00138
00139 class pol_locator_gen : public pol_locator
00140 {
00141 public:
00142 typedef boost::numeric::ublas::vector< double > Vector;
00143 private:
00144 double threshold;
00145
00146 poss_centroid_list list_poss_centroids;
00147
00148 poss_centroid_list list_poss_matches;
00149
00150 double *posn_gauss,*angle_gauss;
00151 int posn_gauss_size, angle_gauss_size;
00152
00153 int calcGaussBoxSize( double sigma, double accuracy )
00154 {
00155
00156 double n;
00157
00158 sigma = 2.0 * sigma * sigma;
00159
00160 for(n=1.0; ;n+=1.0)
00161 {
00162 if (exp( -n*n/sigma )< accuracy) break;
00163 }
00164
00165 return (int) n;
00166 }
00167
00168 public:
00169
00170
00171 pol_locator_gen()
00172 {
00173 posn_gauss=angle_gauss=0;
00174 posn_gauss_size=angle_gauss_size=0;
00175 threshold=0;
00176 }
00177 pol_locator_gen(double t)
00178 {
00179 posn_gauss=angle_gauss=0;
00180 posn_gauss_size=angle_gauss_size=0;
00181 threshold=t;
00182 }
00183 ~pol_locator_gen()
00184 {
00185 if (posn_gauss) delete[] posn_gauss;
00186 if (angle_gauss) delete[] angle_gauss;
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 }
00202
00203 virtual void init( int numdims, ...)
00204 {
00205
00206
00207
00208
00209 va_list vlist;
00210
00211 if (numdims!=2)
00212 return;
00213
00214
00215
00216 va_start(vlist, numdims);
00217
00218 double s,p;
00219 s=va_arg(vlist, double);
00220 p=va_arg(vlist, double);
00221
00222 if (posn_gauss) delete posn_gauss;
00223
00224 s = 2*s*s;
00225 int size = calcGaussBoxSize( s,p );
00226 int i;
00227
00228 posn_gauss=new double[size];
00229 posn_gauss_size=size;
00230
00231
00232 for(i=0;i<size;++i)
00233 {
00234 double d = (double)i*(double)i;
00235 double w = exp( -d/s );
00236
00237 posn_gauss[i]=w;
00238 }
00239
00240
00241 s=va_arg(vlist, double);
00242 p=va_arg(vlist, double);
00243
00244 if (angle_gauss) delete angle_gauss;
00245
00246 s = 2*s*s;
00247 size = calcGaussBoxSize( s,p );
00248
00249 angle_gauss=new double[size];
00250 angle_gauss_size=size;
00251
00252
00253 for(i=0;i<size;++i)
00254 {
00255 double d = (double)i*(double)i;
00256 double w = exp( -d/s );
00257
00258 angle_gauss[i]=w;
00259 }
00260
00261
00262 poss_centroid::posn_gauss= posn_gauss;
00263 poss_centroid::angle_gauss=angle_gauss;
00264 poss_centroid::angle_gauss_size=angle_gauss_size;
00265 poss_centroid::posn_gauss_size=posn_gauss_size;
00266
00267 va_end(vlist);
00268 }
00269
00270 virtual void addEntry( double weight, ... )
00271 {
00272
00273 va_list vlist;
00274 va_start(vlist,weight);
00275
00276 Vector posn( 2 );
00277 posn( 0 ) = va_arg( vlist, double );
00278 posn( 1 ) = va_arg( vlist, double );
00279 double angle= va_arg( vlist, double );
00280
00281
00282
00283 poss_centroid *pc = new poss_centroid;
00284 pc->posn=posn;
00285 pc->ang=angle;
00286 pc->entry_weight=weight;
00287 list_poss_centroids.push_back(pc);
00288
00289 va_end(vlist);
00290 }
00291
00292 virtual pol_match_ptr_list getMatches()
00293 {
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 poss_centroid_list::iterator i_pc, i_pm;
00310 std::cout<<"hello1"<< std::endl;
00311
00312 for(i_pc=list_poss_centroids.begin(); i_pc!=list_poss_centroids.end();++i_pc)
00313 {
00314 poss_centroid* pc=(*i_pc);
00315
00316 if (!pc) continue;
00317
00318
00319
00320
00321 poss_centroid *best_match=0;
00322 double best_score=0;
00323 for(i_pm=list_poss_matches.begin(); i_pm!=list_poss_matches.end();++i_pm)
00324 {
00325 double score;
00326 poss_centroid *match=(*i_pm);
00327 if (!match) continue;
00328
00329 score = pc->consistent( match );
00330
00331
00332
00333 if (score>0)
00334 {
00335 best_score=score;
00336 best_match=match;
00337 break;
00338 }
00339 }
00340
00341
00342 if (best_match)
00343 {
00344 best_match->update( pc );
00345 }
00346 else
00347 {
00348
00349
00350 list_poss_matches.push_back( pc );
00351 }
00352 }
00353 std::cout<<"hello2"<<std::endl;
00354
00355
00356 pol_match_ptr_list retval;
00357 double max=0;
00358 for(i_pc=list_poss_matches.begin();
00359 i_pc!=list_poss_matches.end(); ++i_pc)
00360 {
00361 poss_centroid *match= (*i_pc);
00362
00363 std::cout << "Found a possible entry, weight(" << threshold << ")= " << match->entry_weight<< std::endl;
00364 if (match->entry_weight> max)
00365 max = match->entry_weight;
00366 if (match->entry_weight > 5000)
00367 {
00368 pol_match_ptr m( new pol_match );
00369
00370 m->model_found = NULL;
00371 m->pos = match->posn;
00372 m->orient=match->ang;
00373 m->strength=match->entry_weight;
00374 retval.push_back(m);
00375 }
00376 }
00377 std::cout<<"hello3"<<std::endl;
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 std::cout<<"hello4"<<std::endl;
00394 std::cout << "Max val = " << max << std::endl;
00395
00396 return retval;
00397 }
00398 };
00399
00400
00401
00402 double* poss_centroid::angle_gauss = NULL;
00403 double* poss_centroid::posn_gauss = NULL;
00404 int poss_centroid::angle_gauss_size = 0;
00405 int poss_centroid::posn_gauss_size = 0;
00406 }
00407 #endif
00408