contrib/brl/bseg/sdet/sdet_detector_params.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 #include "sdet_detector_params.h"
00004 #include <vcl_string.h>
00005 #include <vcl_sstream.h>
00006 #include <vcl_iostream.h>
00007 
00008 //------------------------------------------------------------------------
00009 // Constructors
00010 //
00011 
00012 sdet_detector_params::sdet_detector_params(const sdet_detector_params& dp)
00013   : gevd_param_mixin()
00014 {
00015   InitParams(dp.smooth, dp.noise_weight, dp.noise_multiplier,
00016              dp.automatic_threshold, dp.aggressive_junction_closure,
00017              dp.minLength, dp.maxGap, dp.minJump, dp.contourFactor,
00018              dp.junctionFactor, dp.junctionp, dp.spacingp, dp.borderp,
00019              dp.peaks_only, dp.valleys_only,
00020              dp.corner_angle, dp.separation, dp.min_corner_length,
00021              dp.cycle, dp.ndimension);
00022 }
00023 
00024 sdet_detector_params::sdet_detector_params(float smooth_sigma, float noise_w,
00025                                            float noise_m, bool automatic_t,
00026                                            int aggressive_jc, int minl,
00027                                            float maxgp, float minjmp,
00028                                            float contour_f, float junction_f,
00029                                            bool recover_j, bool equal_spacing,
00030                                            bool follow_b,
00031                                            bool peaks_only,
00032                                            bool valleys_only,
00033                                            float ang, float sep, int min_corner_len,
00034                                            int cyc, int ndim)
00035 {
00036   InitParams(smooth_sigma, noise_w, noise_m, automatic_t,
00037              aggressive_jc, minl, maxgp, minjmp,
00038              contour_f, junction_f, recover_j, equal_spacing,
00039              follow_b, peaks_only, valleys_only,
00040              ang, sep, min_corner_len,
00041              cyc, ndim);
00042 }
00043 
00044 void sdet_detector_params::InitParams(float smooth_sigma, float noise_w,
00045                                       float noise_m, bool automatic_t,
00046                                       int aggressive_jc, int minl,
00047                                       float maxgp, float minjmp,
00048                                       float contour_f, float junction_f,
00049                                       bool recover_j, bool equal_spacing,
00050                                       bool follow_b,
00051                                       bool only_peaks,
00052                                       bool only_valleys,
00053                                       float ang, float sep, int min_corner_len,
00054                                       int cyc, int ndim)
00055 {
00056   //Step contour parameters
00057   smooth = smooth_sigma;
00058   noise_weight = noise_w;
00059   noise_multiplier = noise_m;
00060   automatic_threshold = automatic_t;
00061   aggressive_junction_closure = aggressive_jc;
00062   minLength = minl;
00063   spacingp = equal_spacing;
00064   borderp = follow_b;
00065   junctionp = recover_j;
00066   // Fold Parameters
00067   peaks_only = only_peaks;
00068   valleys_only = only_valleys;
00069   //Corner parameters
00070   corner_angle = ang;
00071   separation = sep;
00072   min_corner_length = min_corner_len;
00073   cycle = cyc;
00074   ndimension = ndim;
00075   // The remaining parameters are set according to the state of
00076   // aggressive junction closure.  If the value is <0 then the
00077   // state of junction parameters is derived from the constructor
00078   // arguments.  If the value is >0 then the variable is assumed to
00079   // be a bool and the parameters are determined from computation.
00080 
00081   if (aggressive_junction_closure<0)
00082   {
00083     junctionp = recover_j;
00084     contourFactor = contour_f;
00085     junctionFactor = junction_f;
00086     maxGap = maxgp;
00087     minJump = minjmp;
00088   }
00089 
00090   // Perform the sanity check anyway.
00091   SanityCheck();
00092 }
00093 
00094 void sdet_detector_params::set_noise_weight(float nw)
00095 {
00096   noise_weight = nw;
00097 }
00098 
00099 void sdet_detector_params::set_noise_multiplier(float nm)
00100 {
00101   noise_multiplier = nm;
00102 }
00103 
00104 void sdet_detector_params::set_automatic_threshold(bool at)
00105 {
00106   automatic_threshold = at;
00107 }
00108 
00109 void sdet_detector_params::set_aggressive_junction_closure(int ajc)
00110 {
00111   aggressive_junction_closure = ajc;
00112 }
00113 
00114 void sdet_detector_params::set_close_borders(bool cb)
00115 {
00116   borderp = cb;
00117 }
00118 
00119 
00120 //-----------------------------------------------------------------------------
00121 //
00122 //: Checks that parameters are within acceptable bounds.
00123 // This method is always called after a parameter modifier has changed the prms.
00124 //
00125 bool sdet_detector_params::SanityCheck()
00126 {
00127   vcl_stringstream msg;
00128   bool valid = true;
00129 
00130   if (aggressive_junction_closure >0 )
00131   {
00132     junctionp = true;
00133     contourFactor = noise_multiplier;
00134     junctionFactor = .5f*noise_multiplier;
00135     maxGap = 4.f;
00136     minJump = .1f;
00137   }
00138   if (aggressive_junction_closure == 0)
00139   {
00140     contourFactor = noise_multiplier;
00141     junctionFactor = 1.5f*noise_multiplier;
00142     maxGap = 2.2f;
00143     minJump = 1.0f;
00144   }
00145   if (smooth <= 0)      // Standard deviation of the smoothing kernel
00146   {
00147     msg << "ERROR: Value of gaussian smoothing sigma is not positive: "
00148         << smooth << " <= 0\0";
00149     smooth = smooth==0 ? 1.0f : -smooth;
00150   }
00151   // MPP 2/11//2002
00152   // Invert noise_weight sign per Jim G.
00153   if (noise_weight > 0.0 || noise_weight < -1.0)   // Noise weighting factor
00154   {
00155     msg << "ERROR: Value of noise weight must be between -1 and 0, not "
00156         << noise_weight << '\0';
00157     noise_weight = -0.5f;
00158   }
00159   if (noise_multiplier <= 0)    // The over all noise scale factor
00160   {
00161     msg << "ERROR: Value of noise scale factor is not positive: "
00162         << noise_multiplier << " <= 0\0";
00163     noise_multiplier = noise_multiplier==0 ? 1.0f : -noise_multiplier;
00164   }
00165   if (minLength <= 3)   // Edgel chain length
00166   {
00167     msg << "ERROR: Value of minimum chain length is too low: "
00168         << minLength << " <= 3\0";
00169     minLength = 3;
00170   }
00171   if (maxGap <= 0)      // Chain gaps to jump
00172   {
00173     msg << "ERROR: Value of maximum gap is not positive: "
00174         << maxGap << " <= 0\0";
00175     maxGap = 2.2f;
00176   }
00177   if (minJump <= 0)     // Jump to close a junction
00178   {
00179     msg << "ERROR: Value of min jump junction is not positive: "
00180         << minJump << " <= 0\0";
00181     maxGap = 1.0f;
00182   }
00183   if (contourFactor <= 0)       // Threshold in following a contour
00184   {
00185     msg << "ERROR: Value of contour factor is not positive: "
00186         << contourFactor << " <= 0\0";
00187     contourFactor = 1.0f;
00188   }
00189   if (junctionFactor<= 0)       // Threshold in following a junction
00190   {
00191     msg << "ERROR: Value of junction factor is not positive: "
00192         << junctionFactor << " <= 0\0";
00193     maxGap = 1.5f;
00194   }
00195   if (peaks_only&&valleys_only)
00196   {
00197     msg << "ERROR: Can restrict to either peaks or valleys, not both\0";
00198     valid = false;
00199   }
00200   if (corner_angle < 5.0f)
00201   {
00202     msg << "ERROR: Value of corner angle is too low: "
00203         << corner_angle << " < 5\0";
00204     valid = false;
00205   }
00206   if (separation < 1.0f)
00207   {
00208     msg << "ERROR: Value of corner separation is too low: "
00209         << separation << " < 1\0";
00210     valid = false;
00211   }
00212   if (min_corner_length < 5)
00213   {
00214     msg << "ERROR: Value of minimum chain length too low: "
00215         << min_corner_length << " < 5\0";
00216     valid = false;
00217   }
00218   if (cycle > 10)
00219   {
00220     msg << "ERROR: Value of number of corners in a 1-cycle is too high: "
00221         << cycle << " > 10\0";
00222     valid = false;
00223   }
00224   if (ndimension > 3)
00225   {
00226     msg << "ERROR: Value of corner spatial dimension is too large: "
00227         << ndimension << " > 3\0";
00228     valid = false;
00229   }
00230 
00231   SetErrorMsg(msg.str().c_str());
00232   return valid;
00233 }
00234 
00235 vcl_ostream& operator << (vcl_ostream& os, const sdet_detector_params& dp)
00236 {
00237   vcl_string sa, st;
00238   if (dp.aggressive_junction_closure>0)
00239     sa = "yes";
00240   else
00241     sa = "no";
00242   if (dp.automatic_threshold)
00243     st = "yes";
00244   else
00245     st = "no";
00246 
00247   return
00248   os << "Edge Detector Params:\n"
00249      << " Smooth Sigma " << dp.smooth << vcl_endl
00250      << " Noise Weight " << dp.noise_weight << vcl_endl
00251      << " Noise Multiplier " << dp.noise_multiplier << vcl_endl
00252      << " Automatic Threshold? " << st << vcl_endl
00253      << " Aggressive Closure " << sa << vcl_endl
00254      << " Recover Junctions " << dp.junctionp << vcl_endl
00255      << " Minimum Chain Length " << dp.minLength << vcl_endl
00256      << " Peaks Only " << dp.peaks_only << vcl_endl
00257      << " Valleys Only " << dp.valleys_only << vcl_endl << vcl_endl
00258      << "Corner Detection Params:\n"
00259      << " Corner Angle " << dp.corner_angle << vcl_endl
00260      << " Corner Separation " << dp.separation  << vcl_endl
00261      << " Min Corner Length " << dp.min_corner_length << vcl_endl
00262      << " Close borders " << dp.borderp << vcl_endl << vcl_endl;
00263 }
00264 #if 0
00265 //------------------------------------------------------------
00266 //: Describe the parameters to a parameter modifier.
00267 void sdet_detector_params::Describe(ParamModifier& /* mod */)
00268 {
00269 //   static UIChoice JunctionClosure[] =
00270 //   {
00271 //     UIChoicePair("Default",-1),
00272 //     UIChoicePair("Weak",0),
00273 //     UIChoicePair("Aggressive",1),
00274 //     UIChoice_finish
00275 //   };
00276 
00277 //   // These are the parameters which the user is likely to want to set.
00278 //   mod.Name("EdgeDetector Parameters(VanDuc)");
00279 //   mod.AddParam("Sigma", smooth);
00280 //   mod.AddParam("Noise Weight", noise_weight);
00281 //   mod.AddParam("Noise Multiplier", noise_multiplier);
00282 //   mod.AddParam("Automatic Threshold", automatic_threshold,
00283 //             ParamModifier::OnOff);
00284 //   mod.AddParam("Junction Closure", aggressive_junction_closure,
00285 //             JunctionClosure);
00286 }
00287 #endif