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

strk_tracking_face_2d.cxx

Go to the documentation of this file.
00001 // This is brl/bseg/strk/strk_tracking_face_2d.cxx
00002 #include "strk_tracking_face_2d.h"
00003 //:
00004 // \file
00005 // See strk_tracking_face_2d.h
00006 //
00007 //-----------------------------------------------------------------------------
00008 #include <vcl_cmath.h> // for log(), exp() ..
00009 #include <vcl_cstdlib.h> // for rand()
00010 #include <vnl/vnl_math.h>
00011 #include <vgl/vgl_polygon.h>
00012 #include <vgl/vgl_polygon_scan_iterator.h>
00013 #include <bsta/bsta_joint_histogram.h>
00014 #include <vsol/vsol_point_2d.h>
00015 #include <vtol/vtol_vertex_2d.h>
00016 #include <btol/btol_face_algs.h>
00017 
00018 
00019 //#define DEBUG
00020 
00021 //
00022 //======================== TRACKING FACE IMPLEMENTATION =============
00023 //
00024 void strk_tracking_face_2d::centroid(double& x, double& y) const
00025 {
00026   if (!intf_)
00027   {
00028     x = 0;
00029     y = 0;
00030   }
00031   vtol_face_2d_sptr f = intf_->cast_to_face_2d();
00032   vsol_point_2d_sptr p = btol_face_algs::centroid(f);
00033   x = p->x();
00034   y = p->y();
00035 }
00036 
00037 static vnl_matrix_fixed<double,3,3> ident()
00038 {
00039   vnl_matrix_fixed<double,3,3> M;
00040   M[0][0] = 1.0;   M[0][1] = 0.0;   M[0][2] = 0.0;
00041   M[1][0] = 0.0;   M[1][1] = 1.0;   M[1][2] = 0.0;
00042   M[2][0] = 0.0;   M[2][1] = 0.0;   M[2][2] = 1.0;
00043   return M;
00044 }
00045 
00046 void strk_tracking_face_2d::init_bins()
00047 {
00048   intensity_hist_bins_=16;
00049   gradient_dir_hist_bins_=8;
00050   color_hist_bins_=8;
00051 }
00052 
00053 strk_tracking_face_2d::
00054 strk_tracking_face_2d(vtol_face_2d_sptr const& face,
00055                       vil1_memory_image_of<float> const& image,
00056                       vil1_memory_image_of<float> const& Ix,
00057                       vil1_memory_image_of<float> const& Iy,
00058                       vil1_memory_image_of<float> const& hue,
00059                       vil1_memory_image_of<float> const& sat,
00060                       const float min_gradient,
00061                       const float parzen_sigma,
00062                       const unsigned int intensity_hist_bins,
00063                       const unsigned int gradient_dir_hist_bins,
00064                       const unsigned int color_hist_bins,
00065                       const float max_intensity)
00066 {
00067   intensity_hist_bins_ = intensity_hist_bins;
00068   gradient_dir_hist_bins_=gradient_dir_hist_bins;
00069   color_hist_bins_=color_hist_bins;
00070   min_gradient_ = min_gradient;
00071   parzen_sigma_ = parzen_sigma;
00072   max_intensity_ = max_intensity;
00073   intf_ = 0;
00074   Ix_ = 0;
00075   Iy_ = 0;
00076   hue_ = 0;
00077   sat_ = 0;
00078   intensity_mi_=0;
00079   gradient_dir_mi_=0;
00080   color_mi_=0;
00081   model_intensity_entropy_=0;
00082   model_gradient_dir_entropy_=0;
00083   model_color_entropy_=0;
00084   intensity_entropy_=0;
00085   gradient_dir_entropy_=0;
00086   color_entropy_=0;
00087   intensity_joint_entropy_=0;
00088   model_intensity_joint_entropy_=0;
00089   gradient_joint_entropy_=0;
00090   color_joint_entropy_=0;
00091   intensity_info_diff_ = 0;
00092   color_info_diff_ = 0;
00093   gradient_info_ = Ix&&Iy;
00094   color_info_ = hue&&sat;
00095   renyi_joint_entropy_ = false;
00096   this->init_intensity_info(face, image);
00097   //cases
00098   if (gradient_info_)
00099     this->init_gradient_info(Ix, Iy);
00100 
00101   if (color_info_)
00102     this->init_color_info(hue, sat);
00103   trans_ = ident();
00104 }
00105 
00106 strk_tracking_face_2d::strk_tracking_face_2d(vtol_intensity_face_sptr const& intf,
00107                                              const unsigned int intensity_hist_bins,
00108                                              const unsigned int gradient_dir_hist_bins,
00109                                              const unsigned int color_hist_bins,
00110                                              const float max_intensity)
00111 {
00112   intensity_hist_bins_ = intensity_hist_bins;
00113   gradient_dir_hist_bins_=gradient_dir_hist_bins;
00114   color_hist_bins_=color_hist_bins;
00115   max_intensity_ = max_intensity;
00116   if (!intf)
00117     return;
00118   intf_ = intf;
00119   Ix_ = 0;
00120   Iy_ = 0;
00121   gradient_info_ = false;
00122   color_info_ = false;
00123   renyi_joint_entropy_ = false;
00124   intensity_mi_=0;
00125   gradient_dir_mi_=0;
00126   color_mi_=0;
00127   model_intensity_entropy_=0;
00128   model_gradient_dir_entropy_=0;
00129   model_color_entropy_=0;
00130   intensity_entropy_=0;
00131   gradient_dir_entropy_=0;
00132   color_entropy_=0;
00133   intensity_joint_entropy_=0;
00134   model_intensity_joint_entropy_=0;
00135   gradient_joint_entropy_=0;
00136   color_joint_entropy_=0;
00137   intensity_info_diff_ = 0;
00138   color_info_diff_ = 0;
00139   trans_ = ident();
00140 }
00141 
00142 strk_tracking_face_2d::strk_tracking_face_2d(strk_tracking_face_2d_sptr const& tf)
00143 {
00144   intensity_hist_bins_ = tf->intensity_hist_bins_;
00145   gradient_dir_hist_bins_= tf->gradient_dir_hist_bins_;
00146   color_hist_bins_= tf->color_hist_bins_;
00147   vtol_intensity_face_sptr intf = tf->face();
00148   vtol_face_2d_sptr f2d = new vtol_face_2d(intf->cast_to_face_2d());
00149   intf_= new vtol_intensity_face(f2d, intf->Npix(),
00150                                  intf->Xj(), intf->Yj(),
00151                                  intf->Ij());
00152 
00153   Ix_ = 0;
00154   Iy_ = 0;
00155   gradient_info_ = tf->gradient_info_;
00156   if (gradient_info_)
00157   {
00158     int n = intf_->Npix();
00159     Ix_ = new float[n];
00160     Iy_ = new float[n];
00161     for (int i =0; i<n; ++i)
00162     {
00163       Ix_[i]=tf->Ix(i);
00164       Iy_[i]=tf->Iy(i);
00165     }
00166   }
00167   hue_ = 0;
00168   sat_ = 0;
00169   color_info_ = tf->color_info_;
00170   if (color_info_)
00171   {
00172     int n = intf_->Npix();
00173     hue_ = new float[n];
00174     sat_ = new float[n];
00175     for (int i =0; i<n; ++i)
00176     {
00177       hue_[i]=tf->hue(i);
00178       sat_[i]=tf->sat(i);
00179     }
00180   }
00181   renyi_joint_entropy_ = tf->renyi_joint_entropy_;
00182   intensity_mi_ = tf->int_mutual_info();
00183   gradient_dir_mi_ = tf->grad_mutual_info();
00184   color_mi_ = tf->color_mutual_info();
00185   model_intensity_entropy_=tf->model_intensity_entropy_;
00186   model_gradient_dir_entropy_=tf->model_gradient_dir_entropy_;
00187   model_color_entropy_=tf->model_color_entropy_;
00188   intensity_entropy_=tf->intensity_entropy_;
00189   gradient_dir_entropy_=tf->gradient_dir_entropy_;
00190   color_entropy_=tf->color_entropy_;
00191   intensity_joint_entropy_=tf->intensity_joint_entropy_;
00192   model_intensity_joint_entropy_=tf->model_intensity_joint_entropy_;
00193   gradient_joint_entropy_=tf->gradient_joint_entropy_;
00194   color_joint_entropy_=tf->color_joint_entropy_;
00195   intensity_info_diff_ = tf->intensity_info_diff_;
00196   color_info_diff_ = tf->color_info_diff_;
00197   min_gradient_ = tf->min_gradient_;
00198   parzen_sigma_ = tf->parzen_sigma_;
00199   trans_ = tf->trans_;
00200   max_intensity_ = tf->max_intensity_;
00201 }
00202 
00203 strk_tracking_face_2d::strk_tracking_face_2d(strk_tracking_face_2d const& tf)
00204   : vbl_ref_count()
00205 {
00206   vtol_intensity_face_sptr intf = tf.face();
00207   vtol_face_2d_sptr f2d = new vtol_face_2d(intf->cast_to_face_2d());
00208   intf_= new vtol_intensity_face(f2d, intf->Npix(),
00209                                  intf->Xj(), intf->Yj(),
00210                                  intf->Ij());
00211 
00212   Ix_ = 0;
00213   Iy_ = 0;
00214   gradient_info_ = tf.gradient_info_;
00215   if (gradient_info_)
00216   {
00217     int n = intf_->Npix();
00218     Ix_ = new float[n];
00219     Iy_ = new float[n];
00220     for (int i =0; i<n; ++i)
00221     {
00222       Ix_[i]=tf.Ix(i);
00223       Iy_[i]=tf.Iy(i);
00224     }
00225   }
00226   hue_ = 0;
00227   sat_ = 0;
00228   color_info_ = tf.color_info_;
00229   if (color_info_)
00230   {
00231     int n = intf_->Npix();
00232     hue_ = new float[n];
00233     sat_ = new float[n];
00234     for (int i =0; i<n; ++i)
00235     {
00236       hue_[i]=tf.hue(i);
00237       sat_[i]=tf.sat(i);
00238     }
00239   }
00240   renyi_joint_entropy_ = tf.renyi_joint_entropy_;
00241   intensity_mi_ = tf.int_mutual_info();
00242   gradient_dir_mi_ = tf.grad_mutual_info();
00243   color_mi_ = tf.color_mutual_info();
00244   model_intensity_entropy_=tf.model_intensity_entropy_;
00245   model_gradient_dir_entropy_=tf.model_gradient_dir_entropy_;
00246   model_color_entropy_=tf.model_color_entropy_;
00247   intensity_entropy_=tf.intensity_entropy_;
00248   gradient_dir_entropy_=tf.gradient_dir_entropy_;
00249   color_entropy_=tf.color_entropy_;
00250   intensity_joint_entropy_=tf.intensity_joint_entropy_;
00251   model_intensity_joint_entropy_=tf.model_intensity_joint_entropy_;
00252   gradient_joint_entropy_=tf.gradient_joint_entropy_;
00253   color_joint_entropy_=tf.color_joint_entropy_;
00254   intensity_info_diff_ = tf.intensity_info_diff_;
00255   color_info_diff_ = tf.color_info_diff_;
00256   min_gradient_ = tf.min_gradient_;
00257   parzen_sigma_ = tf.parzen_sigma_;
00258   trans_ = tf.trans_;
00259   intensity_hist_bins_=tf.intensity_hist_bins_;
00260   gradient_dir_hist_bins_=tf.gradient_dir_hist_bins_;
00261   color_hist_bins_=tf.color_hist_bins_;
00262   max_intensity_ = tf.max_intensity_;
00263 }
00264 
00265 strk_tracking_face_2d::~strk_tracking_face_2d()
00266 {
00267   delete [] Ix_;
00268   delete [] Iy_;
00269   delete [] hue_;
00270   delete [] sat_;
00271 }
00272 
00273 void strk_tracking_face_2d::set_gradient(vil1_memory_image_of<float> const& Ix,
00274                                          vil1_memory_image_of<float> const& Iy)
00275 {
00276     int i = 0;
00277     if (!intf_||!Ix_||!Iy_)
00278       return;
00279     for (intf_->reset(); intf_->next(); ++i)
00280     {
00281       int x = int(intf_->X()), y = int(intf_->Y());
00282       this->set_Ix(i, Ix(x,y));
00283       this->set_Iy(i, Iy(x,y));
00284     }
00285 }
00286 
00287 void strk_tracking_face_2d::set_color(vil1_memory_image_of<float> const& hue,
00288                                       vil1_memory_image_of<float> const& sat)
00289 {
00290     int i = 0;
00291     if (!intf_||!hue_||!sat_)
00292       return;
00293     for (intf_->reset(); intf_->next(); ++i)
00294     {
00295       int x = int(intf_->X()), y = int(intf_->Y());
00296       this->set_hue(i, hue(x,y));
00297       this->set_sat(i, sat(x,y));
00298     }
00299 }
00300 
00301 void strk_tracking_face_2d::
00302 init_intensity_info(vtol_face_2d_sptr const& face,
00303                     vil1_memory_image_of<float> const& image)
00304 {
00305   if (!face||!image)
00306     return;
00307   intf_ = new vtol_intensity_face(face);
00308   int width = image.width(), height = image.height();
00309   intf_->ResetPixelData();
00310   vgl_polygon<double> p;
00311   if (!btol_face_algs::vtol_to_vgl(intf_->cast_to_face_2d(), p))
00312     return;
00313   vgl_polygon_scan_iterator<double> psi(p, true);
00314 
00315   //go throught the pixels once to gather statistics for the face Npix etc.
00316   for (psi.reset(); psi.next();)
00317     for (int x = psi.startx(); x<=psi.endx(); ++x)
00318     {
00319       int y = psi.scany();
00320       if (x<0||x>=width||y<0||y>=height)
00321         continue;
00322 
00323       unsigned short v = (unsigned short)image(x, y);
00324       intf_->IncrementMeans(float(x), float(y), v);
00325     }
00326   if (!intf_->Npix())
00327   {
00328     vcl_cout << "In strk_tracking_face_2d::strk_tracking_face_2d(..) -"
00329              << " no pixels\n";
00330     return;
00331   }
00332   intf_->InitPixelArrays();
00333 
00334   bsta_histogram<float> model_intensity_hist(max_intensity_, intensity_hist_bins_);
00335   intensity_hist_bins_ = model_intensity_hist.nbins();
00336 
00337   //Got through the pixels again to actually set the face arrays X(), Y() etc
00338   for (psi.reset(); psi.next();)
00339     for (int x = psi.startx(); x<=psi.endx(); ++x)
00340     {
00341       int y = psi.scany();
00342       if (x<0||x>=width||y<0||y>=height)
00343         continue;
00344       unsigned short v = (unsigned short)image(x, y);
00345       model_intensity_hist.upcount(v, 1.0f);
00346       intf_->InsertInPixelArrays(float(x), float(y), v);
00347     }
00348   //apply parzen window to histogram
00349 #ifdef DEBUG
00350   vcl_cout << "\n\n Before Parzen(1d) - npix ="
00351            << model_intensity_hist.area() << vcl_endl;
00352 
00353   model_intensity_hist.print();
00354 #endif //DEBUG
00355 
00356   model_intensity_hist.parzen(parzen_sigma_);
00357 
00358 #ifdef DEBUG
00359   vcl_cout << "After Parzen(1d)\n";
00360   model_intensity_hist.print();
00361 #endif //DEBUG
00362   //compute the model entropy
00363   model_intensity_entropy_ = model_intensity_hist.entropy();
00364 }
00365 
00366 //: fill the gradient values in the face
00367 //  Assumes that the intensity face parent has already been initialized.
00368 void strk_tracking_face_2d::
00369 init_gradient_info(vil1_memory_image_of<float> const& Ix,
00370                    vil1_memory_image_of<float> const& Iy)
00371 {
00372   if (!intf_||!Ix||!Iy)
00373     return;
00374   int n = intf_->Npix();
00375   Ix_ = new float[n];
00376   Iy_ = new float[n];
00377   bsta_histogram<float> model_gradient_dir_hist(360, gradient_dir_hist_bins_);
00378   gradient_dir_hist_bins_ = model_gradient_dir_hist.nbins();
00379   int i = 0;
00380   double deg_rad = 180.0/vnl_math::pi;
00381   for (intf_->reset(); intf_->next(); ++i)
00382   {
00383     int x = int(intf_->X()), y = int(intf_->Y());
00384     float Ixi = Ix(x,y), Iyi = Iy(x,y);
00385     // set the gradient values
00386     Ix_[i] = Ixi;  Iy_[i] = Iyi;
00387     float ang = float(deg_rad*vcl_atan2(Iyi, Ixi))+180.f;
00388     float mag = vcl_abs(Ixi)+vcl_abs(Iyi);
00389     if (mag>min_gradient_)
00390       model_gradient_dir_hist.upcount(ang, mag);
00391   }
00392 
00393   //apply parzen window to histogram
00394   model_gradient_dir_hist.parzen(parzen_sigma_);
00395 
00396   //compute the gradient direction entropy
00397   model_gradient_dir_entropy_= model_gradient_dir_hist.entropy();
00398 }
00399 
00400 //: fill the color values in the face
00401 //  Assumes that the intensity face parent has already been initialized.
00402 void strk_tracking_face_2d::
00403 init_color_info(vil1_memory_image_of<float> const& hue,
00404                 vil1_memory_image_of<float> const& sat)
00405 {
00406   if (!intf_||!hue||!sat)
00407     return;
00408   int n = intf_->Npix();
00409   hue_ = new float[n];
00410   sat_ = new float[n];
00411   bsta_histogram<float> model_color_hist(360, color_hist_bins_);
00412   color_hist_bins_ = model_color_hist.nbins();
00413   int i = 0;
00414   for (intf_->reset(); intf_->next(); ++i)
00415   {
00416     int x = int(intf_->X()), y = int(intf_->Y());
00417     float hue_i = hue(x,y), sat_i = sat(x,y);
00418     // set the gradient values
00419     hue_[i] = hue_i;  sat_[i] = sat_i;
00420     if (sat_i>0)
00421       model_color_hist.upcount(hue_i, sat_i);
00422   }
00423 
00424   //apply parzen window to histogram
00425   model_color_hist.parzen(parzen_sigma_);
00426 
00427   //compute the color entropy
00428   model_color_entropy_= model_color_hist.entropy();
00429 }
00430 
00431 void strk_tracking_face_2d::set_int_mutual_info(float mi)
00432 {
00433   intensity_mi_ = mi;
00434   total_info_= mi + gradient_dir_mi_+color_mi_;
00435 }
00436 
00437 void strk_tracking_face_2d::set_grad_mutual_info(float mi)
00438 {
00439   gradient_dir_mi_ = mi;
00440   total_info_= mi + intensity_mi_ + color_mi_;
00441 }
00442 
00443 void strk_tracking_face_2d::set_color_mutual_info(float mi)
00444 {
00445   color_mi_ = mi;
00446   total_info_= mi + intensity_mi_+ gradient_dir_mi_;
00447 }
00448 
00449 #if 0
00450 // rotate gradients and recompute gradient mutual information
00451 void strk_tracking_face_2d::transform_gradients(double theta)
00452 {
00453   double deg_rad = 180.0/vnl_math::pi;
00454   double c = vcl_cos(theta), s = vcl_sin(theta);
00455 
00456   bsta_histogram<float> model_gradient_dir_hist(360, gradient_dir_hist_bins_);
00457   gradient_dir_hist_bins_ = model_gradient_dir_hist.nbins();
00458 
00459   // step through points in face
00460   int i=0;
00461   for (this->reset(); this->next(); ++i)
00462   {
00463     float Ix0 = Ix_[i];
00464     float Iy0 = Iy_[i];
00465     Ix_[i] = float(Ix0*c - Iy0*s);
00466     Iy_[i] = float(Ix0*s + Iy0*c);
00467     float ang = float(deg_rad*vcl_atan2(Iy_[i],Ix_[i]))+180.f;
00468     float mag = vcl_abs(Ix_[i])+vcl_abs(Iy_[i]);
00469     if (mag>min_gradient_)
00470       model_gradient_dir_hist.upcount(ang, mag);
00471   }
00472 
00473   //apply parzen window to histogram
00474   model_gradient_dir_hist.parzen(parzen_sigma_);
00475 
00476   //compute the gradient direction entropy
00477   float ent = 0;
00478   for (unsigned int m = 0; m<gradient_dir_hist_bins_; ++m)
00479   {
00480     float pm = model_gradient_dir_hist.p(m);
00481     if (!pm)
00482       continue;
00483     ent -= pm*vcl_log(pm);
00484   }
00485   model_gradient_dir_entropy_= float(ent/vcl_log(2.0));
00486 }
00487 #endif // 0
00488 
00489 // rotate gradients
00490 void strk_tracking_face_2d::transform_gradients(double theta)
00491 {
00492   double c = vcl_cos(theta), s = vcl_sin(theta);
00493 
00494   // step through gradient values in face
00495   int i=0;
00496   for (this->reset(); this->next(); ++i)
00497   {
00498     float Ix0 = Ix_[i];
00499     float Iy0 = Iy_[i];
00500     Ix_[i] = float(Ix0*c - Iy0*s);
00501     Iy_[i] = float(Ix0*s + Iy0*c);
00502   }
00503 }
00504 
00505 void strk_tracking_face_2d::transform(double tx, double ty, double theta, double scale)
00506 {
00507   double xo = 0, yo =0;
00508   this->centroid(xo, yo);
00509   double c = vcl_cos(theta), s = vcl_sin(theta);
00510   vcl_vector<vtol_vertex_sptr> verts;
00511   this->face()->vertices(verts);
00512   for (vcl_vector<vtol_vertex_sptr>::iterator vit = verts.begin();
00513        vit != verts.end(); ++vit)
00514   {
00515     vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00516     if (!v)
00517       continue;
00518     double x = v->x(), y = v->y();
00519     double xp =(x-xo)*scale, yp =(y-yo)*scale;
00520     v->set_x(xp*c - yp*s + xo + tx);
00521     v->set_y(xp*s + yp*c + yo + ty);
00522   }
00523   for (this->reset(); this->next();)
00524   {
00525     double x = this->X(), y = this->Y();
00526     double xp =(x-xo)*scale, yp =(y-yo)*scale;
00527     this->set_X(float(xp*c - yp*s + xo + tx));
00528     this->set_Y(float(xp*s + yp*c + yo + ty));
00529   }
00530   //update global transform
00531   vnl_matrix_fixed<double,3,3> Mt, Mt_inv, M, Mf;
00532   Mt[0][0] = 1.0;   Mt[0][1] = 0.0;   Mt[0][2] = -xo;
00533   Mt[1][0] = 0.0;   Mt[1][1] = 1.0;   Mt[1][2] = -yo;
00534   Mt[2][0] = 0.0;   Mt[2][1] = 0.0;   Mt[2][2] = 1.0;
00535 
00536   Mt_inv[0][0] = 1.0;   Mt_inv[0][1] = 0.0;   Mt_inv[0][2] = xo+tx;
00537   Mt_inv[1][0] = 0.0;   Mt_inv[1][1] = 1.0;   Mt_inv[1][2] = yo+ty;
00538   Mt_inv[2][0] = 0.0;   Mt_inv[2][1] = 0.0;   Mt_inv[2][2] = 1.0;
00539 
00540   double scc = c*scale, scs = s*scale;
00541   M[0][0] =scc ;   M[0][1] = -scs;   M[0][2] = 0;
00542   M[1][0] = scs;   M[1][1] = scc;    M[1][2] = 0;
00543   M[2][0] = 0.0;   M[2][1] = 0.0;    M[2][2] = 1.0;
00544   trans_ = Mt_inv*M*Mt*trans_;
00545 
00546   if (gradient_info_)
00547     this->transform_gradients(theta);
00548 }
00549 
00550 //:  Note this transform call does not currently transform gradient directions
00551 void strk_tracking_face_2d::transform(vnl_matrix_fixed<double,3,3> const& T)
00552 {
00553   vcl_vector<vtol_vertex_sptr> verts;
00554   this->face()->vertices(verts);
00555   for (vcl_vector<vtol_vertex_sptr>::iterator vit = verts.begin();
00556        vit != verts.end(); ++vit)
00557   {
00558     vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00559     if (!v)
00560       continue;
00561     double x = v->x(), y = v->y();
00562     vnl_vector_fixed<double, 3> X(x, y, 1.0), Xp;
00563     Xp = T*X;
00564     v->set_x(Xp[0]);
00565     v->set_y(Xp[1]);
00566   }
00567   for (this->reset(); this->next();)
00568   {
00569     double x = this->X(), y = this->Y();
00570     vnl_vector_fixed<double, 3> X(x, y, 1.0), Xp;
00571     Xp = T*X;
00572     this->set_X(float(Xp[0]));
00573     this->set_Y(float(Xp[1]));
00574   }
00575   trans_ = T*trans_;
00576 }
00577 
00578 float strk_tracking_face_2d::
00579 compute_intensity_mutual_information(vil1_memory_image_of<float> const& image)
00580 {
00581   if (!intf_)
00582     return 0;
00583   int width = image.width(), height = image.height();
00584   bsta_histogram<float> image_hist(max_intensity_, intensity_hist_bins_);
00585   bsta_joint_histogram<float> joint_hist(max_intensity_, intensity_hist_bins_);
00586   unsigned int npix = intf_->Npix();
00587   if (npix == 0)
00588     return 0;
00589   unsigned int n = 0;
00590   for (intf_->reset(); intf_->next(); ++n)
00591   {
00592     int x = int(intf_->X()), y = int(intf_->Y());
00593     if (x<0||x>=width||y<0||y>=height)
00594       continue;
00595     float Ii = image(x,y);
00596     float Im = intf_->I();
00597     image_hist.upcount(Ii, 1.0f);
00598     joint_hist.upcount(Im, 1.0f, Ii, 1.0f);
00599 #ifdef DEBUG
00600     vcl_cout << '(' << x << ' ' << y << "):[" << Im << ' ' << Ii << ']' << vcl_endl;
00601 #endif
00602   }
00603   if (n<0.9*npix)
00604     return 0;
00605 #ifdef DEBUG
00606   vcl_cout << "Itensity Hist\n";
00607   image_hist.print();
00608   vcl_cout << "Joint Intensity Hist\n";
00609   joint_hist.print();
00610 #endif
00611   //apply parzen windows
00612   image_hist.parzen(parzen_sigma_);
00613   joint_hist.parzen(parzen_sigma_);
00614 
00615   //compute the mutual information
00616   intensity_entropy_= image_hist.entropy();
00617   intensity_joint_entropy_ = renyi_joint_entropy_ ? joint_hist.renyi_entropy() : joint_hist.entropy();
00618 
00619   float mi = float(model_intensity_entropy_ + intensity_entropy_ - intensity_joint_entropy_);
00620 
00621 #ifdef DEBUG
00622   vcl_cout << "Entropies:(M,I,J, MI)=(" << model_intensity_entropy_ << ' '
00623            << intensity_entropy_ << ' ' << intensity_joint_entropy_ << ' ' << mi <<")\n";
00624 #endif
00625   return mi;
00626 }
00627 
00628 float strk_tracking_face_2d::
00629 compute_intensity_mutual_information(vcl_vector <vcl_vector< vgl_point_2d<int> > > region_map,
00630                                      int base_x, int base_y,
00631                                      vil1_memory_image_of<float> const& image)
00632 {
00633   if (!intf_)
00634     return 0;
00635   int width = image.width(), height = image.height();
00636   bsta_histogram<float> image_hist(max_intensity_, intensity_hist_bins_);
00637   bsta_joint_histogram<float> joint_hist(max_intensity_, intensity_hist_bins_);
00638   unsigned int npix = intf_->Npix();
00639   if (npix == 0)
00640     return 0;
00641 #ifdef DEBUG
00642   unsigned int n = 0;
00643 #endif
00644   for (intf_->reset(); intf_->next();)
00645   {
00646     int x = int(intf_->X()), y = int(intf_->Y());
00647 
00648     //: region_map starts from (0,0)
00649     x = x - base_x; y = y - base_y;
00650     if (x < 0 || x >= static_cast<int>(region_map.size()) ||
00651         y < 0 || y >= static_cast<int>(region_map[x].size())) continue;
00652 
00653     //: read corresponding region 2 pixel from map
00654     vgl_point_2d<int> p = region_map[x][y];
00655     if (p.x() < 0 || p.y() < 0 || p.x() >= width || p.y() >= height) continue;
00656 
00657     float Ii = image(p.x(),p.y());
00658     float Im = intf_->I();
00659     image_hist.upcount(Ii, 1.0f);
00660     joint_hist.upcount(Im, 1.0f, Ii, 1.0f);
00661 #ifdef DEBUG
00662     vcl_cout << '(' << x << ' ' << y << "):[" << Im << ' ' << Ii << ']' << vcl_endl;
00663     ++n;
00664 #endif
00665   }
00666 
00667 // we don't know the relation of number of pixels in second region to
00668 // the number of pixels in the first region (maybe a constant can be put)
00669 #ifdef DEBUG
00670   vcl_cout << "n = " << n << ", 0.9*npix = " << 0.9*npix << " (n should be at least 0.9*npix)\n";
00671 #endif
00672 #if 0
00673   if (n<0.9*npix)
00674     return 0;
00675 #endif // 0
00676 
00677 #ifdef DEBUG
00678   vcl_cout << "Itensity Hist\n";
00679   image_hist.print();
00680   vcl_cout << "Joint Intensity Hist\n";
00681   joint_hist.print();
00682 #endif
00683   //apply parzen windows
00684   image_hist.parzen(parzen_sigma_);
00685   joint_hist.parzen(parzen_sigma_);
00686 
00687   //compute the mutual information
00688   intensity_entropy_= image_hist.entropy();
00689   intensity_joint_entropy_ = renyi_joint_entropy_ ? joint_hist.renyi_entropy() : joint_hist.entropy();
00690 
00691   float mi = float(model_intensity_entropy_ + intensity_entropy_ - intensity_joint_entropy_);
00692 
00693 #ifdef DEBUG
00694   vcl_cout << "Entropies:(M,I,J, MI)=(" << model_intensity_entropy_ << ' '
00695            << intensity_entropy_ << ' ' << intensity_joint_entropy_ << ' ' << mi <<")\n";
00696 #endif
00697   return mi;
00698 }
00699 
00700 float strk_tracking_face_2d::
00701 compute_gradient_mutual_information(vil1_memory_image_of<float> const& Ix,
00702                                     vil1_memory_image_of<float> const& Iy)
00703 {
00704   if (!intf_||!Ix||!Iy)
00705     return 0;
00706   int width = Ix.width(), height = Iy.height();
00707   bsta_histogram<float> image_dir_hist(360, gradient_dir_hist_bins_);
00708   bsta_joint_histogram<float> joint_dir_hist(360, gradient_dir_hist_bins_);
00709 
00710   unsigned int npix = intf_->Npix();
00711   if (npix == 0)
00712     return 0;
00713   double deg_rad = 180.0/vnl_math::pi;
00714   unsigned int n = 0;
00715   for (intf_->reset(); intf_->next(); ++n)
00716   {
00717     int x = int(intf_->X()), y = int(intf_->Y());
00718     if (x<0||x>=width||y<0||y>=height)
00719       continue;
00720     float Ix0 = this->Ix(n), Iy0 = this->Iy(n);
00721     float ang0 = float(deg_rad*vcl_atan2(Iy0, Ix0))+180.f;
00722     float mag0 = vcl_abs(Ix0)+vcl_abs(Iy0); // was: vcl_sqrt(Ix0*Ix0 + Iy0*Iy0);
00723     float Ixi = Ix(x,y), Iyi = Iy(x,y);
00724     float angi = float(deg_rad*vcl_atan2(Iyi, Ixi))+180.f;
00725     float magi = vcl_abs(Ixi)+vcl_abs(Iyi); // was: vcl_sqrt(Ixi*Ixi + Iyi*Iyi);
00726 #ifdef DEBUG
00727     vcl_cout << "ang0, mag0 " << ang0 << ' ' << mag0 << '\n'
00728              << "Ixi, Iyi " << Ixi << ' ' << Iyi << '\n'
00729              << "angi, magi " << angi << ' ' << magi << '\n';
00730 #endif
00731     if (mag0>min_gradient_&&magi>min_gradient_)
00732     {
00733       image_dir_hist.upcount(angi, magi);
00734       joint_dir_hist.upcount(ang0,mag0,angi,magi);
00735     }
00736   }
00737   if (n<0.9*npix)
00738     return 0;
00739 #ifdef DEBUG
00740   vcl_cout << "Image Dir Hist\n";
00741   image_dir_hist.print();
00742   vcl_cout << "Joint Dir Hist\n";
00743   joint_dir_hist.print();
00744 #endif
00745 
00746   //apply parzen windows
00747   image_dir_hist.parzen(parzen_sigma_);
00748   joint_dir_hist.parzen(parzen_sigma_);
00749 
00750   gradient_dir_entropy_ = image_dir_hist.entropy();
00751   gradient_joint_entropy_ = renyi_joint_entropy_ ? joint_dir_hist.renyi_entropy() : joint_dir_hist.entropy();
00752 
00753   float mi = float(model_gradient_dir_entropy_ + gradient_dir_entropy_ - gradient_joint_entropy_);
00754 #ifdef DEBUG
00755   vcl_cout << "Dir Entropies:(M,I,J, MI)=(" << model_gradient_dir_entropy_ << ' '
00756            << gradient_dir_entropy_ << ' ' << gradient_joint_entropy_ << ' ' << mi <<")\n";
00757 #endif
00758   return mi;
00759 }
00760 
00761 float strk_tracking_face_2d::
00762 compute_gradient_mutual_information(vcl_vector <vcl_vector< vgl_point_2d<int> > > region_map,
00763                                     int base_x, int base_y,
00764                                     vil1_memory_image_of<float> const& Ix,
00765                                     vil1_memory_image_of<float> const& Iy)
00766 {
00767   if (!intf_||!Ix||!Iy)
00768     return 0;
00769   int width = Ix.width(), height = Iy.height();
00770   bsta_histogram<float> image_dir_hist(360, gradient_dir_hist_bins_);
00771   bsta_joint_histogram<float> joint_dir_hist(360, gradient_dir_hist_bins_);
00772 
00773   unsigned int npix = intf_->Npix();
00774   if (npix == 0)
00775     return 0;
00776   double deg_rad = 180.0/vnl_math::pi;
00777   unsigned int n = 0;
00778   for (intf_->reset(); intf_->next(); ++n)
00779   {
00780     int x = int(intf_->X()), y = int(intf_->Y());
00781 
00782     x = x - base_x; y = y - base_y;
00783     if (x < 0 || x >= static_cast<int>(region_map.size()) ||
00784         y < 0 || y >= static_cast<int>(region_map[x].size())) continue;
00785 
00786     vgl_point_2d<int> p = region_map[x][y];
00787     if (p.x() < 0 || p.y() < 0 || p.x() >= width || p.y() >= height) continue;
00788 
00789     float Ix0 = this->Ix(n), Iy0 = this->Iy(n);
00790     float ang0 = float(deg_rad*vcl_atan2(Iy0, Ix0))+180.f;
00791     float mag0 = vcl_abs(Ix0)+vcl_abs(Iy0); // was: vcl_sqrt(Ix0*Ix0 + Iy0*Iy0);
00792 
00793     float Ixi = Ix(p.x(),p.y()), Iyi = Iy(p.x(),p.y());
00794     float angi = float(deg_rad*vcl_atan2(Iyi, Ixi))+180.f;
00795     float magi = vcl_abs(Ixi)+vcl_abs(Iyi); // was: vcl_sqrt(Ixi*Ixi + Iyi*Iyi);
00796 #ifdef DEBUG
00797     vcl_cout << "ang0, mag0 " << ang0 << ' ' << mag0 << '\n'
00798              << "Ixi, Iyi " << Ixi << ' ' << Iyi << '\n'
00799              << "angi, magi " << angi << ' ' << magi << '\n';
00800 #endif
00801     if (mag0>min_gradient_&&magi>min_gradient_)
00802     {
00803       image_dir_hist.upcount(angi, magi);
00804       joint_dir_hist.upcount(ang0,mag0,angi,magi);
00805     }
00806   }
00807 
00808 #ifdef DEBUG
00809   vcl_cout << "n = " << n << ", 0.9*npix = " << 0.9*npix << " (n should be larger than 0.9*npix)\n";
00810 #endif
00811 #if 0
00812   if (n<0.9*npix)
00813     return 0;
00814 #endif // 0
00815 
00816 #ifdef DEBUG
00817   vcl_cout << "Image Dir Hist\n";
00818   image_dir_hist.print();
00819   vcl_cout << "Joint Dir Hist\n";
00820   joint_dir_hist.print();
00821 #endif
00822 
00823   //apply parzen windows
00824   image_dir_hist.parzen(parzen_sigma_);
00825   joint_dir_hist.parzen(parzen_sigma_);
00826 
00827   gradient_dir_entropy_ = image_dir_hist.entropy();
00828   gradient_joint_entropy_ = renyi_joint_entropy_ ? joint_dir_hist.renyi_entropy() : joint_dir_hist.entropy();
00829 
00830   float mi = float(model_gradient_dir_entropy_ + gradient_dir_entropy_ - gradient_joint_entropy_);
00831 #ifdef DEBUG
00832   vcl_cout << "Dir Entropies:(M,I,J, MI)=(" << model_gradient_dir_entropy_ << ' '
00833            << gradient_dir_entropy_ << ' ' << gradient_joint_entropy_ << ' ' << mi <<")\n";
00834 #endif
00835   return mi;
00836 }
00837 
00838 float strk_tracking_face_2d::
00839 compute_color_mutual_information(vil1_memory_image_of<float> const& hue,
00840                                  vil1_memory_image_of<float> const& sat)
00841 {
00842   if (!intf_||!hue||!sat)
00843     return 0;
00844   int width = hue.width(), height = hue.height();
00845   bsta_histogram<float> color_hist(360, color_hist_bins_);
00846   bsta_joint_histogram<float> joint_color_hist(360, color_hist_bins_);
00847 
00848   unsigned int npix = intf_->Npix();
00849   if (npix == 0)
00850     return 0;
00851 
00852   unsigned int n = 0;
00853   for (intf_->reset(); intf_->next(); ++n)
00854   {
00855     int x = int(intf_->X()), y = int(intf_->Y());
00856     if (x<0||x>=width||y<0||y>=height)
00857       continue;
00858     float hue0 = this->hue(n), sat0 = this->sat(n);
00859     float hue_i = hue(x,y), sat_i = sat(x,y);
00860     if (sat_i>0)
00861       color_hist.upcount(hue_i, sat_i);
00862     if (sat0>0&&sat_i>0)
00863       joint_color_hist.upcount(hue0, sat0, hue_i, sat_i);
00864   }
00865   if (n<0.9*npix)
00866     return 0;
00867 
00868   //apply parzen windows
00869   color_hist.parzen(parzen_sigma_);
00870   joint_color_hist.parzen(parzen_sigma_);
00871 
00872   //compute entropies
00873   color_entropy_ = color_hist.entropy();
00874