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

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

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