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

Linux Cross Reference
Tina5/tina-libs/tina/geometry/geomTrans_gen.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/geomTrans_gen.c,v $
 23  * Date    :  $Date: 2003/09/02 10:06:55 $
 24  * Version :  $Revision: 1.2 $
 25  * CVS Id  :  $Id: geomTrans_gen.c,v 1.2 2003/09/02 10:06:55 neil Exp $
 26  *
 27  * Notes : Least squares transform functions for matched 3D geometry
 28  *         position (pos) and vector (vec) treated seperately
 29  *
 30  *********
 31 */
 32 
 33 
 34 #include "geomTrans_gen.h"
 35 
 36 #if HAVE_CONFIG_H
 37   #include <config.h>
 38 #endif
 39 
 40 #include <tina/sys/sysDef.h>
 41 #include <tina/sys/sysPro.h>
 42 #include <tina/math/mathDef.h>
 43 #include <tina/math/mathPro.h>
 44 #include <tina/geometry/geomDef.h>
 45 #include <tina/geometry/geom_GenPro.h>
 46 #include <tina/geometry/geom_PointDef.h>
 47 #include <tina/geometry/geom_TransDef.h>
 48 #include <tina/geometry/geomTrans_rot.h>
 49 #include <tina/geometry/geomTrans_trnslation.h>
 50 
 51 /* Compute approx (rot first) least square transformation on the basis
 52  * of vector data obtained from appropriate geometrical primitives
 53  * transform from match->t1 to match->t2 for each member of the list */
 54 Transform3 mlist_comp_transform_vec3(List * match_list, int *terror)
 55 {
 56     Transform3 trans = {Transform3_id};
 57 
 58     trans.type = 0;
 59     trans.R = mlist_comp_rot_all(match_list, terror);   /* uses all */
 60     if (*terror)
 61         trans.t = vec3_zero();
 62     else
 63         trans.t = mlist_comp_translate_all(match_list, trans.R);
 64 
 65     if (*terror)
 66         error("there is a transform error", warning);
 67 
 68     return (trans);
 69 }
 70 
 71 /* Compute approx (rot first) least square transformation on the basis
 72  * of position data obtained from appropriate geometrical primitives
 73  * centroid can be weighted (on basis of match strength) if required
 74  * transform from match->t1 to match->t2 for each member of the list */
 75 Transform3 mlist_comp_transform_pos3(List * match_list, Bool weighted, int *terror)
 76 
 77 /* if true use a weighted centroid */
 78 
 79 {
 80     Transform3 trans = {Transform3_id};
 81     float   tot_weight = (float)0.0;
 82     List   *lptr;
 83     Vec3    c1 = {Vec3_id};
 84     Vec3    c2 = {Vec3_id};
 85 
 86     c1 = c2 = vec3_zero();
 87     trans.type = 0;
 88 
 89     for (lptr = match_list; lptr != NULL; lptr = lptr->next)
 90     {
 91         Match  *mptr = (Match *) lptr->to;
 92         Point3 *p1;
 93         Point3 *p2;
 94         float   weight;
 95 
 96         if (mptr->type != POINT3)
 97             continue;
 98 
 99         p1 = (Point3 *) mptr->to1;
100         p2 = (Point3 *) mptr->to2;
101         weight = (float)((weighted == true) ? mptr->weight : 1.0);
102 
103         c1 = vec3_times(weight, vec3_sum(c1, p1->p));
104         c2 = vec3_sum(c2, p2->p);
105         tot_weight += weight;
106     }
107 
108     c1 = vec3_times(1 / tot_weight, c1);
109     c2 = vec3_times(1 / tot_weight, c2);
110 
111     trans.R = mlist_comp_rot_pos3(match_list, c1, c2, terror);
112     trans.t = (terror) ? vec3_zero() : vec3_diff(c2, mat3_vprod(trans.R, c1));
113 
114     if (*terror)
115         error("there is a transform error", warning);
116 
117     return (trans);
118 }
119 
120 /* Test if particular match is consitent with transformation trans
121  * should take geometry in match->t1 to match->t2 */
122 Bool    transform_match_ok(Match * match, Transform3 trans)
123 {
124     Bool    within_error;
125     void   *geom;
126 
127     if (match == NULL)
128         return (false);
129 
130     geom = geom_copy(match->to1, match->type);
131     geom_transform(geom, match->type, &trans);
132     within_error = geom_within_error(geom, match->to2, match->type);
133     geom_free(geom, match->type);
134     return (within_error);
135 }
136 
137 /* Remove elements of match list (list) that are not consistent with
138  * transformation (trans) use freematch to determine whether to free up
139  * Match structure or only the List element */
140 List   *transform_prune_mlist(List * list, Transform3 trans, Bool freematch)
141 {
142     List   *pruned = NULL;
143     List   *lptr;
144     List   *next;
145 
146     for (lptr = list; lptr != NULL; lptr = next)
147     {
148         next = lptr->next;
149         if (transform_match_ok((Match *) lptr->to, trans) == false)
150         {
151             if (freematch == true)
152                 (void) link_rm(lptr, rfree);    /* delete this match */
153             else
154                 (void) link_rm_el(lptr);
155             continue;
156         }
157         pruned = link_addtostart((List *) pruned, link_copy(lptr, NULL, NULL));
158         link_rm_el(lptr);
159     }
160     return (list_reverse(pruned));
161 }
162 
163 /* Starting from the pair of matches {m1, m2} compute transformation
164  * recruit additional matches from match list (list) if possible */
165 Transform3 match_pair_transform_vec3(Match * m1, Match * m2, List * list, int *match_count)
166 
167 /* full list of matches */
168 
169 {
170     List   *tlist = NULL;
171     Transform3 trans = {Transform3_id};
172     Transform3 oldtrans = {Transform3_id};
173     int     old_count, count = 0;
174     int     terror;
175 
176     *match_count = 0;
177 
178     trans.R = mat3_unit();
179     trans.t = vec3_zero();
180 
181     if (m1 == NULL || m2 == NULL)
182         return (trans);
183     tlist = ref_addtostart(tlist, (void *) m1, MATCH);
184     tlist = ref_addtostart(tlist, (void *) m2, MATCH);
185 
186     do
187     {
188         old_count = count;
189         oldtrans = trans;
190         trans = mlist_comp_transform_vec3(tlist, &terror);
191         list_rm(tlist, (void (*) ()) NULL);
192         if (!terror)
193         {
194             tlist = transform_prune_mlist(
195             list_copy(list, (void *(*) ()) NULL, NULL), trans, false);
196             count = list_length(tlist);
197         }
198     }
199     while (count >= 2 && count > old_count);
200 
201     list_rm(tlist, (void (*) ()) NULL);
202     *match_count = old_count;
203 
204     return (oldtrans);
205 }
206 
207 /* Find the best (highest cardinality) transformation from the match
208  * list try each pair of matches in turn as the basis of the
209  * transformation */
210 Transform3 mlist_best_transform_vec3(List * list, int *match_count)
211 {
212     Transform3 trans = {Transform3_id};
213     Transform3 best_trans = {Transform3_id};
214     int     count, maxcount = -1;
215     List   *l1;
216     List   *l2;
217 
218     best_trans.R = mat3_unit();
219     best_trans.t = vec3_zero();
220 
221     for (l1 = list; l1 != NULL; l1 = l1->next)
222         for (l2 = l1->next; l2 != NULL; l2 = l2->next)
223         {
224             Match  *m1 = (Match *) l1->to;
225             Match  *m2 = (Match *) l2->to;
226 
227             trans = match_pair_transform_vec3(m1, m2, list, &count);
228             if (count > maxcount)
229             {
230                 maxcount = count;
231                 best_trans = trans;
232             }
233         }
234 
235     *match_count = maxcount;
236     return (best_trans);
237 }
238 
239 /* Compute transromation from match list (list) iteratively prune and
240  * grow transformation until stable */
241 Transform3 mlist_transform_vec3(List * list, int *match_count)
242 {
243     List   *tlist;
244     Transform3 trans = {Transform3_id};
245     Transform3 oldtrans = {Transform3_id};
246     int     old_count, count = 0;
247     int     terror;
248 
249     trans.R = mat3_unit();
250     trans.t = vec3_zero();
251     tlist = list_copy(list, (void *(*) ()) NULL, NULL);
252 
253     do
254     {
255         old_count = count;
256         oldtrans = trans;
257         trans = mlist_comp_transform_vec3(tlist, &terror);
258         list_rm(tlist, (void (*) ()) NULL);
259         if (!terror)
260         {
261             tlist = transform_prune_mlist(list_copy(list,
262                             (void *(*) ()) NULL, NULL), trans, false);
263             count = list_length(tlist);
264         }
265     }
266     while (count >= 2 && count > old_count);
267 
268     list_rm(tlist, (void (*) ()) NULL);
269     *match_count = old_count;
270 
271     return (oldtrans);
272 }
273 

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