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

Linux Cross Reference
Tina6/tina-libs/tina/vision/visMatch_corner.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/vision/visMatch_corner.c,v $
 27  * Date    :  $Date: 2004/08/04 15:07:47 $
 28  * Version :  $Revision: 1.4 $
 29  * CVS Id  :  $Id: visMatch_corner.c,v 1.4 2004/08/04 15:07:47 paul Exp $
 30  *
 31  * Author  : Legacy TINA
 32  *
 33  * Notes :
 34  *
 35  *********
 36 */
 37 
 38 #include "visMatch_corner.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/image/img_GenDef.h>
 50 #include <tina/image/img_GenPro.h>
 51 #include <tina/geometry/geomDef.h>
 52 #include <tina/geometry/geomPro.h>
 53 
 54 void    get_corner_matches(Rindex * fx1, Rindex * fx2, int pos_type, Imregion(*search_func) ( /* ??? */ ), void* (*make_match) ( /* ??? */ ))
 55 /* given the corners detercted in two specified regions and indexed by
 56    the Rindex fast access structure, generate a list of candidate matches
 57    for each corner from those available within the specified search region */
 58 {
 59     int     ly, uy;
 60     int     i;
 61     Imregion *index_region;
 62 
 63     if (fx1 == NULL || fx2 == NULL)
 64         return;
 65 
 66     if ((index_region = fx1->region) == NULL)
 67         return;
 68 
 69     ly = index_region->ly;
 70     uy = index_region->uy;
 71 
 72     for (i = ly; i < uy; ++i)
 73     {
 74         List   *ledge = fx1->index[i];
 75 
 76         while (ledge != NULL)
 77         {
 78             Edgel  *edge = (Edgel *) ledge->to;
 79 
 80             if (edge != NULL)
 81                 get_corner_match(edge, fx2, pos_type, search_func(edge), make_match);
 82             ledge = ledge->next;
 83         }
 84     }
 85 }
 86 
 87 void    apply_func_to_windex(Rindex * fx, void *(*func) ( /* ??? */ ), void *data)
 88 /* generic function to apply ana arbitrary function (func) to every Edgel
 89    data structure indexed by the Rindex fast access structure, the generic
 90    extra data field is user specifiable */ 
 91 {
 92     int     ly, uy;
 93     int     i;
 94     Imregion *index_region;
 95 
 96     if (fx == NULL)
 97         return;
 98 
 99     if ((index_region = fx->region) == NULL)
100         return;
101 
102     ly = index_region->ly;
103     uy = index_region->uy;
104 
105     for (i = ly; i < uy; ++i)
106     {
107         List   *ledge = fx->index[i];
108 
109         while (ledge != NULL)
110         {
111             Edgel  *edge = (Edgel *) ledge->to;
112 
113             if (edge != NULL)
114                 func(edge, data);
115             ledge = ledge->next;
116         }
117     }
118 }
119 
120 void    get_corner_match(Edgel * edge1, Rindex * fx2, int pos_type,
121                          Imregion search_region, void *(*make_match) ( /* ??? */ ))
122 /*  matches a single corner specified by edge1 to all possible matches
123     specified by the Rindex fast access structure */
124 {
125     int     lx, ly, ux, uy;
126     int     i;
127     Imregion *index_region;
128 
129     if (edge1 == NULL || fx2 == NULL)
130         return;
131 
132     if ((index_region = fx2->region) == NULL)
133         return;
134 
135     lx = search_region.lx;
136     ly = search_region.ly;
137     ux = search_region.ux;
138     uy = search_region.uy;
139 
140     if (lx < index_region->lx)
141         lx = index_region->lx;
142     if (ux > index_region->ux)
143         ux = index_region->ux;
144     if (lx > ux)
145         return;
146     if (ly < index_region->ly)
147         ly = index_region->ly;
148     if (uy > index_region->uy)
149         uy = index_region->uy;
150     if (ly > uy)
151         return;
152 
153     for (i = ly; i < uy; ++i)
154     {
155         List   *ledge = fx2->index[i];
156 
157         while (ledge != NULL)
158         {
159             Edgel  *edge2 = (Edgel *) ledge->to;
160             Vec2   *rect;
161 
162             if (edge2 != NULL)
163             {
164                 rect = (Vec2 *) prop_get(edge2->props, pos_type);
165                 if (rect == NULL)
166                     rect = &edge2->pos;
167                 if ((int) rect->el[0] >= lx && (int) rect->el[0] <= ux)
168                     make_match(edge1, edge2);
169             }
170             ledge = ledge->next;
171         }
172     }
173 }
174 
175 static double match_weight(Match * match)
176 {
177     return (-match->weight); /*BUG fix lack of negative sign resulted in
178                                wrongly ordered match list NAT/SAM 23/11/95 */
179 }
180 
181 static void rm_match_list(List * list)
182 {
183     list_rm(list, match_free);
184 }
185 
186 void    add_match_to_props(Edgel * edge, void *match, int type)
187 {
188     List   *list;
189 
190     if (edge == NULL || match == NULL)
191         return;
192 
193     list = prop_get(edge->props, type);
194     list = list_add_sorted(list, link_alloc((void *) match, POT_MATCH), match_weight);
195     edge->props = proplist_addifnp(edge->props, (void *) list, type, rm_match_list, false);
196 }
197 
198 void    rm_match_from_props(Edgel * edge, int *type)
199 {
200     edge->props = proplist_free(edge->props, *type);
201 }
202 
203 void    rm_corner_matches(Rindex * fx, int *type)
204 /* free up all corner matches curent stored in the edge data structures indexed
205    by the Rindex fast access data structure */
206 {
207     apply_func_to_windex(fx, (void *(*) ()) rm_match_from_props, (void *) type);
208 }
209 
210 void   *get_matches_list(Edgel * edgel, int *type)
211 {
212     List   *matches;
213 
214     matches = prop_get(edgel->props, *type);
215     return ((void *) matches);
216 }
217 
218 Matrix *add_patch_to_props(Edgel * edge, Imrect * image, float sigma)
219 /* store a small piece of the image on the specified edge data structure
220    for use later during correlation based feature matching */
221 {
222     static Matrix *weight = NULL;
223     Matrix *patch;
224     float   x0, y0;
225     float   x, y, x1, y1;
226     float   dx, dy;
227     float   orient;
228     float   norm = (float)0.0;
229     int     i, j;
230 
231     if (edge == NULL || image == NULL)
232         return (NULL);
233     if (weight == NULL)
234     {
235         weight = matrix_alloc(5, 5, matrix_full, float_v);
236         for (x = (float)-2.0 * sigma, i = 0; x <= 2.0 * sigma; x += sigma, i++)
237             for (y = (float)-2.0 * sigma, j = 0; y <= 2.0 * sigma; y += sigma, j++)
238                 weight->el.float_v[i][j] = (float)(exp(-(x * x + y * y) / (4.0 * sigma * sigma)));
239     }
240 /*
241     orient = edge->orient; 
242 */
243     orient = 0.0;
244     if ((patch = matrix_alloc(5, 5, matrix_full, float_v)) == NULL)
245         return (NULL);
246     x0 = edge->pos.el[0];
247     y0 = edge->pos.el[1];
248     for (x = (float)-2.0 * sigma, i = 0; x <= 2.0 * sigma; x += sigma, i++)
249         for (y = (float)-2.0 * sigma, j = 0; y <= 2.0 * sigma; y += sigma, j++)
250         {
251             x1 = -x*sin(orient) + y*cos(orient);
252             y1 = x*cos(orient) + y*sin(orient);
253             patch->el.float_v[i][j] = (float)(weight->el.float_v[i][j] *
254                 im_get_quadinterpf(image, x0 + x1, y0 + y1, &dx, &dy));
255             norm += patch->el.float_v[i][j] * patch->el.float_v[i][j];
256         }
257 /*  feature normalisation found to be unnecessary (ie: worse)
258 */
259     if (norm != 0.0)
260         norm = (float)(1.0 / sqrt(norm));
261     else
262         norm = (float)0.0;
263     for (i = 0; i < 5; i++)
264         for (j = 0; j < 5; j++)
265             patch->el.float_v[i][j] *= norm;
266 
267     edge->props = proplist_add(edge->props, (void *) patch, PATCH, matrix_free);
268     return (patch);
269 }
270 
271 float   corner_correlation(Imrect * image1, Imrect * image2, Edgel * edge1, Edgel * edge2, float sigma)
272 {
273     float   total = (float)0.0;
274     int     i, j;
275     float   norm1 = 0.0, norm2 = 0.0;
276     Matrix *patch1;
277     Matrix *patch2;
278 
279     if (edge1 == NULL || edge2 == NULL)
280         return ((float)0.0);
281 
282     if ((patch1 = prop_get(edge1->props, PATCH)) == NULL)
283         if ((patch1 = add_patch_to_props(edge1, image1, sigma)) == NULL)
284             return ((float)0.0);
285 
286     if ((patch2 = prop_get(edge2->props, PATCH)) == NULL)
287         if ((patch2 = add_patch_to_props(edge2, image2, sigma)) == NULL)
288             return ((float)0.0);
289 
290     for (i = 0; i < 5; i++)
291         for (j = 0; j < 5; j++)
292         {
293             total += patch1->el.float_v[i][j]*patch2->el.float_v[i][j];
294             norm1 += patch1->el.float_v[i][j]*patch1->el.float_v[i][j];
295             norm2 += patch2->el.float_v[i][j]*patch2->el.float_v[i][j];
296         }
297 
298     return (total/sqrt(norm1*norm2));
299 }
300 
301 float   good_corner(Edgel * edge1, Edgel * edge2, float region, float asymetry, Imrect * image1, Imrect * image2)
302 {
303     float   corr, asym;
304 
305     if (edge1 == NULL || edge2 == NULL)
306         return ((float)0.0);
307 
308     /* weak constraint on relative value of corner strength */
309     asym = (edge1->contrast - edge2->contrast)
310         / (edge1->contrast + edge2->contrast);
311     if (fabs(asym) > asymetry)
312         return ((float)0.0);
313     corr = corner_correlation(image1, image2, edge1, edge2, region);
314 
315     return (corr);
316 }
317 
318 float   correlation(Imrect * image1, Imrect * image2, float x1, float y1, float x2, float y2, float sigma)
319 {
320     float   total = (float)0.0;
321     float   norm1 = (float)0.0;
322     float   norm2 = (float)0.0;
323     float   grey1, grey2, dx, dy;
324     float   x, y;
325     static Matrix *weight = NULL;
326     int     i, j;
327 
328     if (weight == NULL)
329     {
330         weight = matrix_alloc(5, 5, matrix_full, float_v);
331         for (x = (float)-2.0 * sigma, i = 0; x <= 2.0 * sigma; x += sigma, i++)
332             for (y = (float)-2.0 * sigma, j = 0; y <= 2.0 * sigma; y += sigma, j++)
333                 weight->el.float_v[i][j] = (float)(exp(-(x * x + y * y) / (2.0 * sigma * sigma)));
334     }
335     for (x = (float)-2.0 * sigma, i = 0; x <= 2.0 * sigma; x += sigma, i++)
336     {
337         for (y = (float)-2.0 * sigma, j = 0; y <= 2.0 * sigma; y += sigma, j++)
338         {
339             grey1 = (float)im_get_quadinterpf(image1, x1 + x, y1 + y, &dx, &dy);
340             grey2 = (float)im_get_quadinterpf(image2, x2 + x, y2 + y, &dx, &dy);
341             total += weight->el.float_v[i][j] * grey1 * grey2;
342             norm1 += weight->el.float_v[i][j] * grey1 * grey1;
343             norm2 += weight->el.float_v[i][j] * grey2 * grey2;
344         }
345     }
346     total /= (float)sqrt(norm1 * norm2);
347     return (total);
348 }
349 
350 void   *get_fixed_match(Edgel * edgel, int *type)
351 /* simple function to return the fixed matches for the specified corner
352    intended for use with apply_func_to_windex() */
353 {
354     List   *matches;
355 
356     matches = prop_get(edgel->props, *type);
357     if (matches != NULL && matches->type == FIXED_MATCH)
358         return (matches->to);
359     else
360         return (NULL);
361 }
362 
363 void   *get_good_match(Edgel * edgel, int *type)
364 /* simple function to return the good matches for the specified corner
365    intended for use with apply_func_to_windex() */
366 {
367     List   *matches;
368 
369     matches = prop_get(edgel->props, *type);
370     if (matches != NULL && matches->type == GOOD_MATCH)
371         return (matches->to);
372     else
373         return (NULL);
374 }
375 

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