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