~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina4/src/vision/stereo/matchable.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**@(#)
  2 **/
  3 /* matchable.c
  4  * 
  5  * generic stereo functions for determining matchability of edge
  6  * sub-strings based upon local properties
  7  * 
  8  * provides an initial prune on ambiguity
  9  * 
 10  * 2 aspects are considered orientation and contrast
 11  * 
 12  * edge orientation varies between -PI and +PI but this depends upon the
 13  * sign of intensity contrast across the edge
 14  * 
 15  * hence 3 factors are dealt with
 16  * 
 17  * similar orientation, same contrast sign, similar contrast value
 18  * 
 19  * for the case where only the orientation is important (ie the sign of
 20  * contrast is allowed to change to allow for accidental viewpoint
 21  * alignments) absolute orientation values which do not include the
 22  * contrast component are computed.
 23  * 
 24  * absolute orientation varies between -PI/2 to PI/2 */
 25 
 26 #include <math.h>
 27 #include <tina/sys.h>
 28 #include <tina/sysfuncs.h>
 29 #include <tina/math.h>
 30 #include <tina/mathfuncs.h>
 31 #include <tina/vision.h>
 32 
 33 /* stereo module static parameter values and set functions
 34  * 
 35  * provides data hiding and limits number of external variables */
 36 
 37 static float low_orient_thres = (float)0.3;
 38 static float hi_orient_thres = (float)1.0;
 39 static float disparity_gradient = (float)0.5;
 40 static float low_con_ratio = (float)0.2;
 41 static float hi_con_ratio = (float)5.0;
 42 
 43 void    es_match_set_low_or_thres(double thres)
 44 {
 45     low_orient_thres = (float)thres;
 46 }
 47 
 48 void    es_match_set_hi_or_thres(double thres)
 49 {
 50     hi_orient_thres = (float)thres;
 51 }
 52 
 53 void    es_match_set_grad_thres(double thres)
 54 {
 55     disparity_gradient = (float)thres;
 56 }
 57 
 58 void    es_match_set_con_ratio(double ratio)
 59 {
 60     low_con_ratio = (float)ratio;
 61     hi_con_ratio = (float)(1.0 / ratio);
 62     ORDER(float, low_con_ratio, hi_con_ratio);
 63 }
 64 
 65 /* calculate the average orientation value of the egels that constitute
 66  * this edge string contour
 67  * 
 68  * the contor will usually be one of the sub strings from the stereo index */
 69 double  es_mean_or(Tstring * es)
 70 {
 71     List *dptr;
 72     List *end;
 73     double  or;
 74 
 75     if (es == NULL)
 76         return (0);
 77 
 78     dptr = es->start;
 79     end = es->end;
 80     or = DD_EDGE(dptr)->orient;
 81     for (; dptr != end;)
 82     {
 83         dptr = dptr->next;
 84         or += DD_EDGE(dptr)->orient;
 85     }
 86     return (or / es->count);
 87 }
 88 
 89 /* calculate the average contrast value of the egels that constitute
 90  * this edge string contour
 91  * 
 92  * the contor will usually be one of the sub strings from the stereo index */
 93 double  es_mean_con(Tstring * es)
 94 {
 95     List *dptr;
 96     List *end;
 97     double  con;
 98 
 99     if (es == NULL)
100         return (0);
101 
102     dptr = es->start;
103     end = es->end;
104     con = DD_EDGE(dptr)->contrast;
105     for (; dptr != end;)
106     {
107         dptr = dptr->next;
108         con += DD_EDGE(dptr)->contrast;
109     }
110     return (con / es->count);
111 }
112 
113 /* test whether the orientation is winthin threshold
114  * 
115  * takes into acount the cyclic nature of orientation using the range
116  * argument
117  * 
118  * in radians 2 choices of range exist: PI    orientation independent of
119  * edge contrast 2PI   orientation dependent upon edge contrast */
120 Bool    orient_less_than_thres(double or, double thres, double range)
121 {
122     return ((or < thres || range - or < thres) ? true : false);
123 }
124 
125 /* test whether orientaions agree within the disparity gradient limit */
126 Bool    orients_within_gradient_limit(double or1, double or2, double dgl)
127 
128 /* disparity gradient limit */
129 {
130     double  cot1, cot2;
131 
132     cot1 = 1.0 / tan(or1);
133     cot2 = 1.0 / tan(or2);
134 
135     if (4 * sqr(cot1 - cot2) <= dgl * (sqr(cot1 + cot2) + 4))
136         return (true);
137     return (false);
138 }
139 
140 /* test whether edge strings orientation values match
141  * 
142  * 
143  * orientation is dependent upon contrast and has range 2PI (-PI to PI) */
144 Bool    es_match_orient(Tstring * es1, Tstring * es2)
145 {
146     double  or1, or2, ordiff;
147 
148     if (es1 == NULL || es2 == NULL)
149         return (false);
150 
151     or1 = es_mean_or(es1);
152     or2 = es_mean_or(es2);
153 
154     ordiff = fabs(or1 - or2);
155     if (orient_less_than_thres(ordiff, low_orient_thres, TWOPI) == true)
156         return (true);
157     if (orient_less_than_thres(ordiff, hi_orient_thres, TWOPI) == false)
158         return (false);
159     return (orients_within_gradient_limit(or1, or2, disparity_gradient));
160 }
161 
162 /* compute absolute orientation
163  * 
164  * this orientation is independent of contrast and has range -PI/2 to PI/2 */
165 double  orient_abs(double or)
166 {
167     int     n;
168 
169     if (or > PIBY2)
170     {
171         n = (int)(or / PI + 1);
172         return (or - n * PI);
173     }
174     if (or < -PIBY2)
175     {
176         n = (int)((-or) / PI + 1);
177         return (or + n * PI);
178     }
179     return (or);
180 }
181 
182 /* test whether edge strings absolute orientation values match
183  * 
184  * this allows contrast reversal to occur between images
185  * 
186  * 
187  * absolute orientation has a range of PI (-PI/2 to PI/2) */
188 Bool    es_match_abs_orient(Tstring * es1, Tstring * es2)
189 {
190     double  or1, or2, ordiff;
191 
192     if (es1 == NULL || es2 == NULL)
193         return (false);
194 
195     or1 = orient_abs(es_mean_or(es1));
196     or2 = orient_abs(es_mean_or(es2));
197 
198     ordiff = fabs(or1 - or2);
199     if (orient_less_than_thres(ordiff, low_orient_thres, PI) == true)
200         return (true);
201     if (orient_less_than_thres(ordiff, hi_orient_thres, PI) == false)
202         return (false);
203     return (orients_within_gradient_limit(or1, or2, disparity_gradient));
204 }
205 
206 /* test whether edge strings contrast values match */
207 Bool    es_match_contrast(Tstring * es1, Tstring * es2)
208 {
209     double  con1, con2;
210     double  con_ratio;
211 
212     if (es1 == NULL || es2 == NULL)
213         return (false);
214 
215     con1 = es_mean_con(es1);
216     con2 = es_mean_con(es2);
217 
218     con_ratio = con1 / con2;
219 
220     return (con_ratio > low_con_ratio && con_ratio < hi_con_ratio) ? true : false;
221 }
222 
223 /* test whether edge strings orientation and contrast values match */
224 Bool    es_match_orandcon(Tstring * es1, Tstring * es2)
225 {
226     if (es_match_contrast(es1, es2) == false)
227         return (false);
228     return (es_match_orient(es1, es2));
229 }
230 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.