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

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

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