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

Linux Cross Reference
Tina4/src/vision/corner/match_cnr.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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