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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.