contrib/brl/bseg/sdet/sdet_third_order_edge_det.cxx
Go to the documentation of this file.
00001 // This is brl/bseg/sdet/sdet_third_order_edge_det.cxx
00002 #include "sdet_third_order_edge_det.h"
00003 //:
00004 // \file
00005 #include <vul/vul_timer.h>
00006 #include <vsol/vsol_point_2d.h>
00007 #include <vsol/vsol_line_2d.h>
00008 #include <vil/vil_convert.h>
00009 
00010 #include <bil/algo/bil_color_conversions.h>
00011 
00012 // function to compute generic edges
00013 void sdet_third_order_edge_det::apply(vil_image_view<vxl_byte> const& image)
00014 {
00015   //convert to grayscale
00016   vil_image_view<vxl_byte> greyscale_view;
00017   if (image.nplanes() == 3) {
00018     vil_convert_planes_to_grey(image, greyscale_view );
00019   }
00020   else if (image.nplanes() == 1) {
00021     greyscale_view = image;
00022   }
00023   else
00024     return;
00025 
00026   //start the timer
00027   vul_timer t;
00028 
00029   //compute image gradients before performing nonmax suppression
00030   vil_image_view<double> grad_x, grad_y, grad_mag;
00031   int scale = 1 << interp_factor_; // 2^interp_factor_
00032 
00033   //compute gradients
00034   switch (grad_op_)
00035   {
00036     case 0: //Interpolated Gaussian
00037     {
00038       if (conv_algo_==0) { //2-d convolutions
00039         brip_subpix_convolve_2d(greyscale_view, grad_x, brip_Gx_kernel(sigma_), double(), interp_factor_);
00040         brip_subpix_convolve_2d(greyscale_view, grad_y, brip_Gy_kernel(sigma_), double(), interp_factor_);
00041       }
00042       else {
00043         brip_subpix_convolve_2d_sep(greyscale_view, grad_x, brip_Gx_kernel(sigma_), double(), interp_factor_);
00044         brip_subpix_convolve_2d_sep(greyscale_view, grad_y, brip_Gy_kernel(sigma_), double(), interp_factor_);
00045       }
00046 
00047       break;
00048     }
00049     case 1: //h0-operator
00050     {
00051       if (conv_algo_==0) { //2-d convolutions
00052         brip_subpix_convolve_2d(greyscale_view, grad_x, brip_h0_Gx_kernel(sigma_), double(), interp_factor_);
00053         brip_subpix_convolve_2d(greyscale_view, grad_y, brip_h0_Gy_kernel(sigma_), double(), interp_factor_);
00054       }
00055       else {
00056         brip_subpix_convolve_2d_sep(greyscale_view, grad_x, brip_h0_Gx_kernel(sigma_), double(), interp_factor_);
00057         brip_subpix_convolve_2d_sep(greyscale_view, grad_y, brip_h0_Gy_kernel(sigma_), double(), interp_factor_);
00058       }
00059       break;
00060     }
00061     case 2:  //h1-operator
00062     {
00063       if (conv_algo_==0) { //2-d convolutions
00064         brip_subpix_convolve_2d(greyscale_view, grad_x, brip_h1_Gx_kernel(sigma_), double(), interp_factor_);
00065         brip_subpix_convolve_2d(greyscale_view, grad_y, brip_h1_Gy_kernel(sigma_), double(), interp_factor_);
00066       }
00067       else {
00068         brip_subpix_convolve_2d_sep(greyscale_view, grad_x, brip_h1_Gx_kernel(sigma_), double(), interp_factor_);
00069         brip_subpix_convolve_2d_sep(greyscale_view, grad_y, brip_h1_Gy_kernel(sigma_), double(), interp_factor_);
00070       }
00071       break;
00072     }
00073   }
00074 
00075   //compute gradient magnitude
00076   grad_mag.set_size(grad_x.ni(), grad_x.nj());
00077 
00078   //get the pointers to the memory chunks
00079   double *gx  =  grad_x.top_left_ptr();
00080   double *gy  =  grad_y.top_left_ptr();
00081   double *g_mag  =  grad_mag.top_left_ptr();
00082 
00083   //compute the gradient magnitude
00084   for (unsigned long i=0; i<grad_mag.size(); i++)
00085     g_mag[i] = vcl_sqrt(gx[i]*gx[i] + gy[i]*gy[i]);
00086 
00087   double conv_time = t.real();
00088   t.mark(); //reset timer
00089 
00090   //Now call the nms code to determine the set of edgels and their subpixel positions
00091   vcl_vector<vgl_point_2d<double> > edge_locs, edge_locations;
00092   vcl_vector<vgl_point_2d<int> > pix_locs;
00093   vcl_vector<double> orientation, mag, d2f;
00094 
00095   //parameters for reliable NMS
00096   double noise_sigma = 1.5;
00097   double rel_thresh = 1.3*noise_sigma/(sigma_*sigma_*sigma_);
00098   sdet_nms NMS(sdet_nms_params(thresh_, (sdet_nms_params::PFIT_TYPE)pfit_type_,
00099                                int(4*sigma_+1)*(1 << interp_factor_), // 2^interp_factor_
00100                                rel_thresh, adapt_thresh_),
00101                grad_x, grad_y, grad_mag);
00102 
00103   //  NMS.apply(true, edge_locs, orientation, mag, d2f, pix_locs);
00104   NMS.apply(true, edge_locs, orientation, mag);
00105 
00106   double nms_time = t.real();
00107   t.mark(); //reset timer
00108 
00109   //convert to the original image scale coordinates
00110   for (unsigned i=0; i<edge_locs.size(); i++)
00111     edge_locations.push_back(vgl_point_2d<double>(edge_locs[i].x()/scale, edge_locs[i].y()/scale));
00112 
00113   //for each edge, compute all the gradients to compute the new orientation
00114   vcl_vector<double> Ix, Iy, Ixx, Ixy, Iyy, Ixxy, Ixyy, Ixxx, Iyyy;
00115 
00116   switch (grad_op_)
00117   {
00118     case 0: //Interpolated Gaussian
00119     {
00120       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ix,   brip_Gx_kernel(sigma_),   double(), interp_factor_);
00121       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iy,   brip_Gy_kernel(sigma_),   double(), interp_factor_);
00122       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixx,  brip_Gxx_kernel(sigma_),  double(), interp_factor_);
00123       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixy,  brip_Gxy_kernel(sigma_),  double(), interp_factor_);
00124       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyy,  brip_Gyy_kernel(sigma_),  double(), interp_factor_);
00125       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxx, brip_Gxxx_kernel(sigma_), double(), interp_factor_);
00126       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxy, brip_Gxxy_kernel(sigma_), double(), interp_factor_);
00127       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixyy, brip_Gxyy_kernel(sigma_), double(), interp_factor_);
00128       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyyy, brip_Gyyy_kernel(sigma_), double(), interp_factor_);
00129       break;
00130     }
00131     case 1: //h0-operator
00132     {
00133       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ix,   brip_h0_Gx_kernel(sigma_),   double(), interp_factor_);
00134       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iy,   brip_h0_Gy_kernel(sigma_),   double(), interp_factor_);
00135       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixx,  brip_h0_Gxx_kernel(sigma_),  double(), interp_factor_);
00136       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixy,  brip_h0_Gxy_kernel(sigma_),  double(), interp_factor_);
00137       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyy,  brip_h0_Gyy_kernel(sigma_),  double(), interp_factor_);
00138       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxx, brip_h0_Gxxx_kernel(sigma_), double(), interp_factor_);
00139       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxy, brip_h0_Gxxy_kernel(sigma_), double(), interp_factor_);
00140       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixyy, brip_h0_Gxyy_kernel(sigma_), double(), interp_factor_);
00141       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyyy, brip_h0_Gyyy_kernel(sigma_), double(), interp_factor_);
00142       break;
00143     }
00144     case 2:  //h1-operator
00145     {
00146       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ix,   brip_h1_Gx_kernel(sigma_),   double(), interp_factor_);
00147       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iy,   brip_h1_Gy_kernel(sigma_),   double(), interp_factor_);
00148       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixx,  brip_h1_Gxx_kernel(sigma_),  double(), interp_factor_);
00149       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixy,  brip_h1_Gxy_kernel(sigma_),  double(), interp_factor_);
00150       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyy,  brip_h1_Gyy_kernel(sigma_),  double(), interp_factor_);
00151       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxx, brip_h1_Gxxx_kernel(sigma_), double(), interp_factor_);
00152       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixxy, brip_h1_Gxxy_kernel(sigma_), double(), interp_factor_);
00153       brip_subpix_convolve_2d(greyscale_view, edge_locations, Ixyy, brip_h1_Gxyy_kernel(sigma_), double(), interp_factor_);
00154       brip_subpix_convolve_2d(greyscale_view, edge_locations, Iyyy, brip_h1_Gyyy_kernel(sigma_), double(), interp_factor_);
00155       break;
00156     }
00157   }
00158 
00159   //Now, compute and update each edge with its new orientation
00160   vcl_vector<double> edge_orientations(edge_locations.size());
00161   for (unsigned i=0; i<edge_locations.size();i++)
00162   {
00163     //compute F
00164     //F[i]   = Ix[i]*Ix[i]*Ixx[i] + 2*Ix[i]*Iy[i]*Ixy[i] + Iy[i]*Iy[i]*Iyy[i];
00165 
00166     //compute Fx and Fy
00167     double Fx = 2*Ix[i]*Ixx[i]*Ixx[i] + 2*Ix[i]*Ixy[i]*Ixy[i] + 2*Ixx[i]*Iy[i]*Ixy[i] +
00168                 2*Ixy[i]*Iyy[i]*Iy[i] + 2*Ix[i]*Iy[i]*Ixxy[i] + Ixyy[i]*Iy[i]*Iy[i] + Ix[i]*Ix[i]*Ixxx[i];
00169     double Fy = 2*Iy[i]*Iyy[i]*Iyy[i] + 2*Iy[i]*Ixy[i]*Ixy[i] + 2*Ixy[i]*Ix[i]*Ixx[i] +
00170                 2*Ix[i]*Iyy[i]*Ixy[i]  + 2*Ix[i]*Iy[i]*Ixyy[i] + Ixxy[i]*Ix[i]*Ix[i] + Iyyy[i]*Iy[i]*Iy[i];
00171 
00172     //save new orientation
00173     edge_orientations[i] = vnl_math::angle_0_to_2pi(vcl_atan2(Fx, -Fy));
00174   }
00175 
00176   double third_order_time = t.real();
00177 
00178   //report timings
00179   vcl_cout << '\n'
00180            << "time taken for conv: " << conv_time << " msec\n"
00181            << "time taken for nms: " << nms_time << " msec\n"
00182            << "time taken for third-order: " << third_order_time << " msec" << vcl_endl;
00183 
00184   //------------------------------------------------------------------------------------------
00185   // Compute the edge uncertainty measures
00186 
00187 #if 0
00188   vcl_vector<double> edge_uncertainties(edge_locations.size());
00189   sdet_edge_uncertainty_measure edge_uncer(grad_x, grad_y, sigma_);
00190   edge_uncer.get_edgel_uncertainties(edge_locs, edge_uncertainties);
00191 #endif
00192   // --- new code ---
00193   t.mark(); //reset timer
00194   for (unsigned i=0; i<edge_locations.size(); i++)
00195   {
00196     vdgl_edgel ed(edge_locations[i].x(),edge_locations[i].y() , mag[i], edge_orientations[i]);
00197     edgels_.push_back(ed);
00198   }
00199   double edgel_encode_time = t.real();
00200   vcl_cout << "time taken for edgel encode: " << edgel_encode_time << " msec" << vcl_endl;
00201 #if 0
00202   //------------------------------------------------------------------------------------------
00203   //create a new edgemap from the tokens identified by NMS
00204   sdet_edgemap_sptr edge_map;
00205   const bool interp_grid = false;
00206   const bool reduce_tokens = true;
00207   if (interp_grid)
00208     edge_map = new sdet_edgemap(grad_mag.ni(), grad_mag.nj());
00209   else
00210     edge_map = new sdet_edgemap(greyscale_view.ni(), greyscale_view.nj());
00211 
00212   for (unsigned i=0; i<edge_locations.size(); i++)
00213   {
00214     //Now insert them into the edge map appropriately
00215     if (interp_grid) {
00216       sdet_edgel* new_edgel = new sdet_edgel(edge_locs[i], edge_orientations[i], mag[i], d2f[i], edge_uncertainties[i]);
00217       new_edgel->gpt = pix_locs[i];
00218       edge_map->insert(new_edgel, pix_locs[i].x(), pix_locs[i].y());
00219     }
00220     else {
00221       if (reduce_tokens) {
00222         //only insert one edgel per grid position
00223         int xx = vnl_math_rnd(edge_locations[i].x());
00224         int yy = vnl_math_rnd(edge_locations[i].y());
00225 
00226         if (edge_map->edge_cells(yy, xx).size()>0)
00227           continue;
00228 
00229         sdet_edgel* new_edgel = new sdet_edgel(edge_locations[i], edge_orientations[i], mag[i], d2f[i], edge_uncertainties[i]);
00230         new_edgel->gpt = vgl_point_2d<int>(xx, yy);
00231         edge_map->insert(new_edgel, xx, yy);
00232       }
00233       else { //insert all of them
00234         sdet_edgel* new_edgel = new sdet_edgel(edge_locations[i], edge_orientations[i], mag[i], d2f[i], edge_uncertainties[i]);
00235         new_edgel->gpt = pix_locs[i];
00236         edge_map->insert(new_edgel);
00237       }
00238     }
00239   }
00240 
00241   //add intensity appearance to the edges
00242   //sdet_add_intensity_app(greyscale_view, edge_map, sigma, 1); //opt: 0: original , 1: smoothed, 2: Half gaussian
00243 
00244   return edge_map;
00245 #endif
00246 }
00247 
00248 bool sdet_third_order_edge_det::apply_color(vil_image_view<vxl_byte> const& image)
00249 {
00250   if (image.nplanes() != 3) {
00251     vcl_cerr << "In sdet_third_order_edge_det::apply_color() - only works with color images!\n";
00252     return false;
00253   }
00254 
00255   vil_image_view<float> comp1, comp2, comp3;
00256   convert_RGB_to_Lab(image, comp1, comp2, comp3);
00257 
00258   //start the timer
00259   vul_timer t;
00260 
00261   //4) compute image gradients of each of the components
00262   vil_image_view<float> f1_dx, f1_dy, f2_dx, f2_dy, f3_dx, f3_dy;
00263   int scale=1;
00264 
00265   switch (grad_op_)
00266   {
00267     case 0: //Gaussian
00268     {
00269       scale = 1 << interp_factor_; // 2^interp_factor_
00270       //compute gradients
00271       if (conv_algo_==0) {
00272         brip_subpix_convolve_2d(comp1, f1_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00273         brip_subpix_convolve_2d(comp1, f1_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00274         brip_subpix_convolve_2d(comp2, f2_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00275         brip_subpix_convolve_2d(comp2, f2_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00276         brip_subpix_convolve_2d(comp3, f3_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00277         brip_subpix_convolve_2d(comp3, f3_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00278       }
00279       else {
00280         brip_subpix_convolve_2d_sep(comp1, f1_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00281         brip_subpix_convolve_2d_sep(comp1, f1_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00282         brip_subpix_convolve_2d_sep(comp2, f2_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00283         brip_subpix_convolve_2d_sep(comp2, f2_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00284         brip_subpix_convolve_2d_sep(comp3, f3_dx, brip_Gx_kernel(sigma_), float(), interp_factor_);
00285         brip_subpix_convolve_2d_sep(comp3, f3_dy, brip_Gy_kernel(sigma_), float(), interp_factor_);
00286       }
00287       break;
00288     }
00289     case 1: //h0-operator
00290     {
00291       scale = 1 << interp_factor_; // 2^interp_factor_
00292 
00293       //compute gradients
00294       if (conv_algo_==0) {
00295         brip_subpix_convolve_2d(comp1, f1_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00296         brip_subpix_convolve_2d(comp1, f1_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00297         brip_subpix_convolve_2d(comp2, f2_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00298         brip_subpix_convolve_2d(comp2, f2_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00299         brip_subpix_convolve_2d(comp3, f3_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00300         brip_subpix_convolve_2d(comp3, f3_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00301       }
00302       else {
00303         brip_subpix_convolve_2d_sep(comp1, f1_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00304         brip_subpix_convolve_2d_sep(comp1, f1_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00305         brip_subpix_convolve_2d_sep(comp2, f2_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00306         brip_subpix_convolve_2d_sep(comp2, f2_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00307         brip_subpix_convolve_2d_sep(comp3, f3_dx, brip_h0_Gx_kernel(sigma_), float(), interp_factor_);
00308         brip_subpix_convolve_2d_sep(comp3, f3_dy, brip_h0_Gy_kernel(sigma_), float(), interp_factor_);
00309       }
00310 
00311       break;
00312     }
00313     case 2:  //h1-operator
00314     {
00315       scale = 1 << interp_factor_; // 2^interp_factor_
00316 
00317       //compute gradients
00318       if (conv_algo_==0) {
00319         brip_subpix_convolve_2d(comp1, f1_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00320         brip_subpix_convolve_2d(comp1, f1_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00321         brip_subpix_convolve_2d(comp2, f2_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00322         brip_subpix_convolve_2d(comp2, f2_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00323         brip_subpix_convolve_2d(comp3, f3_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00324         brip_subpix_convolve_2d(comp3, f3_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00325       }
00326       else {
00327         brip_subpix_convolve_2d_sep(comp1, f1_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00328         brip_subpix_convolve_2d_sep(comp1, f1_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00329         brip_subpix_convolve_2d_sep(comp2, f2_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00330         brip_subpix_convolve_2d_sep(comp2, f2_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00331         brip_subpix_convolve_2d_sep(comp3, f3_dx, brip_h1_Gx_kernel(sigma_), float(), interp_factor_);
00332         brip_subpix_convolve_2d_sep(comp3, f3_dy, brip_h1_Gy_kernel(sigma_), float(), interp_factor_);
00333       }
00334       break;
00335     }
00336   }
00337 
00338   //5) compute the squared norm of the vector-gradient
00339   vil_image_view<double> grad_mag, nu1, nu2; //eigenvalue and eigenvector
00340   grad_mag.set_size(f1_dx.ni(), f1_dx.nj());
00341   nu1.set_size(f1_dx.ni(), f1_dx.nj());
00342   nu2.set_size(f1_dx.ni(), f1_dx.nj());
00343 
00344   //get the pointers to the memory chunks
00345   float *f1x  =  f1_dx.top_left_ptr();
00346   float *f1y  =  f1_dy.top_left_ptr();
00347   float *f2x  =  f2_dx.top_left_ptr();
00348   float *f2y  =  f2_dy.top_left_ptr();
00349   float *f3x  =  f3_dx.top_left_ptr();
00350   float *f3y  =  f3_dy.top_left_ptr();
00351   double *g_mag  =  grad_mag.top_left_ptr();
00352   double *n1  =  nu1.top_left_ptr();
00353   double *n2  =  nu2.top_left_ptr();
00354 
00355   //compute the squared norm of gradient
00356   for (unsigned long i=0; i<grad_mag.size(); i++) {
00357     double A = f1x[i]*f1x[i]+f2x[i]*f2x[i]+f3x[i]*f3x[i];
00358     double B = f1x[i]*f1y[i]+f2x[i]*f2y[i]+f3x[i]*f3y[i];
00359     double C = f1y[i]*f1y[i]+f2y[i]*f2y[i]+f3y[i]*f3y[i];
00360 
00361     double l = (A+C+ vcl_sqrt((A-C)*(A-C) + 4*B*B))/2;
00362 
00363     if (vcl_fabs(B)>1e-2) {
00364       n1[i] = B/vcl_sqrt(B*B+(l-A)*(l-A));
00365       n2[i] = (l-A)/vcl_sqrt(B*B+(l-A)*(l-A));
00366     }
00367     else {
00368       n1[i] = (l-C)/vcl_sqrt(B*B+(l-C)*(l-C));
00369       n2[i] = B/vcl_sqrt(B*B+(l-C)*(l-C));
00370     }
00371 
00372     g_mag[i] = vcl_sqrt(l/3); //take the square root of the squared norm
00373   }
00374 
00375 
00376   double conv_time = t.real();
00377   t.mark(); //reset timer
00378 
00379   //Now call the nms code to get the subpixel edge tokens
00380   vcl_vector<vgl_point_2d<double> > edge_locations;
00381   vcl_vector<double> orientation, mag, d2f;
00382 
00383   sdet_nms NMS(sdet_nms_params(thresh_, (sdet_nms_params::PFIT_TYPE)pfit_type_), nu1, nu2, grad_mag);
00384   NMS.apply(true, edge_locations, orientation, mag, d2f);
00385 
00386   double nms_time = t.real();
00387   t.mark(); //reset timer
00388 
00389   //convert to the original image scale coordinates
00390   for (unsigned i=0; i<edge_locations.size(); i++)
00391     edge_locations[i].set(edge_locations[i].x()/scale, edge_locations[i].y()/scale);
00392 
00393   //for each edge, compute all the gradients to compute the new orientation
00394   vcl_vector<double> If1x, If1y, If1xx, If1xy, If1yy, If1xxy, If1xyy, If1xxx, If1yyy;
00395   vcl_vector<double> If2x, If2y, If2xx, If2xy, If2yy, If2xxy, If2xyy, If2xxx, If2yyy;
00396   vcl_vector<double> If3x, If3y, If3xx, If3xy, If3yy, If3xxy, If3xyy, If3xxx, If3yyy;
00397 
00398   switch (grad_op_)
00399   {
00400     case 0: //Interpolated Gaussian
00401     {
00402       brip_subpix_convolve_2d(comp1, edge_locations, If1x,   brip_Gx_kernel(sigma_),   double(), interp_factor_);
00403       brip_subpix_convolve_2d(comp1, edge_locations, If1y,   brip_Gy_kernel(sigma_),   double(), interp_factor_);
00404       brip_subpix_convolve_2d(comp1, edge_locations, If1xx,  brip_Gxx_kernel(sigma_),  double(), interp_factor_);
00405       brip_subpix_convolve_2d(comp1, edge_locations, If1xy,  brip_Gxy_kernel(sigma_),  double(), interp_factor_);
00406       brip_subpix_convolve_2d(comp1, edge_locations, If1yy,  brip_Gyy_kernel(sigma_),  double(), interp_factor_);
00407       brip_subpix_convolve_2d(comp1, edge_locations, If1xxx, brip_Gxxx_kernel(sigma_), double(), interp_factor_);
00408       brip_subpix_convolve_2d(comp1, edge_locations, If1xxy, brip_Gxxy_kernel(sigma_), double(), interp_factor_);
00409       brip_subpix_convolve_2d(comp1, edge_locations, If1xyy, brip_Gxyy_kernel(sigma_), double(), interp_factor_);
00410       brip_subpix_convolve_2d(comp1, edge_locations, If1yyy, brip_Gyyy_kernel(sigma_), double(), interp_factor_);
00411 
00412       brip_subpix_convolve_2d(comp2, edge_locations, If2x,   brip_Gx_kernel(sigma_),   double(), interp_factor_);
00413       brip_subpix_convolve_2d(comp2, edge_locations, If2y,   brip_Gy_kernel(sigma_),   double(), interp_factor_);
00414       brip_subpix_convolve_2d(comp2, edge_locations, If2xx,  brip_Gxx_kernel(sigma_),  double(), interp_factor_);
00415       brip_subpix_convolve_2d(comp2, edge_locations, If2xy,  brip_Gxy_kernel(sigma_),  double(), interp_factor_);
00416       brip_subpix_convolve_2d(comp2, edge_locations, If2yy,  brip_Gyy_kernel(sigma_),  double(), interp_factor_);
00417       brip_subpix_convolve_2d(comp2, edge_locations, If2xxx, brip_Gxxx_kernel(sigma_), double(), interp_factor_);
00418       brip_subpix_convolve_2d(comp2, edge_locations, If2xxy, brip_Gxxy_kernel(sigma_), double(), interp_factor_);
00419       brip_subpix_convolve_2d(comp2, edge_locations, If2xyy, brip_Gxyy_kernel(sigma_), double(), interp_factor_);
00420       brip_subpix_convolve_2d(comp2, edge_locations, If2yyy, brip_Gyyy_kernel(sigma_), double(), interp_factor_);
00421 
00422       brip_subpix_convolve_2d(comp3, edge_locations, If3x,   brip_Gx_kernel(sigma_),   double(), interp_factor_);
00423       brip_subpix_convolve_2d(comp3, edge_locations, If3y,   brip_Gy_kernel(sigma_),   double(), interp_factor_);
00424       brip_subpix_convolve_2d(comp3, edge_locations, If3xx,  brip_Gxx_kernel(sigma_),  double(), interp_factor_);
00425       brip_subpix_convolve_2d(comp3, edge_locations, If3xy,  brip_Gxy_kernel(sigma_),  double(), interp_factor_);
00426       brip_subpix_convolve_2d(comp3, edge_locations, If3yy,  brip_Gyy_kernel(sigma_),  double(), interp_factor_);
00427       brip_subpix_convolve_2d(comp3, edge_locations, If3xxx, brip_Gxxx_kernel(sigma_), double(), interp_factor_);
00428       brip_subpix_convolve_2d(comp3, edge_locations, If3xxy, brip_Gxxy_kernel(sigma_), double(), interp_factor_);
00429       brip_subpix_convolve_2d(comp3, edge_locations, If3xyy, brip_Gxyy_kernel(sigma_), double(), interp_factor_);
00430       brip_subpix_convolve_2d(comp3, edge_locations, If3yyy, brip_Gyyy_kernel(sigma_), double(), interp_factor_);
00431 
00432       break;
00433     }
00434     case 1: //h0-operator
00435     {
00436       brip_subpix_convolve_2d(comp1, edge_locations, If1x,   brip_h0_Gx_kernel(sigma_),   double(), interp_factor_);
00437       brip_subpix_convolve_2d(comp1, edge_locations, If1y,   brip_h0_Gy_kernel(sigma_),   double(), interp_factor_);
00438       brip_subpix_convolve_2d(comp1, edge_locations, If1xx,  brip_h0_Gxx_kernel(sigma_),  double(), interp_factor_);
00439       brip_subpix_convolve_2d(comp1, edge_locations, If1xy,  brip_h0_Gxy_kernel(sigma_),  double(), interp_factor_);
00440       brip_subpix_convolve_2d(comp1, edge_locations, If1yy,  brip_h0_Gyy_kernel(sigma_),  double(), interp_factor_);
00441       brip_subpix_convolve_2d(comp1, edge_locations, If1xxx, brip_h0_Gxxx_kernel(sigma_), double(), interp_factor_);
00442       brip_subpix_convolve_2d(comp1, edge_locations, If1xxy, brip_h0_Gxxy_kernel(sigma_), double(), interp_factor_);
00443       brip_subpix_convolve_2d(comp1, edge_locations, If1xyy, brip_h0_Gxyy_kernel(sigma_), double(), interp_factor_);
00444       brip_subpix_convolve_2d(comp1, edge_locations, If1yyy, brip_h0_Gyyy_kernel(sigma_), double(), interp_factor_);
00445 
00446       brip_subpix_convolve_2d(comp2, edge_locations, If2x,   brip_h0_Gx_kernel(sigma_),   double(), interp_factor_);
00447       brip_subpix_convolve_2d(comp2, edge_locations, If2y,   brip_h0_Gy_kernel(sigma_),   double(), interp_factor_);
00448       brip_subpix_convolve_2d(comp2, edge_locations, If2xx,  brip_h0_Gxx_kernel(sigma_),  double(), interp_factor_);
00449       brip_subpix_convolve_2d(comp2, edge_locations, If2xy,  brip_h0_Gxy_kernel(sigma_),  double(), interp_factor_);
00450       brip_subpix_convolve_2d(comp2, edge_locations, If2yy,  brip_h0_Gyy_kernel(sigma_),  double(), interp_factor_);
00451       brip_subpix_convolve_2d(comp2, edge_locations, If2xxx, brip_h0_Gxxx_kernel(sigma_), double(), interp_factor_);
00452       brip_subpix_convolve_2d(comp2, edge_locations, If2xxy, brip_h0_Gxxy_kernel(sigma_), double(), interp_factor_);
00453       brip_subpix_convolve_2d(comp2, edge_locations, If2xyy, brip_h0_Gxyy_kernel(sigma_), double(), interp_factor_);
00454       brip_subpix_convolve_2d(comp2, edge_locations, If2yyy, brip_h0_Gyyy_kernel(sigma_), double(), interp_factor_);
00455 
00456       brip_subpix_convolve_2d(comp3, edge_locations, If3x,   brip_h0_Gx_kernel(sigma_),   double(), interp_factor_);
00457       brip_subpix_convolve_2d(comp3, edge_locations, If3y,   brip_h0_Gy_kernel(sigma_),   double(), interp_factor_);
00458       brip_subpix_convolve_2d(comp3, edge_locations, If3xx,  brip_h0_Gxx_kernel(sigma_),  double(), interp_factor_);
00459       brip_subpix_convolve_2d(comp3, edge_locations, If3xy,  brip_h0_Gxy_kernel(sigma_),  double(), interp_factor_);
00460       brip_subpix_convolve_2d(comp3, edge_locations, If3yy,  brip_h0_Gyy_kernel(sigma_),  double(), interp_factor_);
00461       brip_subpix_convolve_2d(comp3, edge_locations, If3xxx, brip_h0_Gxxx_kernel(sigma_), double(), interp_factor_);
00462       brip_subpix_convolve_2d(comp3, edge_locations, If3xxy, brip_h0_Gxxy_kernel(sigma_), double(), interp_factor_);
00463       brip_subpix_convolve_2d(comp3, edge_locations, If3xyy, brip_h0_Gxyy_kernel(sigma_), double(), interp_factor_);
00464       brip_subpix_convolve_2d(comp3, edge_locations, If3yyy, brip_h0_Gyyy_kernel(sigma_), double(), interp_factor_);
00465 
00466       break;
00467     }
00468     case 2:  //h1-operator
00469     {
00470       brip_subpix_convolve_2d(comp1, edge_locations, If1x,   brip_h1_Gx_kernel(sigma_),   double(), interp_factor_);
00471       brip_subpix_convolve_2d(comp1, edge_locations, If1y,   brip_h1_Gy_kernel(sigma_),   double(), interp_factor_);
00472       brip_subpix_convolve_2d(comp1, edge_locations, If1xx,  brip_h1_Gxx_kernel(sigma_),  double(), interp_factor_);
00473       brip_subpix_convolve_2d(comp1, edge_locations, If1xy,  brip_h1_Gxy_kernel(sigma_),  double(), interp_factor_);
00474       brip_subpix_convolve_2d(comp1, edge_locations, If1yy,  brip_h1_Gyy_kernel(sigma_),  double(), interp_factor_);
00475       brip_subpix_convolve_2d(comp1, edge_locations, If1xxx, brip_h1_Gxxx_kernel(sigma_), double(), interp_factor_);
00476       brip_subpix_convolve_2d(comp1, edge_locations, If1xxy, brip_h1_Gxxy_kernel(sigma_), double(), interp_factor_);
00477       brip_subpix_convolve_2d(comp1, edge_locations, If1xyy, brip_h1_Gxyy_kernel(sigma_), double(), interp_factor_);
00478       brip_subpix_convolve_2d(comp1, edge_locations, If1yyy, brip_h1_Gyyy_kernel(sigma_), double(), interp_factor_);
00479 
00480       brip_subpix_convolve_2d(comp2, edge_locations, If2x,   brip_h1_Gx_kernel(sigma_),   double(), interp_factor_);
00481       brip_subpix_convolve_2d(comp2, edge_locations, If2y,   brip_h1_Gy_kernel(sigma_),   double(), interp_factor_);
00482       brip_subpix_convolve_2d(comp2, edge_locations, If2xx,  brip_h1_Gxx_kernel(sigma_),  double(), interp_factor_);
00483       brip_subpix_convolve_2d(comp2, edge_locations, If2xy,  brip_h1_Gxy_kernel(sigma_),  double(), interp_factor_);
00484       brip_subpix_convolve_2d(comp2, edge_locations, If2yy,  brip_h1_Gyy_kernel(sigma_),  double(), interp_factor_);
00485       brip_subpix_convolve_2d(comp2, edge_locations, If2xxx, brip_h1_Gxxx_kernel(sigma_), double(), interp_factor_);
00486       brip_subpix_convolve_2d(comp2, edge_locations, If2xxy, brip_h1_Gxxy_kernel(sigma_), double(), interp_factor_);
00487       brip_subpix_convolve_2d(comp2, edge_locations, If2xyy, brip_h1_Gxyy_kernel(sigma_), double(), interp_factor_);
00488       brip_subpix_convolve_2d(comp2, edge_locations, If2yyy, brip_h1_Gyyy_kernel(sigma_), double(), interp_factor_);
00489 
00490       brip_subpix_convolve_2d(comp3, edge_locations, If3x,   brip_h1_Gx_kernel(sigma_),   double(), interp_factor_);
00491       brip_subpix_convolve_2d(comp3, edge_locations, If3y,   brip_h1_Gy_kernel(sigma_),   double(), interp_factor_);
00492       brip_subpix_convolve_2d(comp3, edge_locations, If3xx,  brip_h1_Gxx_kernel(sigma_),  double(), interp_factor_);
00493       brip_subpix_convolve_2d(comp3, edge_locations, If3xy,  brip_h1_Gxy_kernel(sigma_),  double(), interp_factor_);
00494       brip_subpix_convolve_2d(comp3, edge_locations, If3yy,  brip_h1_Gyy_kernel(sigma_),  double(), interp_factor_);
00495       brip_subpix_convolve_2d(comp3, edge_locations, If3xxx, brip_h1_Gxxx_kernel(sigma_), double(), interp_factor_);
00496       brip_subpix_convolve_2d(comp3, edge_locations, If3xxy, brip_h1_Gxxy_kernel(sigma_), double(), interp_factor_);
00497       brip_subpix_convolve_2d(comp3, edge_locations, If3xyy, brip_h1_Gxyy_kernel(sigma_), double(), interp_factor_);
00498       brip_subpix_convolve_2d(comp3, edge_locations, If3yyy, brip_h1_Gyyy_kernel(sigma_), double(), interp_factor_);
00499 
00500       break;
00501     }
00502   }
00503 
00504   //Now, compute and update each edge with its new orientation
00505   vcl_vector<double> edge_orientations(edge_locations.size());
00506 
00507   for (unsigned i=0; i<edge_locations.size();i++)
00508   {
00509     double A   = If1x[i]*If1x[i] + If2x[i]*If2x[i] + If3x[i]*If3x[i];
00510     double Ax  = 2*If1x[i]*If1xx[i] + 2*If2x[i]*If2xx[i] + 2*If3x[i]*If3xx[i];
00511     double Ay  = 2*If1x[i]*If1xy[i] + 2*If2x[i]*If2xy[i] + 2*If3x[i]*If3xy[i];
00512     double Axx = 2*If1x[i]*If1xxx[i] + 2*If1xx[i]*If1xx[i] + 2*If2x[i]*If2xxx[i] + 2*If2xx[i]*If2xx[i] + 2*If3x[i]*If3xxx[i] + 2*If3xx[i]*If3xx[i];
00513     double Axy = 2*If1x[i]*If1xxy[i] + 2*If1xy[i]*If1xx[i] + 2*If2x[i]*If2xxy[i] + 2*If2xy[i]*If2xx[i] + 2*If3x[i]*If3xxy[i] + 2*If3xy[i]*If3xx[i];
00514     double Ayy = 2*If1x[i]*If1xyy[i] + 2*If1xy[i]*If1xy[i] + 2*If2x[i]*If2xyy[i] + 2*If2xy[i]*If2xy[i] + 2*If3x[i]*If3xyy[i] + 2*If3xy[i]*If3xy[i];
00515 
00516     double B   = If1x[i]*If1y[i] + If2x[i]*If2y[i] + If3x[i]*If3y[i];
00517     double Bx  = If1x[i]*If1xy[i] + If1y[i]*If1xx[i] + If2x[i]*If2xy[i] + If2y[i]*If2xx[i] + If3x[i]*If3xy[i] + If3y[i]*If3xx[i];
00518     double By  = If1x[i]*If1yy[i] + If1y[i]*If1xy[i] + If2x[i]*If2yy[i] + If2y[i]*If2xy[i] + If3x[i]*If3yy[i] + If3y[i]*If3xy[i];
00519     double Bxx = If1x[i]*If1xxy[i] + If1xx[i]*If1xy[i] + If1y[i]*If1xxx[i] + If1xy[i]*If1xx[i] + If2x[i]*If2xxy[i] + If2xx[i]*If2xy[i] + If2y[i]*If2xxx[i] + If2xy[i]*If2xx[i] + If3x[i]*If3xxy[i] + If3xx[i]*If3xy[i] + If3y[i]*If3xxx[i] + If3xy[i]*If3xx[i];
00520     double Bxy = If1x[i]*If1xyy[i] + If1xy[i]*If1xy[i] + If1y[i]*If1xxy[i] + If1yy[i]*If1xx[i] + If2x[i]*If2xyy[i] + If2xy[i]*If2xy[i] + If2y[i]*If2xxy[i] + If2yy[i]*If2xx[i] + If3x[i]*If3xyy[i] + If3xy[i]*If3xy[i] + If3y[i]*If3xxy[i] + If3yy[i]*If3xx[i];
00521     double Byy = If1x[i]*If1yyy[i] + If1xy[i]*If1yy[i] + If1y[i]*If1xyy[i] + If1yy[i]*If1xy[i] + If2x[i]*If2yyy[i] + If2xy[i]*If2yy[i] + If2y[i]*If2xyy[i] + If2yy[i]*If2xy[i] + If3x[i]*If3yyy[i] + If3xy[i]*If3yy[i] + If3y[i]*If3xyy[i] + If3yy[i]*If3xy[i];
00522 
00523     double C   = If1y[i]*If1y[i] + If2y[i]*If2y[i] + If3y[i]*If3y[i];
00524     double Cx  = 2*If1y[i]*If1xy[i] + 2*If2y[i]*If2xy[i] + 2*If3y[i]*If3xy[i];
00525     double Cy  = 2*If1y[i]*If1yy[i] + 2*If2y[i]*If2yy[i] + 2*If3y[i]*If3yy[i];
00526     double Cxx = 2*If1y[i]*If1xxy[i] + 2*If1xy[i]*If1xy[i] + 2*If2y[i]*If2xxy[i] + 2*If2xy[i]*If2xy[i] + 2*If3y[i]*If3xxy[i] + 2*If3xy[i]*If3xy[i];
00527     double Cxy = 2*If1y[i]*If1xyy[i] + 2*If1yy[i]*If1xy[i] + 2*If2y[i]*If2xyy[i] + 2*If2yy[i]*If2xy[i] + 2*If3y[i]*If3xyy[i] + 2*If3yy[i]*If3xy[i];
00528     double Cyy = 2*If1y[i]*If1yyy[i] + 2*If1yy[i]*If1yy[i] + 2*If2y[i]*If2yyy[i] + 2*If2yy[i]*If2yy[i] + 2*If3y[i]*If3yyy[i] + 2*If3yy[i]*If3yy[i];
00529 
00530     double l = ((C+A) + vcl_sqrt((A-C)*(A-C) + 4*B*B))/2.0;
00531     double e = (2*l-A-C);
00532 
00533     double lx = ( (l-C)*Ax + (l-A)*Cx + 2*B*Bx)/e;
00534     double ly = ( (l-C)*Ay + (l-A)*Cy + 2*B*By)/e;
00535     double lxx = ( (lx-Cx)*Ax + (l-C)*Axx + (lx-Ax)*Cx + (l-A)*Cxx + 2*Bx*Bx + 2*B*Bxx - lx*(2*lx-Cx-Ax))/e;
00536     double lxy = ( (ly-Cy)*Ax + (l-C)*Axy + (ly-Ay)*Cx + (l-A)*Cxy + 2*Bx*By + 2*B*Bxy - lx*(2*ly-Cy-Ay))/e;
00537     double lyy = ( (ly-Cy)*Ay + (l-C)*Ayy + (ly-Ay)*Cy + (l-A)*Cyy + 2*By*By + 2*B*Byy - ly*(2*ly-Cy-Ay))/e;
00538 
00539     /********************************************************************************
00540     // This computation is noisy
00541     double n1 = vcl_sqrt((1.0 + (A-C)/d)/2.0);
00542     double n2 = vnl_math_sgn(B)*vcl_sqrt((1.0 - (A-C)/d)/2.0);
00543 
00544     // when B is zero, these derivatives need to be corrected to the limiting value
00545     double n1x, n1y, n2x, n2y;
00546     if (vcl_fabs(B)>1e-2) {
00547       n1x = ( 2*(Ax-Cx)/d - (A-C)*(2*(C-A)*(Cx-Ax) + 8*B*Bx)/(d*d*d))/2/n1;
00548       n1y = ( 2*(Ay-Cy)/d - (A-C)*(2*(C-A)*(Cy-Ay) + 8*B*By)/(d*d*d))/2/n1;
00549       n2x = (-2*(Ax-Cx)/d + (A-C)*(2*(C-A)*(Cx-Ax) + 8*B*Bx)/(d*d*d))/2/n2;
00550       n2y = (-2*(Ay-Cy)/d + (A-C)*(2*(C-A)*(Cy-Ay) + 8*B*By)/(d*d*d))/2/n2;
00551     }
00552     else {
00553       n1x = 0;
00554       n1y = 0;
00555       n2x = 0;
00556       n2y = 0;
00557     }
00558     ********************************************************************************/
00559 
00560     double n1, n2, n1x, n1y, n2x, n2y;
00561     // when B is zero, these derivatives need to be fixed
00562     if (vcl_fabs(B)>1e-2) {
00563       double f = vcl_sqrt(B*B+(l-A)*(l-A));
00564 
00565       n1 = B/f;
00566       n2 = (l-A)/f;
00567 
00568       n1x = Bx/f - B*(B*Bx + (l-A)*(lx-Ax))/(f*f*f);
00569       n1y = By/f - B*(B*By + (l-A)*(ly-Ay))/(f*f*f);
00570       n2x = (lx-Ax)/f - (l-A)*(B*Bx + (l-A)*(lx-Ax))/(f*f*f);
00571       n2y = (ly-Ay)/f - (l-A)*(B*By + (l-A)*(ly-Ay))/(f*f*f);
00572     }
00573     else {
00574       double f = vcl_sqrt(B*B+(l-C)*(l-C));
00575 
00576       n1 = (l-C)/f;
00577       n2 = B/f;
00578 
00579       n1x = (lx-Cx)/f - (l-C)*(B*Bx + (l-C)*(lx-Cx))/(f*f*f);
00580       n1y = (ly-Cy)/f - (l-C)*(B*By + (l-C)*(ly-Cy))/(f*f*f);
00581       n2x = Bx/f - B*(B*Bx + (l-C)*(lx-Cx))/(f*f*f);
00582       n2y = By/f - B*(B*By + (l-C)*(ly-Cy))/(f*f*f);
00583     }
00584 
00585     //compute Fx and Fy
00586     double Fx = lx*n1x + n1*lxx + n2x*ly + n2*lxy;
00587     double Fy = lx*n1y + n1*lxy + n2y*ly + n2*lyy;
00588 
00589     //save new orientation
00590     edge_orientations[i] = vnl_math::angle_0_to_2pi(vcl_atan2(Fx, -Fy));
00591   }
00592 
00593   double third_order_time = t.real();
00594 
00595   //report timings
00596   vcl_cout << '\n'
00597            << "time taken for conv: " << conv_time << " msec\n"
00598            << "time taken for nms: " << nms_time << " msec\n"
00599            << "time taken for color third-order: " << third_order_time << " msec" << vcl_endl;
00600 
00601   // --- new code ---
00602   t.mark(); //reset timer
00603   for (unsigned i=0; i<edge_locations.size(); i++)
00604   {
00605     vdgl_edgel ed(edge_locations[i].x(),edge_locations[i].y() , mag[i], edge_orientations[i]);
00606     edgels_.push_back(ed);
00607   }
00608   double edgel_encode_time = t.real();
00609   vcl_cout << "time taken for edgel encode: " << edgel_encode_time << " msec" << vcl_endl;
00610 
00611 #if 0
00612   //create a new edgemap from the tokens collected from NMS
00613   brip_edgemap_sptr edge_map = new brip_edgemap(comp1.ni(), comp1.nj());
00614 
00615   for (unsigned i=0; i<edge_locations.size(); i++) {
00616     if (reduce_tokens) {
00617       //only insert one edgel per grid position
00618       int xx = brip_round(edge_locations[i].x());
00619       int yy = brip_round(edge_locations[i].y());
00620 
00621       if (edge_map->edge_cells(yy, xx).size()>0)
00622         continue;
00623 
00624       edge_map->insert(new brip_edgel(edge_locations[i], edge_orientations[i], mag[i], d2f[i]));
00625     }
00626     else { //insert all of them
00627       edge_map->insert(new brip_edgel(edge_locations[i], edge_orientations[i], mag[i], d2f[i]));
00628     }
00629   }
00630 
00631   //add intensity appearance to the edges
00632   brip_add_color_app(comp1, comp2, comp3, edge_map, sigma_, 1); //opt: 0: original , 1: smoothed, 2: Half gaussian
00633 
00634   return edge_map;
00635 #endif
00636 
00637   return true;
00638 }
00639 
00640 void sdet_third_order_edge_det::line_segs(vcl_vector<vsol_line_2d_sptr>& lines)
00641 {
00642   lines.clear();
00643   for (unsigned i = 0; i<edgels_.size(); ++i)
00644   {
00645     double ang = edgels_[i].get_theta();
00646     double x = edgels_[i].x(), y = edgels_[i].y();
00647     double vx = vcl_cos(ang), vy = vcl_sin(ang);
00648     vsol_point_2d_sptr line_start = new vsol_point_2d(x-vx*0.25, y-vy*0.25);
00649     vsol_point_2d_sptr line_end = new vsol_point_2d(x+vx*0.25, y+vy*0.25);
00650     vsol_line_2d_sptr line = new vsol_line_2d(line_start, line_end);
00651     lines.push_back(line);
00652   }
00653 }
00654 
00655 //: save edgels in the edge map file FORMAT, output files have .edg extension
00656 bool sdet_third_order_edge_det::save_edg_ascii(const vcl_string& filename, unsigned ni, unsigned nj, const vcl_vector<vdgl_edgel>& edgels)
00657 {
00658   //1) If file open fails, return.
00659   vcl_ofstream outfp(filename.c_str(), vcl_ios::out);
00660 
00661   if (!outfp) {
00662     vcl_cerr << "*** Error opening file " << filename.c_str() << '\n';
00663     return false;
00664   }
00665 
00666   //2) write out the header block
00667   outfp << "# EDGE_MAP v3.0\n\n"
00668         << "# Format :  [Pixel_Pos]  Pixel_Dir Pixel_Conf  [Sub_Pixel_Pos] Sub_Pixel_Dir Strength Uncer\n\n"
00669         << "WIDTH=" << ni << '\n'
00670         << "HEIGHT=" << nj << '\n'
00671         << "EDGE_COUNT=" << edgels.size()  << '\n'
00672         << '\n' << vcl_endl;
00673 
00674   //save the edgel tokens
00675   for (unsigned k = 0; k < edgels.size(); k++) {
00676     vdgl_edgel edgel = edgels[k];
00677     double x = edgel.x();
00678     double y = edgel.y();
00679 
00680     unsigned ix = (unsigned)x;
00681     unsigned iy = (unsigned)y;
00682     double idir = edgel.get_theta();
00683     double iconf = edgel.get_grad();
00684     double dir = idir, conf = iconf, uncer = 0.0;
00685     outfp << '[' << ix << ", " << iy << "]    "
00686           << idir << ' ' << iconf << "   [" << x << ", " << y << "]   "
00687           << dir << ' ' << conf << ' ' << uncer << vcl_endl;
00688   }
00689 
00690   outfp.close();
00691 
00692   return true;
00693 }