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

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

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