contrib/gel/vsrl/vsrl_manager.cxx

Go to the documentation of this file.
00001 #include "vsrl_manager.h"
00002 //:
00003 // \file
00004 // \brief This program was written to test the Dense Matching software
00005 // \author G.W. Brooksby
00006 // \date February 13, 2003
00007 
00008 #include <vcl_cstdlib.h>
00009 #include <vcl_cmath.h>
00010 #include <vcl_iostream.h>
00011 #include <vil1/vil1_load.h>
00012 #include <vil1/vil1_scale_intensities.h>
00013 #include <vil1/vil1_save.h>
00014 #include <vnl/vnl_double_2.h>
00015 #include <vgui/vgui.h>
00016 #include <vgui/vgui_dialog.h>
00017 #include <vgui/vgui_image_tableau.h>
00018 #include <vgui/vgui_viewer2D_tableau.h>
00019 #include <vgui/vgui_easy2D_tableau.h>
00020 #include <vgui/vgui_soview2D.h>
00021 #include <vgui/vgui_grid_tableau.h>
00022 #include <vgui/vgui_shell_tableau.h>
00023 #include <vsrl/vsrl_stereo_dense_matcher.h>
00024 #include <sdet/sdet_region_proc_params.h>
00025 #include <sdet/sdet_region_proc.h>
00026 #include <vdgl/vdgl_digital_curve.h>
00027 #include <vdgl/vdgl_interpolator.h>
00028 #include <vdgl/vdgl_edgel_chain.h>
00029 #include <vtol/vtol_vertex_2d.h>
00030 #include <vtol/vtol_vertex_2d_sptr.h>
00031 #include <vtol/vtol_vertex.h>
00032 #include <vtol/vtol_edge_2d.h>
00033 #include <vtol/vtol_edge_2d_sptr.h>
00034 #include <vtol/vtol_intensity_face.h>
00035 #include <vepl/vepl_gradient_mag.h>
00036 #include <vepl/vepl_gaussian_convolution.h>
00037 #include <vepl/vepl_threshold.h>
00038 #include <vsrl/vsrl_point_picker.h>
00039 #include <vsrl/vsrl_results_dense_matcher.h>
00040 #include <vsrl/vsrl_3d_output.h>
00041 #include <vsrl/vsrl_region_disparity.h>
00042 #include <vsrl/vsrl_image_correlation.h>
00043 #include <vgel/vgel_multi_view_data.h>
00044 #include <vgel/vgel_multi_view_data_vertex_sptr.h>
00045 #include <vgel/vgel_kl.h>
00046 #include <vgl/vgl_point_2d.h>
00047 #include <vgl/vgl_point_3d.h>
00048 #include <rsdl/rsdl_point.h>
00049 #include <rsdl/rsdl_kd_tree.h>
00050 #if 0
00051 #ifdef INCLUDE_JSEG
00052 extern "C"
00053 {
00054 #include <jseg/jseg.h>
00055 }
00056 #endif
00057 #endif
00058 // static manager instance
00059 vsrl_manager* vsrl_manager::instance_=0;
00060 
00061 //ensure only one instance is created
00062 vsrl_manager *vsrl_manager::instance()
00063 {
00064   if (!instance_)
00065   {
00066     instance_ = new vsrl_manager();
00067     instance_->init();
00068   }
00069   return vsrl_manager::instance_;
00070 }
00071 
00072 vsrl_manager::vsrl_manager():vgui_wrapper_tableau(){}
00073 
00074 vsrl_manager::~vsrl_manager(){}
00075 
00076 void vsrl_manager::init()
00077 {
00078   shadow_mean_ = 50.0;
00079   shadows_only_ = true;
00080   shadow_metric_ = NULL;
00081   // Load the image tableaux
00082   itabL_ = vgui_image_tableau_new();
00083   itabR_ = vgui_image_tableau_new();
00084   dimg_tab_ = vgui_image_tableau_new();  // disparity image tableau
00085   disparity_bias_=0;
00086 
00087   // Put the image tableaux into an easy2D tableau
00088   e2d0_ = vgui_easy2D_tableau_new(itabL_);
00089   e2d1_ = vgui_easy2D_tableau_new(itabR_);
00090   e2d2_ = vgui_easy2D_tableau_new(dimg_tab_);
00091 
00092   // Set up characteristics of points to be drawn
00093   e2d0_->set_foreground(1,0,0);
00094   e2d1_->set_foreground(1,0,0);
00095   e2d2_->set_foreground(1,0,0);
00096   e2d0_->set_point_radius(5);
00097   e2d1_->set_point_radius(5);
00098   e2d2_->set_point_radius(5);
00099   e2d0_->set_line_width(2);
00100   e2d1_->set_line_width(2);
00101   e2d2_->set_line_width(2);
00102 
00103   // Put the easy2D tableaux into the viewers
00104   vgui_viewer2D_tableau_sptr viewer0 = vgui_viewer2D_tableau_new(e2d0_);
00105   vgui_viewer2D_tableau_sptr viewer1 = vgui_viewer2D_tableau_new(e2d1_);
00106   vgui_viewer2D_tableau_sptr viewer2 = vgui_viewer2D_tableau_new(e2d2_);
00107 
00108   // Put the viewers into tableaux for picking points
00109   vpicker0_=new vsrl_point_picker(viewer0);
00110   vpicker1_=new vsrl_point_picker(viewer1);
00111   vpicker2_=new vsrl_point_picker(viewer2);
00112 
00113   //Put the viewers into a grid
00114   grid_ = new vgui_grid_tableau(3,1);
00115   grid_->add_at(vpicker0_, 0,0);
00116   grid_->add_at(vpicker1_, 1,0);
00117   grid_->add_at(vpicker2_, 2,0);
00118   grid_->set_selected(0,0);
00119   grid_->set_uses_paging_events(false); // disable paging
00120   grid_->set_grid_size_changeable(false); // disable adding panes
00121 
00122   // Put the grid into a shell tableau at the top the hierarchy
00123   vgui_shell_tableau_new shell(grid_);
00124 
00125   // Get a parameters object
00126   params_ = vsrl_parameters::instance();
00127 
00128   this->add_child(shell);
00129 }
00130 
00131 void vsrl_manager::quit()
00132 {
00133   vcl_exit(1);
00134 }
00135 
00136 void vsrl_manager::load_left_image()
00137 {
00138   vgui_dialog load_image_dlg("Load Image file");
00139   static vcl_string image_filename = "";
00140   static vcl_string ext = "*.*";
00141   load_image_dlg.file("Image Filename:", ext, image_filename);
00142   if (!load_image_dlg.ask()) return;
00143   imgL_ = vil1_load(image_filename.c_str());
00144   itabL_->set_image(imgL_);
00145   this->post_redraw();
00146   return;
00147 }
00148 
00149 void vsrl_manager::load_right_image()
00150 {
00151   vgui_dialog load_image_dlg("Load Image file");
00152   static vcl_string image_filename = "";
00153   static vcl_string ext = "*.*";
00154   load_image_dlg.file("Image Filename:", ext, image_filename);
00155   if (!load_image_dlg.ask()) return;
00156   imgR_ = vil1_load(image_filename.c_str());
00157   itabR_->set_image(imgR_);
00158   this->post_redraw();
00159   return;
00160 }
00161 
00162 void vsrl_manager::load_disparity_image()
00163 {
00164   vgui_dialog load_image_dlg("Load Disparity Image file");
00165   static vcl_string image_filename = "";
00166   static vcl_string ext = "*.*";
00167   load_image_dlg.file("Disparity Image Filename:", ext, image_filename);
00168   if (!load_image_dlg.ask()) return;
00169   disp_img_ = vil1_load(image_filename.c_str());
00170   vil1_memory_image_of<unsigned char> real_image(disp_img_);
00171 
00172   vil1_image scaled_image = scale_image(real_image);
00173 
00174   // Display the scaled image
00175   dimg_tab_->set_image(scaled_image);
00176   this->post_redraw();
00177 }
00178 
00179 void vsrl_manager::save_disparity_image()
00180 {
00181   vgui_dialog save_image_dlg("Save Disparity Image file");
00182   static vcl_string image_filename = "";
00183   static vcl_string ext = "*.tif";
00184   save_image_dlg.file("Disparity Image Filename", ext, image_filename);
00185   if (!save_image_dlg.ask()) return;
00186   vil1_memory_image_of<unsigned char> disp(disp_img_);
00187   if (!vil1_save(disp,image_filename.c_str())) {
00188     vcl_cout << "Error saving disparity image!\n";
00189   }
00190   return;
00191 }
00192 
00193 void vsrl_manager::load_params_file()
00194 {
00195   //
00196   vgui_dialog load_params_dlg("Load Dense Matcher Parameters file");
00197   static vcl_string params_filename = "";
00198   static vcl_string ext = "*.*";
00199   load_params_dlg.file("Dense Matcher Parameter Filename:", ext, params_filename);
00200   if (!load_params_dlg.ask()) return;
00201   params_->load(params_filename.c_str()); // load the parameters file
00202   disparity_bias_ = params_->correlation_range;
00203 }
00204 
00205 void vsrl_manager::point_pick()
00206 {
00207   vcl_cerr << "vsrl_manager::point_pick() not yet implemented\n";
00208   return;
00209 }
00210 
00211 void vsrl_manager::clear_all()
00212 {
00213   e2d0_->clear();
00214   e2d1_->clear();
00215   e2d2_->clear();
00216   this->post_redraw();
00217   return;
00218 }
00219 
00220 bool vsrl_manager::handle(vgui_event const & event)
00221 {
00222   this->child.handle(event);
00223 
00224   if (event.type == vgui_BUTTON_DOWN &&
00225       event.button == vgui_LEFT &&
00226       !event.modifier)
00227     {
00228       put_points();
00229     }
00230   else if (event.type == vgui_BUTTON_DOWN &&
00231            event.button == vgui_LEFT &&
00232            event.modifier == vgui_SHIFT)
00233     {
00234       put_lines();
00235     }
00236   else if (event.type == vgui_BUTTON_DOWN &&
00237            event.button == vgui_MIDDLE &&
00238            event.modifier == vgui_SHIFT)
00239     {
00240       vgl_point_2d<float>  pos = vpicker0_->get_point();  // get the last point picked
00241       vcl_cout << "handle: pos = " << pos << vcl_endl;
00242       int x = int(pos.x()); int y = int(pos.y()); // convert to int.
00243       show_correlations(x,y);
00244     }
00245   return true;
00246 }
00247 
00248 bool vsrl_manager::validate_point(vgl_point_2d<float> const& pt)
00249 {
00250   if (pt.x() < 0 ||
00251       pt.y() < 0 ||
00252       pt.x() >= disp_img_.cols() ||
00253       pt.y() >= disp_img_.rows() )
00254     {
00255       vcl_cout << "Error: point out of range of disparity image.\n";
00256       return false;
00257     }
00258   else
00259     return true;
00260 }
00261 
00262 int vsrl_manager::get_disparity(vgl_point_2d<float> const& pt)
00263 {
00264   vil1_memory_image_of<unsigned char> disp(disp_img_);
00265   int pixel_val = disp(int(pt.x()),int(pt.y()));
00266   if (pixel_val > 0) {
00267     // we subtract the disparity bias, plus 1 for the indexing offset
00268     //    pixel_val -= (disparity_bias_ + 1);
00269     pixel_val -= (params_->correlation_range + 1);
00270     vcl_cout << "Disparity: " << pixel_val << vcl_endl;
00271   }
00272   return pixel_val;
00273 }
00274 
00275 bool vsrl_manager::put_points()
00276 {
00277   unsigned r=0, c=0;
00278   grid_->get_last_selected_position(&c, &r);
00279 
00280   // determine which grids to update
00281   vgl_point_2d<float> pos;
00282   // Point Picked in Left Pane
00283   if (c==0)
00284   {
00285     pos = vpicker0_->get_point();  // get the last point picked
00286     vcl_cout << "put_points: pos = " << pos << vcl_endl;
00287     if (!validate_point(pos)) return true;
00288     int disp = get_disparity(pos);
00289     vpicker1_->put_point(pos.x()+disp,pos.y());
00290     vpicker2_->put_point(pos.x(),     pos.y());
00291   }
00292   // Point Picked in Right Pane
00293   if (c==1)
00294   {
00295     pos = vpicker1_->get_point();  // get the last point picked
00296     if (!validate_point(pos)) return true;
00297     int disp = get_disparity(pos);
00298     vpicker0_->put_point(pos.x()-disp,pos.y());
00299     vpicker2_->put_point(pos.x(),     pos.y());
00300   }
00301   // Point Picked in Disparity Pane
00302   if (c==2)
00303   {
00304     pos = vpicker2_->get_point();  // get the last point picked
00305     if (!validate_point(pos)) return true;
00306     int disp = get_disparity(pos);
00307     vpicker0_->put_point(pos.x(),     pos.y());
00308     vpicker1_->put_point(pos.x()+disp,pos.y());
00309   }
00310   this->post_redraw();
00311   return true;
00312 }
00313 
00314 bool vsrl_manager::put_lines()
00315 {
00316   unsigned r=0, c=0;
00317   grid_->get_last_selected_position(&c, &r);
00318 
00319   // determine which grids to update
00320   vgl_point_2d<float> pos;
00321   // Point Picked in Left Pane
00322   if (c==0)
00323   {
00324     pos = vpicker0_->get_point();  // get the last point picked
00325     vpicker1_->put_H_line(pos.x(),pos.y());
00326     vpicker2_->put_H_line(pos.x(),pos.y());
00327   }
00328   // Point Picked in Right Pane
00329   if (c==1)
00330   {
00331     pos = vpicker1_->get_point();  // get the last point picked
00332     vpicker0_->put_H_line(pos.x(),pos.y());
00333     vpicker2_->put_H_line(pos.x(),pos.y());
00334   }
00335   // Point Picked in Disparity Pane
00336   if (c==2)
00337   {
00338     pos = vpicker2_->get_point();  // get the last point picked
00339     vpicker0_->put_H_line(pos.x(),pos.y());
00340     vpicker1_->put_H_line(pos.x(),pos.y());
00341   }
00342   this->post_redraw();
00343   return true;
00344 }
00345 
00346 bool vsrl_manager::do_dense_matching()
00347 {
00348   if (!imgL_ || !imgR_) return false;
00349 
00350   static float sig = 1.0f;
00351   static float cutoff = 0.01f;
00352   static bool smoothing = false;
00353   vgui_dialog gs_dialog("Gaussian Smoothing");
00354   gs_dialog.field("Sigma:",sig);
00355   gs_dialog.field("Cutoff:",cutoff);
00356   gs_dialog.checkbox("Perform Gaussian Smoothing",smoothing);
00357   if (!gs_dialog.ask()) return false;
00358 
00359   // If desired, we can do Gaussian smoothing.  This can be handy for
00360   // badly interlaced images.
00361   if (smoothing) {
00362     vil1_image left = vepl_gaussian_convolution(imgL_,sig,cutoff);
00363     vil1_image right = vepl_gaussian_convolution(imgR_,sig,cutoff);
00364     imgL_=left;
00365     imgR_=right;
00366   }
00367 
00368   itabL_->set_image(imgL_);
00369   itabR_->set_image(imgR_);
00370 
00371   // The parameters used will be the default parameters or
00372   // the parameters loaded manually from a file.
00373   // Now create a dense matcher with the images that are loaded.
00374   vcl_cout << "Begin Stereo Dense Matcher...";
00375   vsrl_stereo_dense_matcher matcher(imgL_,imgR_);
00376   vcl_cout << "Setting Correlation Range...";
00377   matcher.set_correlation_range(params_->correlation_range);
00378   vcl_cout << "Running Dense Matcher.\n";
00379   // Run the dense matcher.
00380   matcher.execute();
00381 
00382   // Get & display the disparity image
00383   // Get a buffer the size of the left image
00384   vil1_memory_image_of<unsigned char> buffer(imgL_.cols(),imgL_.rows());
00385   // Zero out the buffer
00386   for (int x=0;x<buffer.width();x++)
00387     for (int y=0;y<buffer.height();y++)
00388       buffer(x,y)=0;
00389   // Get the disparities into the buffer
00390   for (int y=0;y<buffer.height();y++) {
00391     for (int x=0;x<buffer.width();x++) {
00392       int disparity = matcher.get_disparity(x,y);
00393       int value = disparity + params_->correlation_range+1;
00394       if (value < 0)
00395         value = 0;
00396       if (value>2*params_->correlation_range+1)
00397         value=0;
00398       buffer(x,y)=static_cast<unsigned char>(value);
00399     }
00400   }
00401 
00402   // Display the disparity image
00403   disp_img_ = buffer;
00404   vil1_image scaled_image = scale_image(buffer);
00405   dimg_tab_->set_image(scaled_image);
00406 
00407   vcl_cout << "Dense Matcher complete.\n";
00408   this->post_redraw();
00409   return true;
00410 }
00411 
00412 vil1_image vsrl_manager::scale_image(vil1_memory_image_of<unsigned char> img)
00413 {
00414   double maxval = 0;
00415   double minval = 1e15;
00416   for (int x=0;x<img.width();x++) {
00417     for (int y=0;y<img.height();y++) {
00418       if (img(x,y) > maxval) {
00419         maxval = img(x,y);
00420       }
00421       if (img(x,y) < minval) {
00422         minval = img(x,y);
00423       }
00424     }
00425   }
00426   vcl_cout << "vsrl_manager::scale_image<unsigned char> - Max = " << maxval
00427            << ", Min = " << minval << vcl_endl;
00428 
00429   double scale = 255.0/maxval;
00430   double shift = 0;
00431   vil1_image scaled_image = vil1_scale_intensities(img, scale, shift);
00432   return scaled_image;
00433 }
00434 
00435 vil1_image vsrl_manager::scale_image(vil1_memory_image_of<double> img)
00436 {
00437   double maxval = 0;
00438   double minval = 1e15;
00439   for (int x=0;x<img.width();x++) {
00440     for (int y=0;y<img.height();y++) {
00441       if (img(x,y) > maxval) {
00442         maxval = img(x,y);
00443       }
00444       if (img(x,y) < minval) {
00445         minval = img(x,y);
00446       }
00447     }
00448   }
00449   vcl_cout << "vsrl_manager::scale_image<double> - Max = " << maxval
00450            << ", Min = " << minval << vcl_endl;
00451 
00452   double scale = 255.0/maxval;
00453   double shift = 0;
00454   vil1_image scaled_image = vil1_scale_intensities(img, scale, shift);
00455   return scaled_image;
00456 }
00457 
00458 void vsrl_manager::find_regions()
00459 {
00460   this->clear_all();
00461   static bool debug = false;
00462   static bool agr = true;
00463   static bool residual = false;
00464   static sdet_detector_params dp;
00465   vgui_dialog region_dialog("Edgel Regions");
00466   region_dialog.field("Gaussian sigma", dp.smooth);
00467   region_dialog.field("Noise Threshold", dp.noise_multiplier);
00468   region_dialog.checkbox("Automatic Threshold", dp.automatic_threshold);
00469   region_dialog.checkbox("Agressive Closure", agr);
00470   region_dialog.checkbox("Compute Junctions", dp.junctionp);
00471   region_dialog.checkbox("Debug", debug);
00472   region_dialog.checkbox("Residual Image", residual);
00473   region_dialog.field("Shadow Mean Intensity Threshold", shadow_mean_);
00474   region_dialog.checkbox("Display Only Shadow Regions", shadows_only_);
00475   if (!region_dialog.ask())
00476     return;
00477   if (agr)
00478     dp.aggressive_junction_closure=1;
00479   else
00480     dp.aggressive_junction_closure=0;
00481 
00482   sdet_region_proc_params rpp(dp, true, debug, 2);
00483   sdet_region_proc rp(rpp);
00484   rp.set_image(imgL_);
00485   rp.extract_regions();
00486   if (debug)
00487   {
00488     vil1_image ed_img = rp.get_edge_image();
00489     vgui_image_tableau_sptr itab =  e2d0_->get_image_tableau();
00490     if (!itab)
00491     {
00492       vcl_cout << "In segv_segmentation_manager::regions() - null image tableau\n";
00493       return;
00494     }
00495     itab->set_image(ed_img);
00496   }
00497   if (!debug)
00498   {
00499     vcl_vector<vtol_intensity_face_sptr>& regions = rp.get_regions();
00500     this->find_shadows(regions);
00501     this->draw_regions(regions, true);
00502   }
00503   if (residual)
00504   {
00505     vil1_image res_img = rp.get_residual_image();
00506     vgui_image_tableau_sptr itab =  e2d0_->get_image_tableau();
00507     if (!itab)
00508     {
00509       vcl_cout << "In segv_segmentation_manager::regions() - null image tableau\n";
00510       return;
00511     }
00512     itab->set_image(res_img);
00513   }
00514 }
00515 
00516 void vsrl_manager::draw_regions(vcl_vector<vtol_intensity_face_sptr>& regions,
00517                                 bool verts)
00518 {
00519   // This segment of code is ripped from various places in brl...bgui.
00520 
00521   for (vcl_vector<vtol_intensity_face_sptr>::iterator rit = regions.begin();
00522        rit != regions.end(); rit++)
00523   {
00524     vtol_face_2d_sptr f = (*rit)->cast_to_face_2d();
00525     edge_list edges; f->edges(edges);
00526 
00527     vgui_soview2D_group* vsovg = new vgui_soview2D_group();
00528 
00529     for (edge_list::iterator eit = edges.begin(); eit != edges.end(); eit++)
00530     {
00531       vtol_edge_2d_sptr e = (*eit)->cast_to_edge_2d();
00532 
00533       vgui_soview2D_linestrip* e_line = new vgui_soview2D_linestrip();
00534 
00535       vsol_curve_2d_sptr c = e->curve();
00536 
00537       if (!c) {
00538         vcl_cout << "vsrl_manager::draw_regions - null curve.\n";
00539         return;
00540       }
00541       if (c->cast_to_vdgl_digital_curve())
00542       {
00543         vdgl_digital_curve_sptr dc = c->cast_to_vdgl_digital_curve();
00544         //get the edgel chain
00545         vdgl_interpolator_sptr itrp = dc->get_interpolator();
00546         vdgl_edgel_chain_sptr ech = itrp->get_edgel_chain();
00547 
00548         //n, x, and y are in the parent class vgui_soview2D_linestrip
00549         e_line->n = ech->size();
00550         //offset the coordinates for display (may not be needed)
00551         e_line->x = new float[e_line->n], e_line->y = new float[e_line->n];
00552         for (unsigned int i=0; i<e_line->n;i++)
00553         {
00554           vdgl_edgel ed = (*ech)[i];
00555           e_line->x[i] = (float)ed.get_x();
00556           e_line->y[i] = (float)ed.get_y();
00557         }
00558       }
00559       else
00560         vcl_cout << "vsrl_manager::draw_regions - attempt to draw an edge with unknown curve geometry\n";
00561 
00562       vsovg->ls.push_back(e_line);
00563     }
00564 
00565     e2d0_->add(vsovg);
00566 
00567     if (verts)
00568     {
00569       vertex_list vts; f->vertices(vts);
00570       for (vcl_vector<vtol_vertex_sptr>::iterator vit = vts.begin();
00571            vit != vts.end(); vit++)
00572       {
00573         vtol_vertex_2d_sptr v = (*vit)->cast_to_vertex_2d();
00574         e2d0_->add_point(static_cast<float>(v->x()),static_cast<float>(v->y()));
00575       }
00576     }
00577   }
00578 }
00579 
00580 void
00581 vsrl_manager::set_params()
00582 {
00583   // establish the variables.  Should already have instantiated params_
00584   int corr_range=params_->correlation_range;
00585   double inner_cost=params_->inner_cost;
00586   double outer_cost=params_->outer_cost;
00587   double continuity_cost=params_->continuity_cost;
00588   int correlation_window_width=params_->correlation_window_width;
00589   int correlation_window_height=params_->correlation_window_height;
00590   double bias_cost=params_->bias_cost;
00591   double common_intensity_diff=params_->common_intensity_diff;
00592 
00593   vgui_dialog params_dialog("Dense Matcher Parameters");
00594   params_dialog.field("Correlation Range:", corr_range);
00595   params_dialog.field("Inner Cost:", inner_cost);
00596   params_dialog.field("Outer Cost:", outer_cost);
00597   params_dialog.field("Continuity Cost:",continuity_cost);
00598   params_dialog.field("Correlation Window Width:", correlation_window_width);
00599   params_dialog.field("Correlation Window Height:", correlation_window_height);
00600   params_dialog.field("Bias Cost:",bias_cost);
00601   params_dialog.field("Common Intensity Difference:",common_intensity_diff);
00602   if (!params_dialog.ask()) {
00603     return;
00604   }
00605   else {
00606     params_->correlation_range = corr_range;
00607     params_->inner_cost = inner_cost;
00608     params_->outer_cost = outer_cost;
00609     params_->continuity_cost = continuity_cost;
00610     params_->correlation_window_width = correlation_window_width;
00611     params_->correlation_window_height = correlation_window_height;
00612     params_->bias_cost = bias_cost;
00613     params_->common_intensity_diff = common_intensity_diff;
00614   }
00615   return;
00616 }
00617 
00618 void vsrl_manager::draw_north_arrow()
00619 {
00620   // use a vector of length 10 for the north arrow
00621   north_.set(0.0,10.0);
00622 
00623   // (0,0) is the origin for the north vector
00624   /* vgui_soview2D_lineseg* line = */ draw_vector_at(&north_, 0.0f, 0.0f, 0.0);
00625 
00626   this->post_redraw();
00627   return;
00628 }
00629 
00630 //
00631 // Draw the given vector at the specified point with the specified rotation.
00632 // (x,y) = where to draw the vector
00633 // theta = the angle through which the vector is rotated before drawing.
00634 //
00635 vgui_soview2D_lineseg*
00636 vsrl_manager::draw_vector_at(vgl_vector_2d<float>* vec, float x, float y, float theta)
00637 {
00638   // make the vector green
00639   e2d0_->set_foreground(0,1,0);
00640 
00641   // Apply rotation to get rot_vec
00642   vgl_vector_2d<float> rot_vec;
00643   rot_vec.x_ =  vec->x() * vcl_cos(theta) + vec->y() * vcl_sin(theta);
00644   rot_vec.y_ = -vec->x() * vcl_sin(theta) + vec->y() * vcl_cos(theta);
00645 
00646   // Apply translation
00647   float endx = rot_vec.x()+x;
00648   float endy = rot_vec.y()+y;
00649 
00650   // Create the lineseg & draw it
00651   vgui_soview2D_lineseg* vector = new vgui_soview2D_lineseg(x,y,endx,endy);
00652   e2d0_->add(vector);
00653 
00654   e2d0_->set_foreground(1,0,0);
00655   this->post_redraw();
00656   return vector;
00657 }
00658 
00659 // Calculate & Display Image Gradient magnitudes
00660 //
00661 vil1_image
00662 vsrl_manager::show_gradient_mag(vil1_image* im_in)
00663 {
00664   vil1_image im_out = vepl_gradient_mag(*im_in);
00665   disp_img_ = im_out;  // this line lets us save out the image
00666   //  vil1_image scaled_image = scale_image(im_out);
00667   dimg_tab_->set_image(im_out);
00668   this->post_redraw();
00669   return im_out;
00670 }
00671 
00672 // Calculate & Display Image Gradient directions
00673 //
00674 vil1_image
00675 vsrl_manager::show_gradient_dir(vil1_memory_image_of<double> im_in)
00676 {
00677   // calculate the gradient
00678   // I prefer to implement my own gradient operation because I want to handle the edges
00679   // more carefully and I want better control of what happens at inflection points of ATAN2.
00680   // The scale (40) and offset (128) keep the range of the ATAN2 function within the range of
00681   // the <unsigned char> image.
00682   vcl_cout << "vsrl_manager::show_gradient_dir() - Begin\n";
00683 
00684   vil1_memory_image_of<double> im_out(im_in.width(),im_in.height());
00685 
00686   const double shift=128;
00687   const double scale=40; // actually: 127/pi
00688   register double dx, dy;
00689   for (int x=0; x<im_out.width(); x++) {
00690     for (int y=0; y<im_out.height(); y++) {
00691       if (x==0) {
00692         dx = im_in(x+1,y) - im_in(x,y); // image edge
00693       }
00694       else {
00695         dx = im_in(x,y) - im_in(x-1,y);
00696       }
00697       if (y==0) {
00698         dy = im_in(x,y+1) - im_in(x,y); // image edge
00699       }
00700       else {
00701         dy = im_in(x,y) - im_in(x,y-1);
00702       }
00703       im_out(x,y) = vcl_atan2(dy,dx) * scale + shift;
00704     }
00705   }
00706 
00707   vil1_image scaled_image = scale_image(im_out);
00708   dimg_tab_->set_image(scaled_image);
00709   this->post_redraw();
00710   vcl_cout << "vsrl_manager::show_gradient_dir() - End\n";
00711   return im_out;
00712 }
00713 
00714 // Generic function called by menu to make testing easier
00715 void
00716 vsrl_manager::test_left_func()
00717 {
00718   this->occlusion_map();
00719   this->post_redraw();
00720   return;
00721 }
00722 
00723 // Generic function called by menu to make testing easier
00724 void
00725 vsrl_manager::test_right_func()
00726 {
00727   // get the regions from jseg algorithm
00728   //  vcl_vector<vdgl_digital_region*> regions = run_jseg(imgR_);
00729   //  find_shadows(regions);
00730   //  this->post_redraw();
00731   this->region_disparity();
00732   return;
00733 }
00734 
00735 // Generate 3D output & display range image
00736 vil1_memory_image_of<double>
00737 vsrl_manager::make_3d()
00738 {
00739   // set up the dense matcher
00740   if (!disp_img_ || !imgL_ || !imgR_) {
00741     vil1_memory_image_of<double> null_image;
00742     return null_image; // Sanity check.
00743   }
00744   vsrl_results_dense_matcher matcher(imgL_,disp_img_);
00745   matcher.set_correlation_range(params_->correlation_range);
00746   vsrl_3d_output output(imgL_,imgR_);
00747   output.set_matcher(&matcher);
00748   //  Write the 3D output & triangles to out.dat
00749   output.write_output("out.dat");
00750   vil1_image scaled_image = scale_image(output.range_image_);
00751   itabR_->set_image(scaled_image);  // put the image in the viewer
00752   this->post_redraw();
00753   return output.range_image_;
00754 }
00755 
00756 // Make a vector of digital regions and pass the problem to
00757 // find_shadows(vcl_vector<vdgl_digital_region*>) below.
00758 //
00759 void vsrl_manager::find_shadows(vcl_vector<vtol_intensity_face_sptr>& faces)
00760 {
00761   vcl_vector<vdgl_digital_region*> reg_vec;
00762 
00763   for (vcl_vector<vtol_intensity_face_sptr>::iterator fit = faces.begin();
00764        fit != faces.end(); fit++) {
00765     vdgl_digital_region* reg = (*fit)->cast_to_digital_region();
00766     reg_vec.push_back(reg);
00767   }
00768   find_shadows(reg_vec);
00769   return;
00770 }
00771 
00772 //: This algorithm taken pretty much verbatim from the DDB/RegionSaliency class.
00773 //  Repeated here for digital regions instead of intensity faces...
00774 //
00775 
00776 void vsrl_manager::find_shadows(vcl_vector<vdgl_digital_region*> regions)
00777 {
00778   // Create an array to hold shadow metric
00779   // (First get rid of anything there already)
00780   if (shadow_metric_ != NULL) delete shadow_metric_;
00781   shadow_metric_ = new vcl_vector<float>(regions.size());
00782 
00783   e2d1_->set_foreground(0,0,1);
00784   e2d1_->set_point_radius(5);
00785 
00786   int i=0;
00787   vcl_vector<float>::iterator sm = shadow_metric_->begin();
00788   vcl_cout << "Shadow Threshold: " << shadow_mean_ << vcl_endl;
00789 
00790   for (vcl_vector<vdgl_digital_region*>::iterator rit = regions.begin();
00791        rit != regions.end(); ++rit,++i,++sm)
00792   {
00793     if ((*rit)->Npix() > 0)
00794     {
00795       (*rit)->ComputeIntensityStdev();
00796       vcl_cout << "Intensity Face: " << i << "  Io = " << (*rit)->Io()
00797                << "  I_stdev = " << (*rit)->Io_sd();
00798       if ((*rit)->Io() == 0)
00799         *sm=0.0;
00800       else if ((*rit)->Io() < shadow_mean_)
00801         *sm=1.0;
00802       else
00803       {
00804         // This segment of code is taken from the HistEntropy class
00805         // in TargetJr, GeneralUtility/Basics.  It is used to mimic
00806         // the operation of the shadow detection used in the DDB
00807         // RegionSaliency class.
00808 
00809         float m1=(*rit)->Io(); // Get the region mean
00810         float v1=(*rit)->Io_sd(); // Get the region Stdev.
00811 
00812         // Later we can adjust the shadow reference parameters.
00813 
00814         // For now, this is what we'll use...
00815         float m2 = shadow_mean_; // m2 is the reference shadow mean.
00816         float v2 = 1.0f; // v2 is the reference shadow stdev.
00817 
00818         if (m1==0 || m2==0)
00819           *sm=0.0;
00820         else if ( v1 < 1e-6 || v2 < 1e-6 )
00821           *sm=0.0;
00822         else
00823           *sm = (float)vcl_exp(- vcl_fabs(0.693 * (m1-m2) * vcl_sqrt(1.0/(v1*v1) + 1.0/(v2*v2))));
00824       }
00825       vcl_cout << "  Shadow = " << *sm << vcl_endl;
00826     }
00827 
00828     if (*sm ==1)
00829       e2d1_->add_point((*rit)->Xo(),(*rit)->Yo());
00830   }
00831   e2d1_->set_foreground(1,0,0);
00832   e2d1_->set_point_radius(5);
00833 }
00834 
00835 // Though called "run_jseg" this routine does more than that.  After the jseg routine
00836 // executes, the output of jseg is partitioned into digital_regions and a vector of
00837 // the resulting digital regions is returned.
00838 #if 0
00839 vcl_vector<vdgl_digital_region*>
00840 vsrl_manager::run_jseg(vil1_image image_in)
00841 {
00842 #ifndef INCLUDE_JSEG
00843   vcl_cout << "vsrl_manager::run_jseg - Error. JSEG not included in this compilation.\n";
00844   vcl_vector<vdgl_digital_region*> empty;
00845   return empty;
00846 #else
00847   // Set up the JSEG parameters
00848   static float TQUAN=-1.0f;
00849   static int NSCALE=-1;
00850   static float threshcolor=-1.0f;
00851   vgui_dialog jseg_dialog("JSEG Parameters");
00852   jseg_dialog.field("Color Quantization Threshold (-1=automatic): ",TQUAN);
00853   jseg_dialog.field("Number of Scales (-1=automatic): ",NSCALE);
00854   jseg_dialog.field("Region Merge Threshold (-1=automatic): ",threshcolor);
00855   jseg_dialog.field("Shadow Mean Intensity Threshold: ", shadow_mean_);
00856   if (!jseg_dialog.ask()) return NULL;
00857 
00858   // Get the image for segmentation
00859   vil1_memory_image_of<unsigned char> im(image_in);
00860   unsigned char* cp = im.get_buffer();
00861   int nx = im.cols();
00862   int ny = im.rows();
00863   int dim = 1; // grayscale image
00864 
00865   // Run JSEG
00866   unsigned char* js_img = jseg(cp,dim,nx,ny,TQUAN,NSCALE,threshcolor);
00867   vil1_memory_image_of<unsigned char>* js_out = new vil1_memory_image_of<unsigned char>(js_img,nx,ny);
00868 
00869   // Now we have an "image" of the regions.  We need to sort it into
00870   // vdgl_digital_regions. We'll hold the regions in a vector.
00871 
00872   vcl_vector<vdgl_digital_region*> reg_vec;
00873 
00874   int reg_cntr = 0;  // A counter for regions
00875 
00876   // Initialize things with one region
00877   // We'll use a 3D region and use the Z coord. for the class label.
00878   vcl_cout << "Creating initial region.  #0\n";
00879   vdgl_digital_region* region1 = new vdgl_digital_region();
00880 
00881   // vdgl_digital_region(x,y,z,pix)
00882   // x & y are pixel coords. z is class label. pix=Intensity value of orignal image pixel.
00883   region1->IncrementMeans(0,0,(*js_out)(0,0),im(0,0));
00884   reg_vec.push_back(region1);  // Add the region to the vector.
00885 
00886   // Loop through all the image pixels, assigning them to regions
00887   // This pass only counts the pixels in regions and calculates their means.
00888   // Another pass is required later to actually assign inividual pixels to
00889   // their respective regions.
00890   // (See vdgl_digital_region::IncrementMeans(float,float,float,unsigned short)
00891   // for a description.
00892   for (int x=0;x<im.cols();x++) {
00893     for (int y=0;y<im.rows();y++) {
00894       if (x==0 && y==0) break; // we've already done pixel (0,0)
00895       unsigned char reg_num = (*js_out)(x,y); // get the region class number for this pixel
00896 
00897       // Now loop through the regions and see if we already have a region of
00898       // this class.
00899       bool found = false;  // use this flag to determine if we find a match
00900       for (vcl_vector<vdgl_digital_region*>::iterator rit = reg_vec.begin();
00901            rit<reg_vec.end();rit++){
00902         if (reg_num == (*rit)->Zo()) {
00903           // Found a matching region so put this pixel in the region
00904           (*rit)->IncrementMeans(x,y,reg_num,im(x,y));
00905           found = true;
00906           break; // When you find a match, don't keep looking, just quit.
00907         }
00908       }
00909       // We've gone through all the regions. If we didn't find a match
00910       // for this pixel, make a new region and insert it.
00911       if (!found) {
00912         reg_cntr++;
00913         vcl_cout << "Creating new region.  #" << reg_cntr << vcl_endl;
00914         vdgl_digital_region* new_region = new vdgl_digital_region();
00915         new_region->IncrementMeans(x,y,reg_num,im(x,y));
00916         reg_vec.push_back(new_region);
00917         found=false; //reset the flag
00918       }
00919     }
00920   }
00921   // Initialize the regions to accept pixels...
00922   for (vcl_vector<vdgl_digital_region*>::iterator rit = reg_vec.begin();
00923        rit<reg_vec.end();rit++){
00924     (*rit)->InitPixelArrays();
00925   }
00926   // Loop through all the image pixels again,
00927   for (int x=0;x<im.cols();x++) {
00928     for (int y=0;y<im.rows();y++) {
00929       unsigned char reg_num = (*js_out)(x,y); // get the region class number for this pixel
00930       // Now loop through the regions make pixel assignments
00931       for (vcl_vector<vdgl_digital_region*>::iterator rit = reg_vec.begin();
00932            rit<reg_vec.end();rit++){
00933         if (reg_num == (*rit)->Zo()) {
00934           // Found a matching region so put this pixel in the region
00935           (*rit)->InsertInPixelArrays(x,y,reg_num,im(x,y));
00936           break; // When you find a match, don't keep looking, just quit.
00937         }
00938       }
00939       // We've gone through all the regions. If we didn't find a match
00940       // for this pixel, make a new region and insert it.
00941     }
00942   }
00943   vcl_cout << "Finished Creating Regions.\n";
00944   // Overlay the regions on the original image
00945   if (image_in == imgL_){
00946     show_jseg_boundaries(js_out, e2d0_);
00947   }
00948   else if (image_in == imgR_) {
00949     show_jseg_boundaries(js_out, e2d1_);
00950   }
00951   // Scale & Display the results
00952   vil1_image scaled_image = scale_image(*js_out);
00953   disp_img_ = *js_out;
00954   dimg_tab_->set_image(scaled_image);
00955   this->post_redraw();
00956   return reg_vec;
00957 #endif
00958 }
00959 #endif
00960 // This routine just puts dotted lines (o.k. points) around the boundaries of the
00961 // regions in the jseg segmentation.
00962 void vsrl_manager::show_jseg_boundaries(vil1_memory_image_of<unsigned char>* jseg_out,
00963                                         vgui_easy2D_tableau_sptr tab)
00964 {
00965   if (tab == e2d0_) {
00966     e2d0_->set_foreground(1,0,0);
00967     e2d2_->set_foreground(1,0,0);
00968   }
00969   if (tab == e2d1_) {
00970     e2d1_->set_foreground(0,1,0);
00971     e2d2_->set_foreground(0,1,0);
00972   }
00973 
00974   vil1_memory_image_of<unsigned char> rimg(jseg_out->width(),jseg_out->height());
00975 
00976   tab->set_point_radius(1);
00977   e2d2_->set_point_radius(1);
00978   for (int x=0;x<jseg_out->cols()-1;x++) {
00979     for (int y=0;y<jseg_out->rows()-1;y++) {
00980       rimg(x,y) = 0;
00981       // Vertical Boundaries...
00982       if ( (*jseg_out)(x,y) != (*jseg_out)(x+1,y) ){
00983         tab->add_point(x+0.5f,y);
00984         e2d2_->add_point(x+0.5f,y);
00985         rimg(x,y) = 255;
00986       }
00987       // Horizontal Boundaries...
00988       if ( (*jseg_out)(x,y) != (*jseg_out)(x,y+1) ) {
00989         tab->add_point(x,y+0.5f);
00990         e2d2_->add_point(x,y+0.5f);
00991         rimg(x,y) = 255;
00992       }
00993     }
00994   }
00995   vcl_string fname="regions.tif";
00996   vil1_save(rimg,fname.c_str());
00997   this->post_redraw();
00998   e2d0_->set_foreground(1,0,0);
00999   e2d1_->set_foreground(1,0,0);
01000   e2d2_->set_foreground(1,0,0);
01001   tab->set_point_radius(5);
01002   e2d2_->set_point_radius(5);
01003 }
01004 
01005 // This routine is to display the results of the correlations used for dense matching
01006 //
01007 
01008 float* vsrl_manager::show_correlations(int x, int y)
01009 {
01010   // Don't try anything funny.
01011   if (!imgL_ || !imgR_) {
01012     vcl_cerr << "vsrl_manager::show_correlations() -> 2 images not loaded. Abort.\n";
01013     return NULL;
01014   }
01015 
01016   // Determine which grid pane was used...
01017   unsigned r=0, c=0;
01018   grid_->get_last_selected_position(&c,&r);
01019 
01020   // Make 'em pick the point in the left pane...
01021   if (c!=0) {
01022     vcl_cerr << "vsrl_manager::show_correlations() -> Please pick point in left pane.\n";
01023     return NULL;
01024   }
01025 
01026   // Setup the correlation parameters...
01027 
01028   vsrl_image_correlation corr(imgL_, imgR_);
01029   corr.set_window_width(params_->correlation_window_width);
01030   corr.set_window_height(params_->correlation_window_height);
01031   corr.set_correlation_range(params_->correlation_range);
01032 
01033   // Get the correlation value at the point(s) in question
01034   vgl_point_2d<float> pos;
01035   pos = vpicker0_->get_point();
01036   int range = params_->correlation_range;
01037   float* results = new float[(2*range)+1];
01038   vcl_cout << "Correlation results about point: " << x << ", " << y << vcl_endl
01039            << "X: Y: R:\n";
01040   for (int xo=-range; xo<=range; xo++) {
01041     results[xo+range] = (float)corr.get_correlation(x,y,(x+xo),y);
01042     vcl_cout << (x+xo) << "  " << y << "  " << results[xo+range] << vcl_endl;
01043   }
01044 
01045   e2d0_->add_point(pos.x(),pos.y());
01046   e2d1_->add_point(pos.x(),pos.y());
01047   e2d1_->add_line(pos.x()-range,pos.y(),pos.x()+range,pos.y());
01048 
01049   return results;
01050 }
01051 
01052 void vsrl_manager::raw_correlation()
01053 {
01054   if (!imgL_ || !imgR_) return;
01055 
01056   // Gaussian Smoothing (if needed)...
01057   static float sig = 1.0f;
01058   static float cutoff = 0.01f;
01059   static bool smoothing = false;
01060   vgui_dialog gs_dialog("Gaussian Smoothing");
01061   gs_dialog.field("Sigma:",sig);
01062   gs_dialog.field("Cutoff:",cutoff);
01063   gs_dialog.checkbox("Perform Gaussian Smoothing",smoothing);
01064   if (!gs_dialog.ask()) return;
01065   if (smoothing) {
01066     vil1_image left = vepl_gaussian_convolution(imgL_,sig,cutoff);
01067     vil1_image right = vepl_gaussian_convolution(imgR_,sig,cutoff);
01068     imgL_=left;
01069     imgR_=right;
01070   }
01071   itabL_->set_image(imgL_);
01072   itabR_->set_image(imgR_);
01073 
01074   // Set up for doing the correlations...
01075   vsrl_image_correlation i_corr(imgL_,imgR_ );
01076   i_corr.set_correlation_range(params_->correlation_range);
01077   i_corr.set_window_width(params_->correlation_window_width);
01078   i_corr.set_window_height(params_->correlation_window_height);
01079 
01080   // Get an appropriately sized image buffer into which to write results...
01081   vil1_memory_image_of<unsigned char> disp(imgL_.width(),imgL_.height());
01082 
01083   int range = params_->correlation_range;
01084   for (int y=0; y<imgL_.rows(); y++) {
01085     vcl_cout << "Row: " << y << vcl_endl;
01086     for (int x=0; x<imgL_.cols(); x++) {
01087       float max=-1e10f;
01088       // when the disparities are written to the buffer, they are offset by "range"
01089       // to keep them positive.
01090       disp(x,y) = static_cast<unsigned char>(range); // default value (i.e. disparity=0+offset)
01091       for (int i=-range; i<=range;i++) {
01092         // get the values of the correlation of the pixel in the left
01093         // image with several pixels in the right image.
01094         float result = (float)i_corr.get_correlation(x,y,x+i,y);
01095         if (result > max) {
01096           max = result; // if we get a new peak, update the max value...
01097           disp(x,y) = static_cast<unsigned char>(i+range); // ...and put the new disparity in the disparity buffer
01098         }
01099       }
01100     }
01101   }
01102   vil1_image scaled_image = scale_image(disp);
01103   disp_img_ = disp;
01104   dimg_tab_->set_image(scaled_image);
01105   this->post_redraw();
01106   return;
01107 }
01108 
01109 // This routine makes images of the boundaries found through JSEG
01110 // segmentation.
01111 
01112 vil1_image* vsrl_manager::make_jseg_image(vil1_memory_image_of<unsigned char>* jseg_out)
01113 {
01114   vil1_memory_image_of<unsigned char>* b_image =
01115     new vil1_memory_image_of<unsigned char>(jseg_out->width(),jseg_out->height());
01116   for (int y=0;y<jseg_out->rows()-1;y++) {
01117     for (int x=0;x<jseg_out->cols()-1;x++) {
01118       (*b_image)(x,y) = 0;  // clear out the pixels first
01119       // Horizontal Boundaries
01120       if ( (*jseg_out)(x,y) != (*jseg_out)(x+1,y) ) {
01121         (*b_image)(x,y) = 255;
01122       }
01123       // Vertical Boundaries
01124       if ( (*jseg_out)(x,y) != (*jseg_out)(x,y+1) ) {
01125         (*b_image)(x,y) = 255;
01126       }
01127     }
01128   }
01129   return b_image;
01130 }
01131 // boundary_matching: This routine takes two images, computes jseg segmentation, creates
01132 // two "boundary" images, then uses these images to attempt "dense matching".
01133 void vsrl_manager::boundary_matching()
01134 {
01135 #ifndef INCLUDE_JSEG
01136   vcl_cout << "vsrl_manager::boundary_matching - Error. JSEG not included in this compilation.\n";
01137   return;
01138 #else
01139   // Set up the JSEG parameters
01140   static float TQUAN=-1.0f;
01141   static int NSCALE=-1;
01142   static float threshcolor=-1.0f;
01143   vgui_dialog jseg_dialog("JSEG Parameters");
01144   jseg_dialog.field("Color Quantization Threshold (-1=automatic): ",TQUAN);
01145   jseg_dialog.field("Number of Scales (-1=automatic): ",NSCALE);
01146   jseg_dialog.field("Region Merge Threshold (-1=automatic): ",threshcolor);
01147   jseg_dialog.field("Shadow Mean Intensity Threshold: ", shadow_mean_);
01148   if (!jseg_dialog.ask()) return;
01149   // Get the image for segmentation
01150   // Left image first...
01151   vil1_memory_image_of<unsigned char> imL(imgL_);
01152   unsigned char* cp = imL.get_buffer();
01153   int nx = imL.cols();
01154   int ny = imL.rows();
01155   int dim = 1; // grayscale image
01156 
01157   // Run JSEG
01158   unsigned char* js_imgL = jseg(cp,dim,nx,ny,TQUAN,NSCALE,threshcolor);
01159   vil1_memory_image_of<unsigned char>* js_out_L = new vil1_memory_image_of<unsigned char>(js_imgL,nx,ny);
01160 
01161   // Now for the Right image...
01162   vil1_memory_image_of<unsigned char> imR(imgR_);
01163   cp = imR.get_buffer();
01164   nx = imR.cols();
01165   ny = imR.rows();
01166   unsigned char* js_imgR = jseg(cp,dim,nx,ny,TQUAN,NSCALE,threshcolor);
01167   vil1_memory_image_of<unsigned char>* js_out_R = new vil1_memory_image_of<unsigned char>(js_imgR,nx,ny);
01168 
01169   // We've now jseg-ed 2 images. Now get the boundary images.
01170 
01171   vil1_image* bi_L = make_jseg_image(js_out_L);
01172   vil1_image* bi_R = make_jseg_image(js_out_R);
01173 
01174   // Display images
01175   itabL_->set_image(*bi_L);
01176   itabR_->set_image(*bi_R);
01177   imgL_ = *bi_L;
01178   imgR_ = *bi_R;
01179   this->post_redraw();
01180 
01181   vcl_cout << "Beginning dense matching...\n";
01182 
01183   vsrl_stereo_dense_matcher matcher(*bi_L,*bi_R);
01184   matcher.set_correlation_range(params_->correlation_range);
01185   matcher.execute();
01186 
01187   // Get & display the disparity image
01188   // Get a buffer the size of the left image
01189   vil1_memory_image_of<unsigned char> buffer(imgL_.cols(),imgL_.rows());
01190   // Zero out the buffer
01191   for (int x=0;x<buffer.width();x++)
01192     for (int y=0;y<buffer.height();y++)
01193       buffer(x,y)=0;
01194   // Get the disparities into the buffer
01195   for (int y=0;y<buffer.height();y++) {
01196     for (int x=0;x<buffer.width();x++) {
01197       int disparity = matcher.get_disparity(x,y);
01198       int value = disparity + params_->correlation_range+1;
01199       if (value < 0)
01200         value = 0;
01201       if (value>2*params_->correlation_range+1)
01202         value=0;
01203       buffer(x,y)=value;
01204     }
01205   }
01206 
01207   // Display the disparity image
01208   disp_img_ = buffer;
01209   vil1_image scaled_image = scale_image(buffer);
01210   dimg_tab_->set_image(scaled_image);
01211 
01212   vcl_cout << "Dense Matcher complete.\n";
01213   this->post_redraw();
01214   return;
01215 #endif
01216 }
01217 
01218 void vsrl_manager::region_disparity()
01219 {
01220   // This method depends on the JSEG package being present and
01221   // linked in.  If not, it should abort.
01222 
01223 #ifdef INCLUDE_JSEG
01224   // First do segmentation - one way or another
01225   vcl_vector<vdgl_digital_region*> dregs = run_jseg(imgL_);  // JSEG method
01226 
01227   // Next, find disparity on a pixel-by-pixel basis
01228   // raw correlation is used because the region segmentation should obviate
01229   // the dynamic program.
01230   this->raw_correlation();
01231 
01232   // Find disparity using regions
01233   vsrl_region_disparity r_disp(&imgL_, &imgR_);
01234   vil1_memory_image_of<unsigned char> disp(disp_img_);
01235   vcl_cout << "vsrl_manager::region_disparity\n";
01236   r_disp.SetDisparityImage(&disp);
01237   r_disp.SetRegions(&dregs);
01238   r_disp.Execute();
01239 
01240   // Display results
01241   vil1_memory_image_of<double>* d2 = r_disp.GetRegionDisparities();
01242   // As nice as it is to have these floating point results, the rest of the code
01243   // assumes everything is <unsigned char> **sigh**.  So we convert...
01244   //
01245   for (int c=0; c<disp_img_.width(); c++) {
01246     for (int r=0; r<disp_img_.height(); r++) {
01247       disp(c,r)= (*d2)(c,r);
01248     }
01249   }
01250 
01251   dimg_tab_->set_image(scale_image(disp));
01252 #else
01253   vcl_cout << "vsrl_manager::region_disparity: Error - JSEG package required but not included in this compilation.\n"
01254            << "Compilation flag INCLUDE_JSEG not set.\n";
01255 #endif
01256 
01257   this->post_redraw();
01258 }
01259 
01260 // Generate Dense disparity map using KL corner tracking.
01261 void vsrl_manager::corner_method()
01262 {
01263   if (!imgL_ || !imgR_) {
01264     vcl_cout << "vsrl_manager::corner_method - No Images Loaded.\n";
01265     return; // Sanity check.
01266   }
01267 
01268   // Construct a vector from the images.
01269   vcl_vector<vil1_image> images;
01270   images.push_back(imgL_);
01271   images.push_back(imgR_);
01272 
01273   vgel_multi_view_data_vertex_sptr matched_points;
01274   matched_points = new vgel_multi_view_data<vtol_vertex_2d_sptr> (2);
01275 
01276   // Run the KLT tracker
01277   // first get the params, & then the tracker...
01278   static vgel_kl_params kl_params;
01279   set_kl_params(&kl_params);
01280   vgel_kl kl_points(kl_params);
01281   // now get the matched points
01282   kl_points.match_sequence (images, matched_points);
01283 
01284   // At this point we should have a bunch of matched KL points
01285   // get the matched points from the KLT structures
01286   vcl_vector<vtol_vertex_2d_sptr> pts0;
01287   vcl_vector<vtol_vertex_2d_sptr> pts1;
01288   matched_points->get (0, 1, pts0, pts1);
01289 
01290   // Get an image to store disparities in; make sure it starts out at zero
01291   // disparity.  This will be equivalent to the correlation range +1 because
01292   // that's how we offset the images to handle negative disparity.
01293   //  int zero_disp = params_->correlation_range +1;
01294 
01295   vil1_memory_image_of<unsigned char> disp(imgL_.cols(),imgL_.rows());
01296   for (int y = 0; y<imgL_.rows();y++)
01297     for (int x=0; x<imgL_.cols();x++)
01298       disp(x,y) = 0; // clear all entries
01299 
01300   // This is some setup for the kd_tree we're going to use...
01301   vcl_vector< rsdl_point > rsdlvec;
01302 
01303   // Now calculate the disparity for each matched point.
01304   // This is simply the difference in the X-coordinate.
01305   vcl_vector< vgl_point_3d <float> > points_3d;
01306   vcl_vector<vtol_vertex_2d_sptr>::iterator p0_it = pts0.begin();
01307   vcl_vector<vtol_vertex_2d_sptr>::iterator p1_it = pts1.begin();
01308 
01309   // Now loop over all the points
01310 
01311   // Offset for zero disparity; allows us to handle negative disparities
01312   int zero_disp = 128;
01313   vcl_cout << "vsrl_manager::corner_method():\n";
01314   float x0, x1, y0, y1, d; // d = disparity (proportional to z)
01315   vnl_double_2 v_ang(0.0,0.0);
01316   vtol_vertex_2d tmp;
01317   for (;p0_it < pts0.end(); p0_it++, p1_it++) {
01318     //    vcl_cout << "p0: " << (**p0_it) << "  p1: " << (**p1_it) << vcl_endl;
01319     tmp = **p0_it;  // Point 0
01320     x0 = (float)tmp.x();
01321     y0 = (float)tmp.y();
01322     tmp = **p1_it;  // Point 1
01323     x1 = (float)tmp.x();
01324     y1 = (float)tmp.y();
01325     d = x1 - x0; // Disparity
01326     // stuff the disparity into the right place in the image buffer
01327     disp(int(x0),int(y0)) = vxl_byte(d + zero_disp); // Add in the "0" offset.
01328     vnl_double_2 v_cart(x0,y0);
01329     rsdl_point rpt(v_cart,v_ang); // make the rsdl point
01330     rsdlvec.push_back(rpt);  // add the point to the list for the kd_tree
01331     // While we're looping, we might as well display the points...
01332     e2d0_->add_point(x0,y0);
01333     e2d1_->add_point(x1,y1);
01334   }
01335 
01336   // Now we have a bunch of rsdl_points in a vector, so we
01337   // create an rsdl_kd_tree
01338   rsdl_kd_tree tree(rsdlvec);
01339   vcl_vector<rsdl_point> neighbors;
01340   vcl_vector<int> index;
01341 
01342   // Now scan the image and insert disparity as retrieved from
01343   // the rsdl_kd_tree.
01344   int min_disp = 255;
01345   int xd, yd;
01346   for (int y=0; y<disp.rows(); y++) {
01347     for (int x=0; x<disp.cols(); x++) {
01348       // Only calculate for the pixels that aren't corner points
01349       if (disp(x,y) == 0) {
01350         vnl_double_2 v_cart(x,y);
01351         rsdl_point query(v_cart,v_ang);
01352         // Get the nearest neighbor; we'll use that disparity for now
01353         tree.n_nearest(query,1,neighbors,index);
01354         rsdl_point& nn = neighbors.front();  // This should be the nearest neighbor pt.
01355         xd = int(nn.cartesian(0));
01356         yd = int(nn.cartesian(1));
01357         //        vcl_cout << "X,Y: " << x << ',' << y << "\tXD,YD: " << xd << ',' << yd << vcl_endl;
01358         disp(x,y) = disp(xd,yd); // assign disparity to nearest neighbor's value
01359         if (disp(xd,yd) < min_disp) min_disp = disp(xd,yd);
01360       }
01361     }
01362   }
01363   disp = vil1_scale_intensities(disp,1.0,-min_disp);
01364 
01365 
01366   // display the disparity image
01367   disp_img_ = disp;
01368   vil1_image scaled_image = scale_image(disp);
01369   dimg_tab_->set_image(scaled_image);
01370 
01371   this->post_redraw();
01372   return;
01373 }
01374 
01375 void vsrl_manager::set_kl_params(vgel_kl_params* kl_params)
01376 {
01377   // get the KLT Parameters
01378   vgui_dialog kl_dialog("KLT Parameters");
01379   kl_dialog.field("Number of Points",kl_params->numpoints);
01380   kl_dialog.field("Search Range",kl_params->search_range);
01381   kl_dialog.field("Minimum distance between features",kl_params->mindist);
01382   kl_dialog.field("Window width",kl_params->window_width);
01383   kl_dialog.field("Window height",kl_params->window_height);
01384   kl_dialog.field("Smallest Eigenvalue",kl_params->min_eigenvalue);
01385   kl_dialog.field("Minimum determinant",kl_params->min_determinant);
01386   kl_dialog.field("Minimum displacement",kl_params->min_displacement);
01387   kl_dialog.field("Maximum iterations",kl_params->max_iterations);
01388   kl_dialog.field("Maximum residue",kl_params->max_residue);
01389   kl_dialog.field("Sigma of gradient gaussian",kl_params->grad_sigma);
01390   kl_dialog.field("Sigma of smoothing gaussian",kl_params->smooth_sigma_fact);
01391   kl_dialog.field("Sigma for pyramid calculation",kl_params->pyramid_sigma_fact);
01392   kl_dialog.field("Number of skipped pixels",kl_params->nSkippedPixels);
01393   kl_dialog.checkbox("Replace lost points",kl_params->replaceLostPoints);
01394   kl_dialog.checkbox("Sequential mode",kl_params->sequentialMode);
01395   kl_dialog.checkbox("Smooth before selecting",kl_params->smoothBeforeSelecting);
01396   kl_dialog.checkbox("Write internal images",kl_params->writeInternalImages);
01397   kl_dialog.checkbox("Verbose",kl_params->verbose);
01398   if (!kl_dialog.ask()) return;
01399   return;
01400 }
01401 
01402 void
01403 vsrl_manager::occlusion_map()
01404 {
01405   // This test attempts to predict occlusion
01406   if (!disp_img_ || !imgL_ || !imgR_) return; // Sanity check.
01407   vsrl_results_dense_matcher matcher(imgL_,disp_img_);
01408   matcher.set_correlation_range(params_->correlation_range);
01409   vsrl_3d_output output(imgL_,imgR_);
01410   output.set_matcher(&matcher);
01411   output.write_output("out.dat");
01412   vil1_memory_image_of<unsigned char> range = output.get_unsigned_range_image();
01413   vil1_image scaled_rimage = scale_image(range);
01414   vil1_image thresh_img = vepl_threshold(scaled_rimage,50,0,255);
01415   //  this->show_gradient_mag(&scaled_rimage);
01416   disp_img_ = thresh_img;
01417   dimg_tab_->set_image(thresh_img);
01418   this->post_redraw();
01419   return;
01420 }

Generated on Mon Mar 8 05:24:39 2010 for contrib/gel/vsrl by  doxygen 1.5.1