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

Linux Cross Reference
Tina5/tina-libs/tina/geometry/geomEdge_strings.c

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

  1 /**********
  2  * 
  3  * This file is part of the TINA Open Source Image Analysis Environment
  4  * henceforth known as TINA
  5  *
  6  * TINA is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU Lesser General Public License as 
  8  * published by the Free Software Foundation.
  9  *
 10  * TINA is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public License
 16  * along with TINA; if not, write to the Free Software Foundation, Inc., 
 17  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  *
 19  **********
 20  * 
 21  * Program :    TINA
 22  * File    :  $Source: /home/tina/cvs/tina-libs/tina/geometry/geomEdge_strings.c,v $
 23  * Date    :  $Date: 2002/12/09 11:51:23 $
 24  * Version :  $Revision: 1.1.1.1 $
 25  * CVS Id  :  $Id: geomEdge_strings.c,v 1.1.1.1 2002/12/09 11:51:23 cvstina Exp $
 26  *
 27  * Author  : Legacy TINA
 28  *
 29  * Notes : 
 30  *
 31  *********
 32 */
 33 
 34 #include "geomEdge_strings.h"
 35 
 36 #if HAVE_CONFIG_H
 37   #include <config.h>
 38 #endif
 39 
 40 #include <math.h>
 41 #include <tina/sys/sysDef.h>
 42 #include <tina/sys/sysPro.h>
 43 #include <tina/math/mathDef.h>
 44 #include <tina/math/mathPro.h>
 45 #include <tina/geometry/geomDef.h>
 46 #include <tina/geometry/geom_IndxDef.h>
 47 #include <tina/geometry/geom_IndxPro.h>
 48 #include <tina/geometry/geom_EdgeDef.h>
 49 #include <tina/geometry/geom_EdgePro.h>
 50 
 51 
 52 
 53 /* ARGSUSED quieten lint */
 54 static void edge_add_prop_def(Edgel * e, int type, Prop_def * pdef)
 55 {
 56     if (pdef == NULL)
 57         return;
 58     e->props = proplist_addifnp(e->props, (void *) pdef->prop, pdef->type, pdef->free_func, pdef->dofree);
 59 }
 60 
 61 void    edge_add_prop(Edgel * e, void *ptr, int type, void (*free_func) ( /* ??? */ ), Bool dofree)
 62 {
 63     if (e == NULL)
 64         return;
 65     e->props = proplist_addifnp(e->props, (void *) ptr, type, free_func, dofree);
 66 }
 67 
 68 void    es_add_to_prop_list(Tstring * s, void *ptr, int type, void (*free_func) ( /* ??? */ ), Bool dofree)
 69 {
 70     Prop_def pdef;
 71 
 72     if (s == NULL)
 73         return;
 74 
 75     pdef.prop = ptr;
 76     pdef.type = type;
 77     pdef.free_func = free_func;
 78     pdef.dofree = dofree;
 79 
 80     str_apply_func(s, edge_add_prop_def, (void *) &pdef);
 81 }
 82 
 83 /* code to pick general pos2 strings */
 84 
 85 Bool    dist_to_pos2(void *ptr, int type, Vec2 * pp, double *dist)
 86 {
 87     if (ptr == NULL)
 88         return (false);
 89 
 90     switch (type)
 91     {
 92     case VEC2:
 93         *dist = vec2_mod(vec2_diff(*pp, *(Vec2 *) ptr));
 94         return (true);
 95     case EDGE:
 96         *dist = vec2_mod(vec2_diff(*pp, ((Edgel *) ptr)->pos));
 97         return (true);
 98     default:
 99         return (false);
100     }
101 }
102 
103 Tstring *es_closest2(List * strings, Vec2 pos)
104 {
105     Tstring *str_list_get_min();
106 
107     return (str_list_get_min(strings, dist_to_pos2, (void *) &pos));
108 }
109 
110 void   *es_closest_pos2(List * strings, Vec2 pos, int *type)
111 {
112     Tstring *str = es_closest2(strings, pos);
113     List *dptr;
114 
115     if (str == NULL)
116         return (NULL);
117 
118     dptr = str_get_min(str, dist_to_pos2, (void *) &pos);
119     if (dptr == NULL)
120         return (NULL);
121 
122     *type = dptr->type;
123     return (dptr->to);
124 }
125 
126 /* hysteresis thresholding for edge strings only */
127 
128 static Bool hyster(Tstring * string, double thres)
129 {
130     List *dptr;
131     List *start;
132     List *end;
133 
134     if (string == NULL)
135         return (false);
136 
137     start = string->start;
138     end = string->end;
139 
140     for (dptr = start; dptr != NULL; dptr = dptr->next)
141     {
142         if (((Edgel *) (dptr->to))->contrast > thres)
143             return (true);
144         if (dptr == end)
145             break;
146     }
147     return (false);
148 }
149 
150 List   *es_list_thres(List * strings, int length_thres, double contrast_thres)
151 {
152     List   *lptr;
153     void    edge_set_type_remove_me();
154 
155     while (strings != NULL)
156     {
157         Tstring *sptr = (Tstring *) strings->to;
158 
159         if (sptr->count >= length_thres && hyster(sptr, contrast_thres) == true)
160             break;
161         str_apply_func((Tstring *) strings->to, edge_set_type_remove_me,
162                        NULL);
163         strings = link_rm(strings, str_rm_links);
164     }
165 
166     if (strings == NULL)
167         return (NULL);
168 
169     lptr = strings;
170     while (lptr->next != NULL)
171     {
172         Tstring *sptr = (Tstring *) lptr->next->to;
173 
174         if (sptr->count < length_thres || hyster(sptr, contrast_thres) == false)
175         {
176             str_apply_func(sptr, edge_set_type_remove_me, NULL);
177             link_rm_next(lptr, str_rm_links);
178         } else
179             lptr = lptr->next;
180     }
181 
182     return (strings);
183 }
184 
185 void    er_edge_strings_thres(Imrect * er, int length_thres, double contrast_thres)
186 {
187     List   *strings;
188     void    edge_rm_on_remove_me();
189 
190     if (er == NULL)
191         return;
192 
193     strings = (List *) prop_get(er->props, STRING);
194     strings = es_list_thres(strings, length_thres, contrast_thres);
195     (void) prop_set(er->props, (void *) strings, STRING, false);
196     er_apply_to_all_edges(er, edge_rm_on_remove_me, (void *) er);
197 }
198 
199 Bool    es_closest_ends(Tstring * str1, Tstring * str2, List ** dptr1, List ** dptr2)
200 {
201     Vec2    s1 = {Vec2_id};
202     Vec2    s2 = {Vec2_id};
203     Vec2    e1 = {Vec2_id};
204     Vec2    e2 = {Vec2_id};
205     float   s1s2, s1e2, e1s2, e1e2;
206 
207     if (str1 == NULL || str2 == NULL)
208         return (false);
209 
210     DD_GET_POS2(str1->start, s1);
211     DD_GET_POS2(str1->end, e1);
212     DD_GET_POS2(str2->start, s2);
213     DD_GET_POS2(str2->end, e2);
214 
215     s1s2 = (float)vec2_mod(vec2_diff(s1, s2));
216     s1e2 = (float)vec2_mod(vec2_diff(s1, e2));
217     e1s2 = (float)vec2_mod(vec2_diff(e1, s2));
218     e1e2 = (float)vec2_mod(vec2_diff(e1, e2));
219 
220     if (MIN(s1s2, s1e2) < MIN(e1s2, e1e2))      /* closest to start s1 */
221     {
222         *dptr1 = str1->start;
223         if (s1s2 < s1e2)        /* starts closest */
224             *dptr2 = str2->start;
225         else
226             *dptr2 = str2->end;
227     } else
228     {
229         *dptr1 = str1->end;
230         if (e1e2 < e1s2)        /* ends are closest */
231             *dptr2 = str2->end;
232         else
233             *dptr2 = str2->start;
234     }
235     return (true);
236 }
237 
238 /* combine pair of strings to produce new string first it finds the
239  * closest ends one or other sub-string may be reversed in the new
240  * sting the original strings are not affected */
241 Tstring *es_combine(Tstring * str1, Tstring * str2)
242 {
243     Tstring *str;
244     Vec2    s1 = {Vec2_id};
245     Vec2    s2 = {Vec2_id};
246     Vec2    e1 = {Vec2_id};
247     Vec2    e2 = {Vec2_id};
248     float   s1s2, s1e2, e1s2, e1e2;
249 
250     str1 = str_clone(str1);     /* first copy string structure */
251     str2 = str_clone(str2);
252 
253     if (str1 == NULL)
254         return (str2);
255     if (str2 == NULL)
256         return (str1);
257 
258     DD_GET_POS2(str1->start, s1);
259     DD_GET_POS2(str1->end, e1);
260     DD_GET_POS2(str2->start, s2);
261     DD_GET_POS2(str2->end, e2);
262 
263     s1s2 = (float)vec2_mod(vec2_diff(s1, s2));
264     s1e2 = (float)vec2_mod(vec2_diff(s1, e2));
265     e1s2 = (float)vec2_mod(vec2_diff(e1, s2));
266     e1e2 = (float)vec2_mod(vec2_diff(e1, e2));
267 
268     if (MIN(s1s2, s1e2) < MIN(e1s2, e1e2))      /* closest to start s1 */
269     {
270         if (s1s2 < s1e2)        /* starts closest */
271             str_reverse(str2);
272         str = str_combine(str2, str1);
273     } else
274     {
275         if (e1e2 < e1s2)        /* ends are closest */
276             str_reverse(str2);
277         str = str_combine(str1, str2);
278     }
279     str_rm_only_str(str1);
280     str_rm_only_str(str2);
281     return (str);
282 }
283 
284 /* concatenate list of stings into new string */
285 Tstring *es_list_cat(List * strings)
286 {
287     Tstring *str = NULL;
288     List   *ptr;
289 
290     for (ptr = strings; ptr != NULL; ptr = ptr->next)
291         str = es_combine((Tstring *) str, (Tstring *) ptr->to);
292     return (str);
293 }
294 
295 /* order the list of strings along a virtual meta string only well
296  * defined if strings are not very overlapped */
297 List   *es_list_order(List * strings)
298 {
299     Tstring *str;
300     List   *new_start;
301     List   *new_end;
302     Vec2    s1 = {Vec2_id};
303     Vec2    s2 = {Vec2_id};
304     Vec2    e1 = {Vec2_id};
305     Vec2    e2 = {Vec2_id};
306     List   *ptr;
307 
308     new_start = new_end = strings;
309     strings = strings->next;
310     new_start->next = NULL;
311     str = (Tstring *) new_start->to;
312     DD_GET_POS2(str->start, s1);
313     DD_GET_POS2(str->end, e1);
314 
315     while (strings != NULL)
316     {
317         int     start = 0;
318         double  mind = 0.0;
319         double  d1, d2, d;
320         Vec2    minv = {Vec2_id};
321         List   *minp = NULL;
322 
323         for (ptr = strings; ptr != NULL; ptr = ptr->next)
324         {
325             str = (Tstring *) ptr->to;
326             DD_GET_POS2(str->start, s2);
327             DD_GET_POS2(str->end, e2);
328 
329             d1 = vec2_sqrmod(vec2_diff(s2, s1));
330             d2 = vec2_sqrmod(vec2_diff(e2, s1));
331             d = MIN(d1, d2);
332             if (minp == NULL || d < mind)
333             {
334                 mind = d;
335                 start = 1;
336                 minp = ptr;
337                 minv = (d == d1) ? s2 : e2;
338             }
339             d1 = vec2_sqrmod(vec2_diff(s2, e1));
340             d2 = vec2_sqrmod(vec2_diff(e2, e1));
341             d = MIN(d1, d2);
342             if (d < mind)
343             {
344                 mind = d;
345                 start = 0;
346                 minp = ptr;
347                 minv = (d == d1) ? s2 : e2;
348             }
349         }
350         if (start)
351         {
352             new_start = link_addtostart(new_start, link_copy(minp,
353                                           (void *(*) ()) NULL, NULL));
354             s1 = minv;
355         } else
356         {
357             new_end = link_addtoend(new_end, link_copy(minp,
358                                           (void *(*) ()) NULL, NULL));
359             new_end->next = NULL;
360             e1 = minv;
361         }
362         strings = list_rm_el(strings, minp, (void (*) ()) NULL);
363     }
364     return (new_start);
365 }
366 
367 static void es_add_string_to_edge_prop(Tstring * s)
368 {
369     es_add_to_prop_list(s, (void *) s, STRING, (void (*) ()) NULL, false);
370 }
371 
372 void    er_reference_strings(Imrect * er)
373 {
374     List   *strings;
375 
376     if (er == NULL)
377         return;
378 
379     strings = (List *) prop_get(er->props, STRING);
380     list_apply_func(strings, (void (*) ()) es_add_string_to_edge_prop, NULL);
381 }
382 
383 Windex *es_list_build_wx(List * es)
384 {
385     Windex *index;
386     Imregion *region;
387 
388     region = strings_bounding_region(es);
389     if (region == NULL)
390         return (NULL);
391 
392     index = wx_alloc(region, 16, 16, STRING);
393     list_apply_func(es, wx_add_str2, (void *) index);
394     return (index);
395 }
396 
397 void    es_format(Tstring * es) /* HP warns Inconsistent type
398                                  * declaration: "es_format". */
399 /* BUT its ok */
400 
401 {
402     List *start;
403     List *end;
404     List *dptr;
405 
406     if (es == NULL)
407         return;
408 
409     start = es->start;
410     end = es->end;
411 
412     edge_format((Edgel *) start->to);
413     for (dptr = start; dptr != end;)
414     {
415         dptr = dptr->next;
416         edge_format((Edgel *) dptr->to);
417     }
418 }
419 

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