contrib/brl/bseg/bbgm/pro/processes/bbgm_local_frame_trans_process.cxx
Go to the documentation of this file.
00001 // This is brl/bseg/bbgm/pro/processes/bbgm_local_frame_trans_process.cxx
00002 //:
00003 // \file
00004 
00005 #include <core/vidl_pro/vidl_pro_utils.h>
00006 #include <bprb/bprb_func_process.h>
00007 #include <brip/brip_vil_float_ops.h>
00008 #include <bbgm/bbgm_image_of.h>
00009 #include <bbgm/bbgm_image_sptr.h>
00010 #include <bsta/bsta_attributes.h>
00011 #include <bsta/bsta_gauss_if3.h>
00012 #include <bsta/bsta_mixture.h>
00013 #include <brdb/brdb_value.h>
00014 #include <vbl/io/vbl_io_smart_ptr.h>
00015 #include <vil/vil_convert.h>
00016 #include <vil/vil_math.h>
00017 #include <vcl_iostream.h>
00018 #include <vcl_cmath.h>
00019 
00020 static void eigenvalues(double B, double C, double E, double& la,
00021                         double& lb)
00022 {
00023   double temp = vcl_sqrt((B-E)*(B-E)+4.0*C*C);
00024   la = 0.5*((B+E) + temp);
00025   lb = 0.5*((B+E) - temp);
00026 }
00027 
00028 bool bbgm_local_frame_trans_process_cons(bprb_func_process& pro)
00029 {
00030   //input
00031   vcl_vector<vcl_string> in_types(8), out_types(1);
00032 
00033   in_types[0]= "bbgm_image_sptr"; //background model
00034   in_types[1]= "vil_image_view_base_sptr"; //input frame
00035   in_types[2]= "vil_image_view_base_sptr"; //smoothed input frame
00036   in_types[3]= "vil_image_view_base_sptr"; //x gradient component
00037   in_types[4]= "vil_image_view_base_sptr"; //y gradient component
00038   in_types[5]= "double"; // min_eigenvalue
00039   in_types[6]= "double"; // max_condition_number
00040   in_types[7]= "double"; // max_pixel_shift
00041   pro.set_input_types(in_types);
00042 
00043   out_types[0]="vil_image_view_base_sptr";//transformed frame
00044   pro.set_output_types(out_types);
00045   return true;
00046 }
00047 
00048 //: Execute the process function
00049 bool bbgm_local_frame_trans_process(bprb_func_process& pro)
00050 {
00051   // Sanity check
00052   if (!pro.verify_inputs()) {
00053     vcl_cerr << "In bbgm_local_frame_trans_process::execute() -"
00054              << " invalid inputs\n";
00055     return false;
00056   }
00057 
00058   // Retrieve background image
00059   bbgm_image_sptr bgm = pro.get_input<bbgm_image_sptr>(0);
00060   if (!bgm)
00061   {
00062     vcl_cerr << "In bbgm_measure_process::execute() -"
00063              << " null background distribution image\n";
00064     return false;
00065   }
00066   typedef bsta_gauss_if3 bsta_gauss3_t;
00067   typedef bsta_gauss3_t::vector_type vector3_;
00068   typedef bsta_num_obs<bsta_gauss3_t> gauss_type3;
00069   typedef bsta_mixture<gauss_type3> mix_gauss_type3;
00070   typedef bsta_num_obs<mix_gauss_type3> obs_mix_gauss_type3;
00071 
00072   bbgm_image_of<obs_mix_gauss_type3> *model =
00073     static_cast<bbgm_image_of<obs_mix_gauss_type3>*>(bgm.ptr());
00074 
00075   //Retrieve input frame
00076   vil_image_view_base_sptr temp = pro.get_input<vil_image_view_base_sptr>(1);
00077   vil_image_view<float> frame = *vil_convert_cast(float(), temp);
00078   if (temp->pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00079     vil_math_scale_values(frame,1.0/255.0);
00080 
00081   temp = pro.get_input<vil_image_view_base_sptr>(2);
00082   if (temp->pixel_format() != VIL_PIXEL_FORMAT_FLOAT)
00083     return false;
00084   vil_image_view<float> gauss_smooth = *vil_convert_cast(float(), temp);
00085 
00086   temp = pro.get_input<vil_image_view_base_sptr>(3);
00087   if (temp->pixel_format() != VIL_PIXEL_FORMAT_FLOAT)
00088     return false;
00089   vil_image_view<float> Ix = *vil_convert_cast(float(), temp);
00090 
00091   temp = pro.get_input<vil_image_view_base_sptr>(4);
00092   if (temp->pixel_format() != VIL_PIXEL_FORMAT_FLOAT)
00093     return false;
00094   vil_image_view<float> Iy = *vil_convert_cast(float(), temp);
00095 
00096   unsigned ni = frame.ni(), nj = frame.nj(), np = frame.nplanes();
00097   if (np!=3)
00098     return false;
00099 
00100   // copy the frame into the output translated frame
00101   // pixels are modified only if translation computation is valid
00102   vil_image_view<float>* trans_frame = new vil_image_view<float>(frame);
00103 
00104   double min_eigenvalue =  pro.get_input<double>(5);
00105   double max_condition_number =  pro.get_input<double>(6);
00106   double max_translation =  pro.get_input<double>(7);
00107 
00108   float total = 0;
00109   float n_translate = 0;
00110   double du = 0, dv = 0;
00111   //compute translation on a 5x5 window
00112   for (int j = 2; j<static_cast<int>(nj-2); ++j)
00113   {
00114     for (int i = 2; i<static_cast<int>(ni-2); ++i)
00115     {
00116       total += 1.0f;
00117       double A = 0, B = 0, C= 0, D = 0, E = 0;
00118       bool trans = true;
00119       //run over 5x5 neighborhood about i,j
00120       for (int jn = -2; jn<=2; ++jn)
00121         for (int in = -2; in<=2; ++in) {
00122           //retrieve distribution
00123           obs_mix_gauss_type3 mog = (*model)(i+in, j+jn);
00124           bsta_gauss3_t gc = mog.distribution(0);
00125           vector3_ mean = gc.mean();
00126           vector3_ var = gc.covar();
00127           //sum over bands
00128           for (unsigned p = 0; p<3; ++p)
00129           {
00130             double i0 = gauss_smooth(i+in, j+jn, p);
00131             double ix = Ix(i+in, j+jn, p);
00132             double iy = Iy(i+in, j+jn, p);
00133             double rvar = 1.0/var[p];
00134             A += ix*(i0-mean[p])*rvar;
00135             B += ix*ix*rvar;
00136             C += ix*iy*rvar;
00137             D += iy*(i0-mean[p])*rvar;
00138             E += iy*iy*rvar;
00139           }
00140         }
00141       //solve for local translation
00142       // first get eigenvalues to check for singularities
00143       double la, lb;
00144       eigenvalues(B, C, E, la, lb);
00145       if (vcl_fabs(la)< min_eigenvalue || vcl_fabs(lb)< min_eigenvalue)
00146         trans = false;
00147       if (vcl_fabs(la/lb)>max_condition_number)
00148         trans = false;
00149       if (trans)
00150       {
00151         //solve for translation
00152         double rdet = 1.0/(B*E - C*C);
00153         double inv00 = E*rdet, inv01 = -C*rdet;
00154         double inv10 = -C*rdet, inv11 = B*rdet;
00155         double tu = -(A*inv00 + D*inv01);
00156         double tv = -(A*inv10 + D*inv11);
00157         if (vcl_fabs(tu)<max_translation && vcl_fabs(tv)<max_translation) {
00158           n_translate += 1.0f;
00159           du += vcl_fabs(tu);
00160           dv += vcl_fabs(tv);
00161           for (unsigned p = 0; p<3; ++p) {
00162             double itrans = gauss_smooth(i,j,p)+
00163               tu*Ix(i,j,p)+tv*Iy(i,j,p);
00164             (*trans_frame)(i,j,p) = static_cast<float>(itrans);
00165           }
00166         }
00167       }
00168     }
00169     vcl_cout << '.';
00170   }
00171   vcl_cout << "\nFraction translated " << n_translate/total
00172            << " with <tu> = " << du/n_translate
00173            << "and <tv> = " << dv/n_translate << '\n' << vcl_flush;
00174   vcl_vector<vcl_string> output_types(1);
00175   output_types[0]= "vil_image_view_base_sptr";
00176   pro.set_output_types(output_types);
00177 
00178   brdb_value_sptr output = new brdb_value_t<vil_image_view_base_sptr>(trans_frame);
00179   pro.set_output(0, output);
00180 
00181   return true;
00182 }