Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vifa_parallel.cxx

Go to the documentation of this file.
00001 // This is gel/vifa/vifa_parallel.cxx
00002 #include <vnl/vnl_math.h>
00003 #include <vdgl/vdgl_digital_curve.h>
00004 #include <vsol/vsol_curve_2d.h>
00005 #include <vtol/vtol_edge_2d.h>
00006 #include <vtol/vtol_vertex_2d.h>
00007 #include <vtol/vtol_intensity_face.h>
00008 #include <vifa/vifa_gaussian.h>
00009 #include <vifa/vifa_parallel.h>
00010 
00011 #ifdef DUMP
00012 #include <vul/vul_sprintf.h>
00013 #include <vcl_fstream.h>
00014 
00015 static int pass = 0;
00016 #endif
00017 
00018 const float n_sigma = 2.0;  // on either side of center
00019 
00020 
00021 vifa_parallel::
00022 vifa_parallel(iface_list&   faces,
00023               bool          contrast_weighted,
00024               vifa_parallel_params*  params) :
00025   vifa_parallel_params(params)
00026 {
00027   raw_h_ = new vifa_histogram(nbuckets, min_angle, max_angle);
00028   float  range = max_angle - min_angle;
00029 
00030   for (iface_iterator ifi = faces.begin(); ifi != faces.end(); ++ifi)
00031   {
00032     edge_list edges; (*ifi)->edges(edges);
00033 
00034     for (edge_iterator ei = edges.begin(); ei != edges.end(); ei++)
00035     {
00036       vtol_edge_2d* e = (*ei)->cast_to_edge_2d();
00037 
00038       if (e)
00039       {
00040 #ifdef OLD_LINE_APPROX
00041         const vtol_vertex_2d*  v1 = e->v1()->cast_to_vertex_2d();
00042         const vtol_vertex_2d*  v2 = e->v2()->cast_to_vertex_2d();
00043         double dy = v1->y() - v2->y();
00044         double dx = v1->x() - v2->x();
00045         double length = 0.0;
00046 
00047         if (contrast_weighted)
00048         {
00049           vtol_intensity_face_sptr other_f = get_adjacent_iface(*ifi, e);
00050 
00051           if (other_f)
00052             length = vcl_sqrt((dx * dx) + (dy * dy))
00053                    * vcl_fabs((*ifi)->Io() - other_f->Io());
00054         }
00055 
00056         double  orientation = vcl_atan2(dy, dx) * 180.0 / vnl_math::pi;
00057         if (orientation < 0)
00058           orientation += 180.0;
00059 
00060         float  theta = map_x(float(orientation));
00061         raw_h_->SetCount(theta, raw_h_->GetCount(theta) + float(length));
00062 #else
00063         vsol_curve_2d_sptr  c = e->curve();
00064 
00065         if (c)
00066         {
00067           vdgl_digital_curve*  dc = c->cast_to_vdgl_digital_curve();
00068 
00069           if (dc)
00070           {
00071             double l = dc->length();
00072 
00073             for (int i = 0; i < l; i++)
00074             {
00075               // Use parametric index representation (0 -- 1)
00076               double theta = dc->get_theta(i / l);
00077 #ifdef DEBUG
00078               vcl_cout << "raw theta: " << theta;
00079 #endif
00080               while (theta < min_angle)
00081                 theta += range;
00082 
00083               while (theta > max_angle)
00084                 theta -= range;
00085 #ifdef DEBUG
00086               vcl_cout << " to " << theta << vcl_endl;
00087 #endif
00088               raw_h_->UpCount(float(theta));
00089             }
00090           }
00091         }
00092 #endif  // OLD_LINE_APPROX
00093       }
00094     }
00095   }
00096 
00097   norm_h_ = vifa_parallel::normalize_histogram(raw_h_);
00098 }
00099 
00100 
00101 vifa_parallel::
00102 vifa_parallel(vcl_vector<float>&  pixel_orientations,
00103               vifa_parallel_params*  params) :
00104   vifa_parallel_params(params)
00105 {
00106   raw_h_ = new vifa_histogram(nbuckets, min_angle, max_angle);
00107   float  range = max_angle - min_angle;
00108 
00109   for (vcl_vector<float>::iterator p = pixel_orientations.begin();
00110        p != pixel_orientations.end(); ++p)
00111   {
00112     float  theta = (*p);
00113 
00114     while (theta < min_angle)
00115     {
00116       theta += range;
00117     }
00118     while (theta > max_angle)
00119     {
00120       theta -= range;
00121     }
00122 
00123     raw_h_->UpCount(theta);
00124   }
00125 
00126   norm_h_ = vifa_parallel::normalize_histogram(raw_h_);
00127 }
00128 
00129 vifa_parallel::
00130 vifa_parallel(float  center_angle,
00131               float  std_dev)
00132 {
00133   raw_h_ = new vifa_histogram(nbuckets, min_angle, max_angle);
00134 
00135 #ifdef DEBUG
00136   vcl_cout << "vifa_parallel(): 0.5 is "<< raw_h_->GetValIndex(0.5) << vcl_endl;
00137 #endif
00138 
00139   vifa_gaussian  g(center_angle, std_dev);
00140   for (float i = min_angle; i < 2 * max_angle; i++)
00141   {
00142     float  v = g.pdf(i);
00143     float  vx = map_x(i);
00144 
00145     raw_h_->SetCount(vx, raw_h_->GetCount(vx) + v);
00146   }
00147 
00148   norm_h_ = vifa_parallel::normalize_histogram(raw_h_);
00149 }
00150 
00151 vifa_parallel::~vifa_parallel()
00152 {
00153   delete raw_h_;
00154   delete norm_h_;
00155 }
00156 
00157 void vifa_parallel::reset(void)
00158 {
00159   delete norm_h_;
00160   norm_h_ = normalize_histogram(raw_h_);
00161 }
00162 
00163 vifa_histogram* vifa_parallel::
00164 get_raw_hist(void)
00165 {
00166   return raw_h_;
00167 }
00168 
00169 vifa_histogram* vifa_parallel::
00170 get_norm_hist(void)
00171 {
00172   return norm_h_;
00173 }
00174 
00175 void vifa_parallel::
00176 map_gaussian(float&  max_angle,
00177              float&  std_dev,
00178              float&  scale)
00179 {
00180   bool    set_min_res_flag = true;
00181 
00182   const float  incr = 3.0;  // put me in the params!
00183   float    max_value;
00184   float    local_max_angle = find_peak(max_value);
00185   max_angle = 0.0;
00186   std_dev = 0.0;
00187   scale = 0.0;
00188 
00189   // Skip histograms that are empty
00190   if (local_max_angle != -1.0)
00191   {
00192     float  min_residual = 0.f; // dummy initialisation
00193 
00194     for (float j=-(n_sigma+1); j<=(n_sigma+1); j++)
00195     {
00196       float  new_center = map_x(local_max_angle + (j * incr));
00197       float local_std_dev = 0.0;  // degrees
00198 
00199       for (int i = 0; i < 5; i++)
00200       {
00201         local_std_dev += incr;
00202         vifa_gaussian  g(new_center, local_std_dev);
00203         float      g_max = g.pdf(new_center);
00204         float      local_scale = norm_h_->GetCount(new_center) /
00205                         g_max;
00206         // NOTE: local_scale could be zero if the histogram is 0 here...
00207 
00208 #ifdef DUMP
00209         char      buf[25];
00210         vul_sprintf(buf, "gauss-%d-%d-%d.dat", pass, (int)j, i);
00211         vcl_ofstream  gdump(buf);
00212 #endif
00213         // int    sample_count = 0;
00214         float  sample_sum = 0.0;
00215 
00216         for (float  dx = (-n_sigma * local_std_dev);
00217              dx <= (n_sigma * local_std_dev);
00218              dx += norm_h_->GetBucketSize())
00219         {
00220           float  vx = new_center + dx;
00221           float  e = g.pdf(vx) * local_scale;
00222           // e could be zero because of local_scale, see above
00223           float  x = map_x(vx);
00224           float  f = norm_h_->GetCount(x);
00225           if (f < 0)
00226           {
00227             f = 0;
00228           }
00229 
00230           float  diff = vcl_fabs(f - e);
00231 
00232 #ifdef DUMP
00233           gdump << x << ' ' << e << ' ' << diff << ' ' << vx << ' ' << f << vcl_endl;
00234 #endif
00235           if (e != 0.0)
00236           {
00237             sample_sum += ((diff * diff) / e);
00238             // sample_count++;
00239           }
00240         }
00241 
00242         // Set min_residual the first time thru
00243         if ((set_min_res_flag || sample_sum < min_residual) && sample_sum != 0)
00244         {
00245           set_min_res_flag = false;
00246           min_residual = sample_sum;
00247           std_dev = local_std_dev;
00248           max_angle = new_center;
00249           scale = local_scale;
00250 
00251 #ifdef DEBUG
00252           vcl_cout << "*** ";
00253 #endif
00254         }
00255 
00256 #ifdef DEBUG
00257         vcl_cout << j << " gaussian " << i << " residual "
00258                  << sample_sum << " sample count " << sample_count << vcl_endl;
00259 #endif
00260       }
00261     }
00262 
00263 #ifdef DEBUG
00264     vcl_cout << "best is at " << max_angle << " sd of " << std_dev
00265              << " scale " << scale << vcl_endl;
00266 #endif
00267 
00268 #ifdef DUMP
00269     pass++;
00270 #endif
00271   }
00272 }
00273 
00274 void vifa_parallel::
00275 remove_gaussian(float  max_angle,
00276                 float  std_dev,
00277                 float  scale)
00278 {
00279   // Skip if histogram is empty
00280   if (norm_h_->GetMaxCount() != 0.0)
00281   {
00282     vifa_gaussian  g(max_angle, std_dev);
00283     for (float  dx = (-n_sigma * std_dev);
00284          dx <= (n_sigma * std_dev);
00285          dx += norm_h_->GetBucketSize())
00286     {
00287       float  vx = max_angle + dx;
00288       float  e = g.pdf(vx) * scale;
00289       float  x = map_x(vx);
00290       float  f = norm_h_->GetCount(x);
00291 
00292       if (f >= 0)
00293       {
00294         float  new_val = ((f - e) < 0) ? 0 : (f - e);
00295 
00296 #ifdef DEBUG
00297         vcl_cout << "  --- " << x << ": " << f <<" to " << new_val << vcl_endl;
00298 #endif
00299 
00300         norm_h_->SetCount(x, new_val);
00301       }
00302       else
00303       {
00304         vcl_cerr << "  --- " << x << ": bad " <<
00305           norm_h_->GetValIndex(x) << vcl_endl;
00306       }
00307     }
00308   }
00309 }
00310 
00311 void vifa_parallel::
00312 snapshot(char* fname)
00313 {
00314   norm_h_->WritePlot(fname);
00315 }
00316 
00317 float vifa_parallel::
00318 area(void)
00319 {
00320   if (norm_h_->GetMaxCount() == 0.0)
00321   {
00322     // Return 0 area for empty histograms
00323     return 0.0;
00324   }
00325   else
00326   {
00327     return norm_h_->ComputeArea();
00328   }
00329 }
00330 
00331 float vifa_parallel::
00332 bin_variance(void)
00333 {
00334   float* counts = norm_h_->GetCounts();
00335   int    res = norm_h_->GetRes();
00336   float  sum = 0;
00337   float  sum2 = 0;
00338 
00339   for (int i = 0; i < res; i++)
00340   {
00341     sum += counts[i];
00342     sum2 += (counts[i] * counts[i]);
00343   }
00344 
00345   float mean = sum / res;
00346   float var = (sum2 / res) - (mean * mean);
00347 
00348   return var;
00349 }
00350 
00351 float vifa_parallel::
00352 map_x(float  raw_x)
00353 {
00354   float  range = max_angle - min_angle + 1;
00355 
00356   while (raw_x < min_angle)
00357   {
00358     raw_x += range;
00359   }
00360   while (raw_x > max_angle)
00361   {
00362     raw_x -= range;
00363   }
00364 
00365   return raw_x;
00366 }
00367 
00368 vifa_histogram* vifa_parallel::
00369 normalize_histogram(vifa_histogram* h)
00370 {
00371   vifa_histogram*  norm = new vifa_histogram(nbuckets, min_angle, max_angle);
00372   int        nbuckets = h->GetRes();
00373   float      area = h->ComputeArea();
00374   float*      x_vals = h->GetVals();
00375   float*      y_vals = h->GetCounts();
00376 
00377   for (int i = 0; i < nbuckets; i++)
00378   {
00379     float  new_area = y_vals[i] / area;
00380     norm->SetCount(x_vals[i], new_area);
00381   }
00382 
00383   return norm;
00384 }
00385 
00386 float vifa_parallel::
00387 find_peak(float&  max_value)
00388 {
00389   int    nbuckets = norm_h_->GetRes();
00390   float*  x_vals = norm_h_->GetVals();
00391   float*  y_vals = norm_h_->GetCounts();
00392   int    max_index = -1;
00393   max_value = -1;
00394 
00395   for (int i = 0; i < nbuckets; i++)
00396   {
00397     if (y_vals[i] > max_value)
00398     {
00399       max_index = i;
00400       max_value = y_vals[i];
00401     }
00402   }
00403 
00404   if (max_index == -1)
00405   {
00406     return -1;
00407   }
00408 
00409   max_value = y_vals[max_index];
00410   return x_vals[max_index];
00411 }
00412 
00413 vtol_intensity_face_sptr vifa_parallel::
00414 get_adjacent_iface(vtol_intensity_face_sptr  known_face,
00415                    vtol_edge_2d*         e)
00416 {
00417   vtol_intensity_face_sptr  adj_face = 0;
00418   face_list faces; e->faces(faces);
00419 
00420   // Expect only two intensity faces for 2-D case
00421   if (faces.size() == 2)
00422   {
00423     vtol_intensity_face* f1 = faces[0]->cast_to_intensity_face();
00424     vtol_intensity_face* f2 = faces[1]->cast_to_intensity_face();
00425 
00426     if (f1 && f2)
00427     {
00428       if (*known_face == *f1)
00429       {
00430         adj_face = f2;
00431       }
00432       else if (*known_face == *f2)
00433       {
00434         adj_face = f1;
00435       }
00436       else
00437       {
00438         // Known face does not contain the
00439         // given edge -- leave result NULL
00440       }
00441     }
00442   }
00443   return adj_face;
00444 }

Generated on Thu Jan 10 14:47:31 2008 for contrib/gel/vifa by  doxygen 1.4.4