1 //:
2 // \file
3 #include <sstream>
4 #include <iostream>
5 #include "gevd_detector_params.h"
6 #ifdef _MSC_VER
7 #  include "vcl_msvc_warnings.h"
8 #endif
9 
10 //------------------------------------------------------------------------
11 // Constructors
12 //
13 
gevd_detector_params(const gevd_detector_params & dp)14 gevd_detector_params::gevd_detector_params(const gevd_detector_params& dp)
15   : gevd_param_mixin()
16 {
17   InitParams(dp.smooth, dp.noise_weight, dp.noise_multiplier,
18              dp.automatic_threshold, dp.aggressive_junction_closure,
19              dp.minLength, dp.maxGap, dp.minJump, dp.contourFactor,
20              dp.junctionFactor, dp.junctionp, dp.spacingp, dp.borderp,
21              dp.peaks_only, dp.valleys_only,
22              dp.corner_angle, dp.separation, dp.min_corner_length,
23              dp.cycle, dp.ndimension);
24 }
25 
gevd_detector_params(float smooth_sigma,float noise_w,float noise_m,bool automatic_t,int aggressive_jc,int minl,float maxgp,float minjmp,float contour_f,float junction_f,bool recover_j,bool equal_spacing,bool follow_b,bool peaks_only,bool valleys_only,float ang,float sep,int min_corner_len,int cyc,int ndim)26 gevd_detector_params::gevd_detector_params(float smooth_sigma, float noise_w,
27                                            float noise_m, bool automatic_t,
28                                            int aggressive_jc, int minl,
29                                            float maxgp, float minjmp,
30                                            float contour_f, float junction_f,
31                                            bool recover_j, bool equal_spacing,
32                                            bool follow_b,
33                                            bool peaks_only,
34                                            bool valleys_only,
35                                            float ang, float sep, int min_corner_len,
36                                            int cyc, int ndim)
37 {
38   InitParams(smooth_sigma, noise_w, noise_m, automatic_t,
39              aggressive_jc, minl, maxgp, minjmp,
40              contour_f, junction_f, recover_j, equal_spacing,
41              follow_b, peaks_only, valleys_only,
42              ang, sep, min_corner_len,
43              cyc, ndim);
44 }
45 
InitParams(float smooth_sigma,float noise_w,float noise_m,bool automatic_t,int aggressive_jc,int minl,float maxgp,float minjmp,float contour_f,float junction_f,bool recover_j,bool equal_spacing,bool follow_b,bool only_peaks,bool only_valleys,float ang,float sep,int min_corner_len,int cyc,int ndim)46 void gevd_detector_params::InitParams(float smooth_sigma, float noise_w,
47                                       float noise_m, bool automatic_t,
48                                       int aggressive_jc, int minl,
49                                       float maxgp, float minjmp,
50                                       float contour_f, float junction_f,
51                                       bool recover_j, bool equal_spacing,
52                                       bool follow_b,
53                                       bool only_peaks,
54                                       bool only_valleys,
55                                       float ang, float sep, int min_corner_len,
56                                       int cyc, int ndim)
57 {
58   //Step contour parameters
59   smooth = smooth_sigma;
60   noise_weight = noise_w;
61   noise_multiplier = noise_m;
62   automatic_threshold = automatic_t;
63   aggressive_junction_closure = aggressive_jc;
64   minLength = minl;
65   spacingp = equal_spacing;
66   borderp = follow_b;
67   // Fold Parameters
68   peaks_only = only_peaks;
69   valleys_only = only_valleys;
70   //Corner parameters
71   corner_angle = ang;
72   separation = sep;
73   min_corner_length = min_corner_len;
74   cycle = cyc;
75   ndimension = ndim;
76   // The remaining parameters are set according to the state of
77   // Aggressive junction closure.  If the value is <0 then the
78   // state of junction parameters is derived from the constructor
79   // arguments.  If the value is >0 then the variable is assumed to
80   // be a bool and the parameters are determined from computation.
81 
82   if (aggressive_junction_closure<0)
83   {
84     junctionp = recover_j;
85     contourFactor = contour_f;
86     junctionFactor = junction_f;
87     maxGap = maxgp;
88     minJump = minjmp;
89   }
90 
91   // Perform the sanity check anyway.
92   SanityCheck();
93 }
94 
set_noise_weight(float nw)95 void gevd_detector_params::set_noise_weight(float nw)
96 {
97   noise_weight = nw;
98 }
99 
set_noise_multiplier(float nm)100 void gevd_detector_params::set_noise_multiplier(float nm)
101 {
102   noise_multiplier = nm;
103 }
104 
set_automatic_threshold(bool at)105 void gevd_detector_params::set_automatic_threshold(bool at)
106 {
107   automatic_threshold = at;
108 }
109 
set_aggressive_junction_closure(int ajc)110 void gevd_detector_params::set_aggressive_junction_closure(int ajc)
111 {
112   aggressive_junction_closure = ajc;
113 }
114 
set_close_borders(bool cb)115 void gevd_detector_params::set_close_borders(bool cb)
116 {
117   borderp = cb;
118 }
119 
120 
121 //-----------------------------------------------------------------------------
122 //
123 //: Checks that parameters are within acceptable bounds.
124 // This method is always called after a parameter modifier has changed the prms.
125 //
SanityCheck()126 bool gevd_detector_params::SanityCheck()
127 {
128   std::stringstream msg;
129   bool valid = true;
130 
131   if (aggressive_junction_closure >0 )
132   {
133     junctionp = true;
134     contourFactor = noise_multiplier;
135     junctionFactor = .5f*noise_multiplier;
136     maxGap = 4.f;
137     minJump = .1f;
138   }
139   if (aggressive_junction_closure == 0)
140   {
141     junctionp = true;
142     contourFactor = noise_multiplier;
143     junctionFactor = 1.5f*noise_multiplier;
144     maxGap = 2.2f;
145     minJump = 1.0f;
146   }
147   if (smooth <= 0)      // Standard deviation of the smoothing kernel
148   {
149     msg << "ERROR: Value of gaussian smoothing sigma is not positive: "
150         << smooth << " <= 0\0";
151     smooth = smooth==0 ? 1.0f : -smooth;
152   }
153   // MPP 2/11//2002
154   // Invert noise_weight sign per Jim G.
155   if (noise_weight > 0.0 || noise_weight < -1.0)   // Noise weighting factor
156   {
157     msg << "ERROR: Value of noise weight must be between -1 and 0, not "
158         << noise_weight << '\0';
159     noise_weight = -0.5f;
160   }
161   if (noise_multiplier <= 0)    // The over all noise scale factor
162   {
163     msg << "ERROR: Value of noise scale factor is not positive: "
164         << noise_multiplier << " <= 0\0";
165     noise_multiplier = noise_multiplier==0 ? 1.0f : -noise_multiplier;
166   }
167   if (minLength <= 3)   // Edgel chain length
168   {
169     msg << "ERROR: Value of minimum chain length is too low: "
170         << minLength << " <= 3\0";
171     minLength = 3;
172   }
173   if (maxGap <= 0)      // Chain gaps to jump
174   {
175     msg << "ERROR: Value of maximum gap is not positive: "
176         << maxGap << " <= 0\0";
177     maxGap = 2.2f;
178   }
179   if (minJump <= 0)     // Jump to close a junction
180   {
181     msg << "ERROR: Value of min jump junction is not positive: "
182         << minJump << " <= 0\0";
183     maxGap = 1.0f;
184   }
185   if (contourFactor <= 0)       // Threshold in following a contour
186   {
187     msg << "ERROR: Value of contour factor is not positive: "
188         << contourFactor << " <= 0\0";
189     contourFactor = 1.0f;
190   }
191   if (junctionFactor<= 0)       // Threshold in following a junction
192   {
193     msg << "ERROR: Value of junction factor is not positive: "
194         << junctionFactor << " <= 0\0";
195     maxGap = 1.5f;
196   }
197   if (peaks_only&&valleys_only)
198   {
199     msg << "ERROR: Can restrict to either peaks or valleys, not both\0";
200     valid = false;
201   }
202   if (corner_angle < 5.0f)
203   {
204     msg << "ERROR: Value of corner angle is too low: "
205         << corner_angle << " < 5\0";
206     valid = false;
207   }
208   if (separation < 1.0f)
209   {
210     msg << "ERROR: Value of corner separation is too low: "
211         << separation << " < 1\0";
212     valid = false;
213   }
214   if (min_corner_length < 5)
215   {
216     msg << "ERROR: Value of minimum chain length too low: "
217         << min_corner_length << " < 5\0";
218     valid = false;
219   }
220   if (cycle > 10)
221   {
222     msg << "ERROR: Value of number of corners in a 1-cycle is too high: "
223         << cycle << " > 10\0";
224     valid = false;
225   }
226   if (ndimension > 3)
227   {
228     msg << "ERROR: Value of corner spatial dimension is too large: "
229         << ndimension << " > 3\0";
230     valid = false;
231   }
232 
233   SetErrorMsg(msg.str().c_str());
234   return valid;
235 }
236 
237 //------------------------------------------------------------
238 //: Describe the parameters to a parameter modifier.
239 #if 0 //not implemented in vxl
240 void gevd_detector_params::Describe(ParamModifier& /*mod*/)
241 {
242   std::cerr << "gevd_detector_params::Describe() not yet implemented\n";
243 
244   static UIChoice JunctionClosure[] =
245   {
246     UIChoicePair("Default",-1),
247     UIChoicePair("Weak",0),
248     UIChoicePair("Aggressive",1),
249     UIChoice_finish
250   };
251 
252   // These are the parameters which the user is likely to want to set.
253   mod.Name("EdgeDetector Parameters(VanDuc)");
254   mod.AddParam("Sigma", smooth);
255   mod.AddParam("Noise Weight", noise_weight);
256   mod.AddParam("Noise Multiplier", noise_multiplier);
257   mod.AddParam("Automatic Threshold", automatic_threshold,
258                ParamModifier::OnOff);
259   mod.AddParam("Junction Closure", aggressive_junction_closure,
260                JunctionClosure);
261 }
262 #endif
263