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

gevd_detector.cxx

Go to the documentation of this file.
00001 // This is gel/gevd/gevd_detector.cxx
00002 #include "gevd_detector.h"
00003 //:
00004 // \file
00005 // see gevd_detector.h
00006 //
00007 //-----------------------------------------------------------------------------
00008 
00009 #include <vil1/vil1_image.h>
00010 #include <vcl_iostream.h>
00011 #include "gevd_pixel.h"
00012 #include "gevd_float_operators.h"
00013 #include "gevd_step.h"
00014 #include "gevd_bufferxy.h"
00015 #include "gevd_contour.h"
00016 #include <vtol/vtol_edge_2d.h>
00017 
00018 //--------------------------------------------------------------------------------
00019 //
00020 //: Constructors.
00021 //
00022 gevd_detector::gevd_detector(gevd_detector_params& params)
00023   : gevd_detector_params(params),
00024     edgel(NULL), direction(NULL),
00025     locationx(NULL), locationy(NULL), grad_mag(NULL),
00026     angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00027     vertices(NULL), edges(NULL),
00028     filterFactor(2), hysteresisFactor(2.0), noiseThreshold(0.0)
00029 {
00030   if (params.automatic_threshold)
00031     noise = -params.noise_weight;
00032   else
00033     noise = params.noise_multiplier;
00034 
00035   image_float_buf_ = 0;
00036 }
00037 
00038 gevd_detector::gevd_detector(vil1_image img, float smoothSigma, float noiseSigma,
00039                              float contour_factor, float junction_factor, int min_length,
00040                              float maxgap, float min_jump)
00041   : image(img), noise(noiseSigma), edgel(NULL), direction(NULL),
00042     locationx(NULL), locationy(NULL), grad_mag(NULL),
00043     angle(NULL), junctionx(NULL), junctiony(NULL), njunction(0),
00044     vertices(NULL), edges(NULL),
00045     filterFactor(2), hysteresisFactor(2.0), noiseThreshold(0.0)
00046 {
00047   gevd_detector_params::smooth = smoothSigma;
00048   gevd_detector_params::contourFactor = contour_factor;
00049   gevd_detector_params::junctionFactor = junction_factor;
00050   gevd_detector_params::minLength = min_length;
00051   gevd_detector_params::maxGap = maxgap;
00052   gevd_detector_params::minJump = min_jump;
00053   image_float_buf_ = 0;
00054 }
00055 
00056 //--------------------------------------------------------------------------
00057 //: UnProtect lists that are protected by Contour::
00058 void gevd_detector::UnProtectLists()
00059 {
00060 #if 0 // commented out
00061   if (edges)//Need to mimic the protection of Contour
00062   for (CoolListP<Edge*>::iterator eit = edges->begin();
00063        eit != edges->end(); eit++)
00064     (*eit)->UnProtect();
00065   if (vertices)
00066     for (CoolListP<Vertex*>::iterator vit = vertices->begin();
00067          vit != vertices->end(); vit++)
00068       (*vit)->UnProtect();
00069 #endif
00070 }
00071 
00072 
00073 //: Destructor.
00074 //  Caller has an obligation to clear all the created edges and vertices.
00075 gevd_detector::~gevd_detector()
00076 {
00077   ClearData();
00078 }
00079 
00080 
00081 //: Clear data buffer.  Protected.
00082 //
00083 void gevd_detector::ClearData()
00084 {
00085   delete edgel; delete direction; delete locationx; delete locationy;
00086   delete grad_mag; delete angle;
00087   delete [] junctionx; delete [] junctiony;
00088   delete vertices;
00089   delete edges;
00090   if (image_float_buf_) delete image_float_buf_;
00091 }
00092 
00093 
00094 //: Detect the contour, a list of edges and vertices are generated.
00095 //
00096 bool  gevd_detector::DoContour()
00097 {
00098   if (edges && vertices) return true;
00099 
00100   if (!DoStep()) {
00101     vcl_cout << "***Fail on DoContour.\n";
00102     return false;
00103   }
00104   gevd_contour::ClearNetwork(edges, vertices);       // delete vertices/edges
00105   gevd_contour contour(this->hysteresisFactor*this->noiseThreshold, this->minLength,
00106                   this->minJump*this->noiseThreshold, this->maxGap);
00107   bool t  = contour.FindNetwork(*edgel, njunction, // first, find isolated
00108                                 junctionx, junctiony,   // chains/cycles
00109                                 edges, vertices);
00110   if (!t) {
00111     vcl_cout << "***Fail on FindNetwork.\n";
00112     return false;
00113   }
00114 
00115   vcl_vector<vtol_edge_2d_sptr>::iterator edge;
00116   vcl_cout << "IN DoContour before SubPixelAccuracy\n";
00117   this->print(vcl_cout);
00118   for ( edge = edges->begin() ; edge != edges->end(); ++edge)
00119     {
00120     vcl_cout << "Edgel output from DoContour:";
00121     (*edge)->describe(vcl_cout, 2);
00122     }
00123 
00124   contour.SubPixelAccuracy(*edges, *vertices, // insert subpixel
00125                            *locationx, *locationy); // accuracy
00126   if (this->spacingp)           // reduce zig-zags and space out pixels
00127     gevd_contour::EqualizeSpacing(*edges); // in chains
00128   if (this->borderp)            // insert a virtual contour to enforce
00129     contour.InsertBorder(*edges, *vertices); // closure at border
00130   if (grad_mag&&angle)
00131     gevd_contour::SetEdgelData(*grad_mag, *angle, *edges); //Continuous edgel orientation.
00132 
00133 //   const RectROI* roi = image->GetROI();
00134 //   gevd_contour::Translate(*edges, *vertices, // display location at center
00135 //                      roi->GetOrigX()+0.5, // of pixel instead of
00136 //                      roi->GetOrigY()+0.5); // upper-left corner
00137 
00138   return true;
00139 }
00140 
00141 //--------------------------------------------------------------------------------
00142 //
00143 //: Detect the fold contour, a list of edges and vertices are generated.
00144 //
00145 bool  gevd_detector::DoFoldContour()
00146 {
00147   if (edges && vertices) return true;
00148 
00149 //   if (!DoFold()) {
00150 //     vcl_cout << "***Fail on DoFoldContour.\n";
00151 //     return false;
00152 //   }
00153   gevd_contour::ClearNetwork(edges, vertices);       // delete vertices/edges
00154   gevd_contour contour(this->hysteresisFactor*this->noiseThreshold,
00155                   this->minLength, this->minJump*this->noiseThreshold,
00156                   this->maxGap);
00157 
00158   bool t  = contour.FindNetwork(*edgel, njunction, // first, find isolated
00159                                 junctionx, junctiony,   // chains/cycles
00160                                 edges, vertices);
00161   if (!t) {
00162     vcl_cout << "***Fail on FindNetwork.\n";
00163     return false;
00164   }
00165   contour.SubPixelAccuracy(*edges, *vertices, // insert subpixel
00166                            *locationx, *locationy); // accuracy
00167   if (this->spacingp)           // reduce zig-zags and space out pixels
00168     gevd_contour::EqualizeSpacing(*edges); // in chains
00169   if (this->borderp)            // insert a virtual contour to enforce
00170     contour.InsertBorder(*edges, *vertices); // closure at border
00171   if (grad_mag&&angle)
00172     gevd_contour::SetEdgelData(*grad_mag, *angle, *edges); //Continuous edgel orientation.
00173 
00174 //   const RectROI* roi = image->GetROI();
00175 //   gevd_contour::Translate(*edges, *vertices, // display location at center
00176 //                      roi->GetOrigX()+0.5, // of pixel instead of
00177 //                      roi->GetOrigY()+0.5); // upper-left corner
00178 
00179   return true;
00180 }
00181 
00182 //---------------------------------------------------------------------------
00183 //
00184 //: Detect step profiles in the image, using dG+NMS+extension.
00185 //
00186 bool gevd_detector::DoStep()
00187 {
00188   if (edgel) return true;
00189 
00190   const gevd_bufferxy* source = GetBufferFromImage();
00191   if (!source) {
00192     vcl_cout << " cannot get image buffer\n";
00193     return false;
00194   }
00195 
00196   gevd_step step(this->smooth, this->noise, this->contourFactor, this->junctionFactor);
00197   step.DetectEdgels(*source, edgel, direction, locationx, locationy, grad_mag, angle);
00198 
00199   if (this->junctionp) {                // extension to real/virtual contours
00200     njunction = step.RecoverJunctions(*source,
00201                                       *edgel, *direction,
00202                                       *locationx, *locationy,
00203                                       junctionx, junctiony);
00204   } else {
00205     njunction = 0;
00206     delete [] junctionx; junctionx = NULL;
00207     delete [] junctiony; junctiony = NULL;
00208   }
00209 
00210   this->noiseThreshold = step.NoiseThreshold();
00211 
00212   return edgel!=NULL;
00213 }
00214 
00215 #if 0 // commented out
00216 //---------------------------------------------------------------------------
00217 //
00218 //: Detect fold profiles in the image, using dG+NMS+extension.
00219 //
00220 bool gevd_detector::DoFold()
00221 {
00222   if (edgel) return true;
00223 
00224   const BufferXY* source = GetBufferFromImage();
00225   if (!source) {
00226     vcl_cout << " cannot get image buffer\n";
00227     return false;
00228   }
00229 
00230   Fold fold(this->smooth, this->noise,
00231             this->contourFactor,
00232             this->junctionFactor);
00233   fold.DetectEdgels(*source, edgel, direction,
00234                     locationx, locationy, true, //Flag to compute mag, angle
00235                     grad_mag, angle); //Reusing grad_mag, actually |d2G|
00236 
00237   if (this->junctionp) {                // extension to real/virtual contours
00238     njunction = fold.RecoverJunctions(*source,
00239                                       *edgel, *direction,
00240                                       *locationx, *locationy,
00241                                       junctionx, junctiony);
00242   } else {
00243     njunction = 0;
00244     delete [] junctionx; junctionx = NULL;
00245     delete [] junctiony; junctiony = NULL;
00246   }
00247 
00248   this->noiseThreshold = fold.NoiseThreshold();
00249   return edgel!=NULL;
00250 }
00251 #endif // 0
00252 
00253 //--------------------------------------------------------------------------------
00254 //
00255 //: Transform data in the image as float buffer.
00256 //
00257 gevd_bufferxy* gevd_detector::GetBufferFromImage()
00258 {
00259   if (image_float_buf_) return image_float_buf_;
00260 
00261   if (!image)
00262   {
00263     vcl_cout << "No image\n";
00264     return 0;
00265   }
00266 
00267   //  RectROI* roi = image->GetROI(); // find user-selected region of interest
00268   //  int sizex = roi->GetSizeX();
00269   //  int sizey = roi->GetSizeY();
00270   int sizey= image.rows();
00271   int sizex= image.cols();
00272 
00273   image_float_buf_ = new gevd_bufferxy(sizex, sizey,8*sizeof(float));
00274 
00275 #if 0 // commented out
00276   if (image->GetPixelType() == Image::FLOAT)
00277   {
00278     image->GetSection(image_float_buf_->GetBuffer(),
00279                       roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00280     return image_float_buf_;
00281   }
00282 #endif
00283 
00284   //   gevd_bufferxy image_buf(sizex, sizey, image->GetBitsPixel());
00285   gevd_bufferxy image_buf(sizex, sizey, image.bits_per_component());
00286 
00287 #if 0 // commented out
00288   image->GetSection(image_buf.GetBuffer(),      // copy bytes image into buf
00289                     roi->GetOrigX(), roi->GetOrigY(), sizex, sizey);
00290 #endif
00291 
00292   image.get_section(image_buf.GetBuffer(),     // copy bytes image into buf
00293                     0, 0, sizex, sizey);
00294 
00295   if (! gevd_float_operators::BufferToFloat(image_buf, *image_float_buf_))
00296   {
00297     delete image_float_buf_;
00298     image_float_buf_ = 0;
00299   }
00300 
00301   return image_float_buf_;
00302 }
00303 
00304 // If we're setting a new image, we need to start from scratch
00305 void gevd_detector::SetImage(vil1_image img)
00306 {
00307   image = img;
00308   if (image_float_buf_) {
00309     delete image_float_buf_;
00310     image_float_buf_ = 0;
00311   }
00312   if (edgel) delete edgel;
00313   if (vertices) delete vertices;
00314   if (direction) delete direction;
00315   if (locationx) delete locationx;
00316   if (locationy) delete locationy;
00317   if (grad_mag) delete grad_mag;
00318   if (angle) delete angle;
00319   if (junctionx) delete [] junctionx;
00320   if (junctiony) delete [] junctiony;
00321 }
00322 
00323 void gevd_detector::print(vcl_ostream &strm) const
00324 {
00325   strm << "gevd_Detector:\n"
00326        << "    noise " << noise << vcl_endl
00327        << "    njunction " << njunction << vcl_endl
00328        << "    num vertices " << vertices->size() << vcl_endl
00329        << "    num edges " << edges->size() << vcl_endl
00330        << "    filterfactor " << filterFactor << vcl_endl
00331        << "    hysteresisfactor " << hysteresisFactor << vcl_endl
00332        << "    noiseThreshold " << noiseThreshold << vcl_endl
00333        << "    smooth " <<   smooth << vcl_endl // Smoothing kernel sigma
00334        << "    noise_weight " <<   noise_weight << vcl_endl //The weight between sensor noise and texture noise
00335        << "    noise_multiplier " <<   noise_multiplier << vcl_endl // The overal noise threshold scale factor
00336        << "    automatic_threshold " <<   automatic_threshold << vcl_endl // Determine the threshold values from image
00337        << "    aggressive_junction_closure " <<   aggressive_junction_closure << vcl_endl //Close junctions agressively
00338        << "    minLength " <<   minLength << vcl_endl          // minimum chain length
00339        << "    contourFactor " <<   contourFactor << vcl_endl  // Threshold along contours
00340        << "    junctionFactor " <<   junctionFactor << vcl_endl //Threshold at junctions
00341        << "    filterFactor " <<   filterFactor << vcl_endl    // ratio of sensor to texture noise
00342        << "    junctionp " <<   junctionp << vcl_endl // recover missing junctions
00343        << "    minJump " <<   minJump << vcl_endl  // change in strength at junction
00344        << "    maxGap " <<   maxGap << vcl_endl   // Bridge small gaps up to max_gap across.
00345        << "    spacingp " <<   spacingp << vcl_endl  // equalize spacing?
00346        << "    borderp " <<   borderp << vcl_endl   // insert virtual border for closure?
00347        << "    corner_angle " <<   corner_angle << vcl_endl // smallest angle at corner
00348        << "    separation " <<   separation << vcl_endl // |mean1-mean2|/sigma
00349        << "    min_corner_length " <<   min_corner_length << vcl_endl // min length to find corners
00350        << "    cycle " <<   cycle << vcl_endl // number of corners in a cycle
00351        << "    ndimension " <<   ndimension << vcl_endl // spatial dimension of edgel chains.
00352        << vcl_endl;
00353 }

Generated on Thu Jan 10 14:47:16 2008 for contrib/gel/gevd by  doxygen 1.4.4