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

Linux Cross Reference
Tina4/src/vision/edge/edge_strings.c

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

  1 /**@(#)
  2 **/
  3 #include <math.h>
  4 #include <tina/sys.h>
  5 #include <tina/sysfuncs.h>
  6 #include <tina/math.h>
  7 #include <tina/mathfuncs.h>
  8 #include <tina/vision.h>
  9 #include <tina/visionfuncs.h>
 10 
 11 /* ARGSUSED quieten lint */
 12 static void edge_add_prop_def(Edgel * e, int type, Prop_def * pdef)
 13 {
 14     if (pdef == NULL)
 15         return;
 16     e->props = proplist_addifnp(e->props, (void *) pdef->prop, pdef->type, pdef->free_func, pdef->dofree);
 17 }
 18 
 19 void    edge_add_prop(Edgel * e, void *ptr, int type, void (*free_func) ( /* ??? */ ), Bool dofree)
 20 {
 21     if (e == NULL)
 22         return;
 23     e->props = proplist_addifnp(e->props, (void *) ptr, type, free_func, dofree);
 24 }
 25 
 26 void    es_add_to_prop_list(Tstring * s, void *ptr, int type, void (*free_func) ( /* ??? */ ), Bool dofree)
 27 {
 28     Prop_def pdef;
 29 
 30     if (s == NULL)
 31         return;
 32 
 33     pdef.prop = ptr;
 34     pdef.type = type;
 35     pdef.free_func = free_func;
 36     pdef.dofree = dofree;
 37 
 38     str_apply_func(s, edge_add_prop_def, (void *) &pdef);
 39 }
 40 
 41 /* code to pick general pos2 strings */
 42 
 43 Bool    dist_to_pos2(void *ptr, int type, Vec2 * pp, double *dist)
 44 {
 45     if (ptr == NULL)
 46         return (false);
 47 
 48     switch (type)
 49     {
 50     case VEC2:
 51         *dist = vec2_mod(vec2_diff(*pp, *(Vec2 *) ptr));
 52         return (true);
 53     case EDGE:
 54         *dist = vec2_mod(vec2_diff(*pp, ((Edgel *) ptr)->pos));
 55         return (true);
 56     default:
 57         return (false);
 58     }
 59 }
 60 
 61 Tstring *es_closest2(List * strings, Vec2 pos)
 62 {
 63     Tstring *str_list_get_min();
 64 
 65     return (str_list_get_min(strings, dist_to_pos2, (void *) &pos));
 66 }
 67 
 68 void   *es_closest_pos2(List * strings, Vec2 pos, int *type)
 69 {
 70     Tstring *str = es_closest2(strings, pos);
 71     List *dptr;
 72 
 73     if (str == NULL)
 74         return (NULL);
 75 
 76     dptr = str_get_min(str, dist_to_pos2, (void *) &pos);
 77     if (dptr == NULL)
 78         return (NULL);
 79 
 80     *type = dptr->type;
 81     return (dptr->to);
 82 }
 83 
 84 /* hysteresis thresholding for edge strings only */
 85 
 86 static Bool hyster(Tstring * string, double thres)
 87 {
 88     List *dptr;
 89     List *start;
 90     List *end;
 91 
 92     if (string == NULL)
 93         return (false);
 94 
 95     start = string->start;
 96     end = string->end;
 97 
 98     for (dptr = start; dptr != NULL; dptr = dptr->next)
 99     {
100         if (((Edgel *) (dptr->to))->contrast > thres)
101             return (true);
102         if (dptr == end)
103             break;
104     }
105     return (false);
106 }
107 
108 List   *es_list_thres(List * strings, int length_thres, double contrast_thres)
109 {
110     List   *lptr;
111     void    edge_set_type_remove_me();
112 
113     while (strings != NULL)
114     {
115         Tstring *sptr = (Tstring *) strings->to;
116 
117         if (sptr->count >= length_thres && hyster(sptr, contrast_thres) == true)
118             break;
119         str_apply_func((Tstring *) strings->to, edge_set_type_remove_me,
120                        NULL);
121         strings = link_rm(strings, str_rm_links);
122     }
123 
124     if (strings == NULL)
125         return (NULL);
126 
127     lptr = strings;
128     while (lptr->next != NULL)
129     {
130         Tstring *sptr = (Tstring *) lptr->next->to;
131 
132         if (sptr->count < length_thres || hyster(sptr, contrast_thres) == false)
133         {
134             str_apply_func(sptr, edge_set_type_remove_me, NULL);
135             link_rm_next(lptr, str_rm_links);
136         } else
137             lptr = lptr->next;
138     }
139 
140     return (strings);
141 }
142 
143 void    er_edge_strings_thres(Imrect * er, int length_thres, double contrast_thres)
144 {
145     List   *strings;
146     void    edge_rm_on_remove_me();
147 
148     if (er == NULL)
149         return;
150 
151     strings = (List *) prop_get(er->props, STRING);
152     strings = es_list_thres(strings, length_thres, contrast_thres);
153     (void) prop_set(er->props, (void *) strings, STRING, false);
154     er_apply_to_all_edges(er, edge_rm_on_remove_me, (void *) er);
155 }
156 
157 Bool    es_closest_ends(Tstring * str1, Tstring * str2, List ** dptr1, List ** dptr2)
158 {
159     Vec2    s1 = {Vec2_id};
160     Vec2    s2 = {Vec2_id};
161     Vec2    e1 = {Vec2_id};
162     Vec2    e2 = {Vec2_id};
163     float   s1s2, s1e2, e1s2, e1e2;
164 
165     if (str1 == NULL || str2 == NULL)
166         return (false);
167 
168     DD_GET_POS2(str1->start, s1);
169     DD_GET_POS2(str1->end, e1);
170     DD_GET_POS2(str2->start, s2);
171     DD_GET_POS2(str2->end, e2);
172 
173     s1s2 = (float)vec2_mod(vec2_diff(s1, s2));
174     s1e2 = (float)vec2_mod(vec2_diff(s1, e2));
175     e1s2 = (float)vec2_mod(vec2_diff(e1, s2));
176     e1e2 = (float)vec2_mod(vec2_diff(e1, e2));
177 
178     if (MIN(s1s2, s1e2) < MIN(e1s2, e1e2))      /* closest to start s1 */
179     {
180         *dptr1 = str1->start;
181         if (s1s2 < s1e2)        /* starts closest */
182             *dptr2 = str2->start;
183         else
184             *dptr2 = str2->end;
185     } else
186     {
187         *dptr1 = str1->end;
188         if (e1e2 < e1s2)        /* ends are closest */
189             *dptr2 = str2->end;
190         else
191             *dptr2 = str2->start;
192     }
193     return (true);
194 }
195 
196 /* combine pair of strings to produce new string first it finds the
197  * closest ends one or other sub-string may be reversed in the new
198  * sting the original strings are not affected */
199 Tstring *es_combine(Tstring * str1, Tstring * str2)
200 {
201     Tstring *str;
202     Vec2    s1 = {Vec2_id};
203     Vec2    s2 = {Vec2_id};
204     Vec2    e1 = {Vec2_id};
205     Vec2    e2 = {Vec2_id};
206     float   s1s2, s1e2, e1s2, e1e2;
207 
208     str1 = str_clone(str1);     /* first copy string structure */
209     str2 = str_clone(str2);
210 
211     if (str1 == NULL)
212         return (str2);
213     if (str2 == NULL)
214         return (str1);
215 
216     DD_GET_POS2(str1->start, s1);
217     DD_GET_POS2(str1->end, e1);
218     DD_GET_POS2(str2->start, s2);
219     DD_GET_POS2(str2->end, e2);
220 
221     s1s2 = (float)vec2_mod(vec2_diff(s1, s2));
222     s1e2 = (float)vec2_mod(vec2_diff(s1, e2));
223     e1s2 = (float)vec2_mod(vec2_diff(e1, s2));
224     e1e2 = (float)vec2_mod(vec2_diff(e1, e2));
225 
226     if (MIN(s1s2, s1e2) < MIN(e1s2, e1e2))      /* closest to start s1 */
227     {
228         if (s1s2 < s1e2)        /* starts closest */
229             str_reverse(str2);
230         str = str_combine(str2, str1);
231     } else
232     {
233         if (e1e2 < e1s2)        /* ends are closest */
234             str_reverse(str2);
235         str = str_combine(str1, str2);
236     }
237     str_rm_only_str(str1);
238     str_rm_only_str(str2);
239     return (str);
240 }
241 
242 /* concatenate list of stings into new string */
243 Tstring *es_list_cat(List * strings)
244 {
245     Tstring *str = NULL;
246     List   *ptr;
247 
248     for (ptr = strings; ptr != NULL; ptr = ptr->next)
249         str = es_combine((Tstring *) str, (Tstring *) ptr->to);
250     return (str);
251 }
252 
253 /* order the list of strings along a virtual meta string only well
254  * defined if strings are not very overlapped */
255 List   *es_list_order(List * strings)
256 {
257     Tstring *str;
258     List   *new_start;
259     List   *new_end;
260     Vec2    s1 = {Vec2_id};
261     Vec2    s2 = {Vec2_id};
262     Vec2    e1 = {Vec2_id};
263     Vec2    e2 = {Vec2_id};
264     List   *ptr;
265 
266     new_start = new_end = strings;
267     strings = strings->next;
268     new_start->next = NULL;
269     str = (Tstring *) new_start->to;
270     DD_GET_POS2(str->start, s1);
271     DD_GET_POS2(str->end, e1);
272 
273     while (strings != NULL)
274     {
275         int     start = 0;
276         double  mind = 0.0;
277         double  d1, d2, d;
278         Vec2    minv = {Vec2_id};
279         List   *minp = NULL;
280 
281         for (ptr = strings; ptr != NULL; ptr = ptr->next)
282         {
283             str = (Tstring *) ptr->to;
284             DD_GET_POS2(str->start, s2);
285             DD_GET_POS2(str->end, e2);
286 
287             d1 = vec2_sqrmod(vec2_diff(s2, s1));
288             d2 = vec2_sqrmod(vec2_diff(e2, s1));
289             d = MIN(d1, d2);
290             if (minp == NULL || d < mind)
291             {
292                 mind = d;
293                 start = 1;
294                 minp = ptr;
295                 minv = (d == d1) ? s2 : e2;
296             }
297             d1 = vec2_sqrmod(vec2_diff(s2, e1));
298             d2 = vec2_sqrmod(vec2_diff(e2, e1));
299             d = MIN(d1, d2);
300             if (d < mind)
301             {
302                 mind = d;
303                 start = 0;
304                 minp = ptr;
305                 minv = (d == d1) ? s2 : e2;
306             }
307         }
308         if (start)
309         {
310             new_start = link_addtostart(new_start, link_copy(minp,
311                                           (void *(*) ()) NULL, NULL));
312             s1 = minv;
313         } else
314         {
315             new_end = link_addtoend(new_end, link_copy(minp,
316                                           (void *(*) ()) NULL, NULL));
317             new_end->next = NULL;
318             e1 = minv;
319         }
320         strings = list_rm_el(strings, minp, (void (*) ()) NULL);
321     }
322     return (new_start);
323 }
324 
325 static void es_add_string_to_edge_prop(Tstring * s)
326 {
327     es_add_to_prop_list(s, (void *) s, STRING, (void (*) ()) NULL, false);
328 }
329 
330 void    er_reference_strings(Imrect * er)
331 {
332     List   *strings;
333 
334     if (er == NULL)
335         return;
336 
337     strings = (List *) prop_get(er->props, STRING);
338     list_apply_func(strings, (void (*) ()) es_add_string_to_edge_prop, NULL);
339 }
340 
341 Windex *es_list_build_wx(List * es)
342 {
343     Windex *index;
344     Imregion *region;
345 
346     region = strings_bounding_region(es);
347     if (region == NULL)
348         return (NULL);
349 
350     index = wx_alloc(region, 16, 16, STRING);
351     list_apply_func(es, wx_add_str2, (void *) index);
352     return (index);
353 }
354 
355 void    es_format(Tstring * es) /* HP warns Inconsistent type
356                                  * declaration: "es_format". */
357 /* BUT its ok */
358 
359 {
360     List *start;
361     List *end;
362     List *dptr;
363 
364     if (es == NULL)
365         return;
366 
367     start = es->start;
368     end = es->end;
369 
370     edge_format((Edgel *) start->to);
371     for (dptr = start; dptr != end;)
372     {
373         dptr = dptr->next;
374         edge_format((Edgel *) dptr->to);
375     }
376 }
377 

~ [ 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.