contrib/gel/vmal/vmal_kl.cxx
Go to the documentation of this file.
00001 // This is gel/vmal/vmal_kl.cxx
00002 #include "vmal_kl.h"
00003 
00004 #include <vxl_config.h>
00005 #include <vil1/vil1_pixel.h>
00006 #include <vil1/vil1_memory_image_of.h>
00007 #include <vil1/vil1_image_as.h>
00008 #include <vmal/vmal_multi_view_data.h>
00009 #include <vtol/vtol_vertex_2d.h>
00010 
00011 #include <vcl_iostream.h>
00012 
00013 
00014 vmal_kl::vmal_kl(const vmal_kl_params & params) : params_(params)
00015 {
00016 }
00017 
00018 vmal_kl::~vmal_kl()
00019 {
00020 }
00021 
00022 void vmal_kl::match_sequence(vcl_vector<vil1_image> &image_list,vmal_multi_view_data_vertex_sptr matches)
00023 {
00024   // Uses the KL tracker to track points through an image
00025   int nFeatures = params_.numpoints;
00026   int nFrames = image_list.size();
00027    // If there are no frames in this movie, then skip
00028   if (nFrames < 1) return;
00029 
00030   // Set up the context
00031   KLT_TrackingContext tc = KLTCreateTrackingContext();
00032   KLT_FeatureList     fl = KLTCreateFeatureList(nFeatures);
00033   KLT_FeatureTable    ft = KLTCreateFeatureTable(nFrames, nFeatures);
00034 
00035   // Apply the defaults
00036   set_tracking_context (tc);
00037   tc->sequentialMode = TRUE;
00038 
00039   int width=image_list[0].width();
00040   int height=image_list[0].height();
00041 
00042   // Now, get the imagery into a linear buffer
00043   KLT_PixelType* img1=convert_to_gs_image(image_list[0]);
00044 
00045   // Get some features from the first image
00046   KLTSelectGoodFeatures(tc, img1, width, height, fl);
00047   KLTStoreFeatureList(fl, ft, 0);
00048 
00049   for (int i=1; i<nFrames; i++)
00050       {
00051      KLT_PixelType* img2=convert_to_gs_image(image_list[i]);
00052 
00053       // Track the points
00054       KLTTrackFeatures(tc, img1, img2, width, height, fl);
00055 
00056       // Restore lost features
00057       if (params_.replaceLostPoints)
00058          KLTReplaceLostFeatures(tc, img2, width, height, fl);
00059 
00060       // Store the values
00061       KLTStoreFeatureList(fl, ft, i);
00062       }
00063    // Go through the feature table and store them
00064    int matchnum = -1;
00065    int pointnum, viewnum;
00066    //matches.set_params(ft->nFrames,ft->nFeatures);
00067 
00068    for (pointnum=0; pointnum<ft->nFeatures; pointnum++)
00069       for (viewnum=0; viewnum<ft->nFrames; viewnum++)
00070    {
00071    // Get the current feature
00072    KLT_Feature feat = ft->feature[pointnum][viewnum];
00073 
00074    // Get the components of this feature
00075    float x = feat->x;
00076    float y = feat->y;
00077 
00078    // Test to see if this is the continuation of a sequence
00079    // - then put in the table
00080    if (feat->val == 0)
00081    {
00082     vtol_vertex_2d_sptr vertex=new vtol_vertex_2d(x,y);
00083       matches->set(viewnum, matchnum, vertex);
00084    }
00085 
00086    // Otherwise, this is the start of a sequence
00087    if (feat->val > 0)
00088       {
00089       // Must test to see if the next value is zero
00090       // - otherwise this is a 1-frame sequence
00091       if (viewnum < ft->nFrames-1 &&
00092           ft->feature[pointnum][viewnum+1]->val == 0)
00093          {
00094          // This is a new match
00095          matchnum++;
00096 
00097          // Store it
00098        vtol_vertex_2d_sptr vertex=new vtol_vertex_2d(x,y);
00099          matches->set (viewnum, matchnum, vertex);
00100          }
00101       }
00102    }
00103    // Finally, renumber the matches
00104 //   matches.renumber();
00105 }
00106 
00107 
00108 #if 0 // vidl_vil1 no longer exists
00109 void vmal_kl::match_sequence(vidl_vil1_movie_sptr movie,vmal_multi_view_data_vertex_sptr matches)
00110 {
00111   vcl_vector<vil1_image> image_list;
00112   for (vidl_vil1_movie::frame_iterator pframe = movie->first();
00113         pframe <= movie->last();
00114         ++pframe)
00115     {
00116     vil1_image im = vil1_image(pframe->get_image());
00117     image_list.push_back(im);
00118     }
00119   match_sequence(image_list,matches);
00120 }
00121 #endif
00122 
00123 vcl_vector<vtol_vertex_2d_sptr>* vmal_kl::extract_points(vil1_image & image)
00124 {
00125   int width=image.width();
00126   int height=image.height();
00127   vcl_cerr << "Beginning points extraction\n";
00128 
00129   KLT_PixelType* img1=convert_to_gs_image(image);
00130 
00131   // Now, run the extractor
00132   int nFeatures = params_.numpoints;
00133 
00134   vcl_cerr << "Setting up the context...\n";
00135   // Set up the context
00136   KLT_TrackingContext tc = KLTCreateTrackingContext();
00137 
00138   // Set the default values
00139   set_tracking_context (tc);
00140 
00141   // KLTPrintTrackingContext(tc);
00142 
00143   // Set up structure to hold the features.
00144   vcl_cerr << "Setting up structure to hold the features...\n";
00145   KLT_FeatureList fl = KLTCreateFeatureList(nFeatures);
00146 
00147   // Extract the features
00148   vcl_cerr << "Extracting the features...\n";
00149   KLTSelectGoodFeatures(tc, img1, width, height, fl);
00150 
00151   // Make an IUPointGroup to hold the values
00152    vcl_vector<vtol_vertex_2d_sptr> *grp = new vcl_vector<vtol_vertex_2d_sptr>();
00153 
00154   for (int i=0 ; i< fl->nFeatures ; i++)
00155      {
00156      // Change the point into an IUPoint - offset by ilow, jlow
00157      float x = fl->feature[i]->x;
00158      float y = fl->feature[i]->y;
00159      //HomgPoint2D *point = new HomgPoint2D (x, y,1.0)
00160     vtol_vertex_2d_sptr point=new vtol_vertex_2d(x,y);
00161      // Put the point in the backup list
00162      grp->push_back(point);
00163      }
00164 
00165   // !!
00166   // We probably need to delete the feature list
00167 
00168   // Return the group
00169   return grp;
00170 }
00171 
00172 //Convert a vil1_image to an array of grey scale
00173 KLT_PixelType* vmal_kl::convert_to_gs_image(vil1_image &image)
00174 {
00175   vcl_cerr << "Converting image to grey scale...\n";
00176   if (vil1_pixel_format(image)==VIL1_RGB_BYTE)
00177   {
00178     int w=image.width();
00179     int h=image.height();
00180     KLT_PixelType* tab_mono=new KLT_PixelType[w*h];
00181     vcl_cerr << "width: " <<w<< "  height"<<h<<  vcl_endl;
00182 
00183     vil1_memory_image_of<vxl_byte> ima_mono;
00184     ima_mono.resize(w,h);
00185 
00186     vil1_image_as_byte(image).get_section(ima_mono.get_buffer(), 0, 0, w, h);
00187     vxl_byte* p=ima_mono.get_buffer();
00188 
00189     for (int i=0;i<w;i++)
00190       for (int j=0;j<h;j++)
00191         tab_mono[i*h+j]=(KLT_PixelType)p[i*h+j];
00192 
00193     return tab_mono;
00194   } else return NULL;
00195 }
00196 
00197 void vmal_kl::set_tracking_context( KLT_TrackingContext tc)
00198 {
00199   /* Set values to values derived from the parameters */
00200   tc->mindist               = params_.mindist;
00201   tc->window_width          = params_.window_width;
00202   tc->window_height         = params_.window_height;
00203   tc->sequentialMode        = params_.sequentialMode;
00204   tc->smoothBeforeSelecting = params_.smoothBeforeSelecting;
00205   tc->writeInternalImages   = params_.writeInternalImages;
00206   tc->min_eigenvalue        = params_.min_eigenvalue;
00207   tc->min_determinant       = params_.min_determinant;
00208   tc->max_iterations        = params_.max_iterations;
00209   tc->min_displacement      = params_.min_displacement;
00210   tc->max_residue           = params_.max_residue;
00211   tc->grad_sigma            = params_.grad_sigma;
00212   tc->smooth_sigma_fact     = params_.smooth_sigma_fact;
00213   tc->pyramid_sigma_fact    = params_.pyramid_sigma_fact;
00214   tc->nSkippedPixels        = params_.nSkippedPixels;
00215 
00216   // klt functions to complete the setup
00217   KLTChangeTCPyramid (tc, params_.search_range); //set nPyramidLevels and subsampling
00218   KLTUpdateTCBorder  (tc); //set borderx and bordery
00219 }
00220