hsm.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <math.h>
3 #include <time.h>
4 #include <assert.h>
5 #include <time.h>
6 #include "../csm_all.h"
7 
8 #include "hsm.h"
9 
11  assert(p->max_norm>0);
12  assert(p->linear_cell_size>0);
13  assert(p->angular_cell_size_deg>0);
14  assert(p->num_angular_hypotheses >0);
15  assert(p->linear_xc_max_npeaks>0);
16  assert(p->xc_ndirections>0);
17 
18  hsm_buffer b = (hsm_buffer) malloc(sizeof(struct hsm_buffer_struct));
19 
20  b->num_angular_cells = (int) ceil(360.0 / p->angular_cell_size_deg);
21  b->num_linear_cells = 1 + 2 * (int) ceil(p->max_norm / p->linear_cell_size);
23  b->rho_min = - p->max_norm;
24  b->rho_max = + p->max_norm;
25 
26  b->hs = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
27  b->hs_cross_corr = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
28  b->ht = (double**) calloc((size_t)b->num_angular_cells, sizeof(double*));
29 
30  for(int i=0; i<b->num_angular_cells; i++) {
31  b->ht[i] = (double*) calloc((size_t)b->num_linear_cells, sizeof(double));
32  for(int r=0;r<b->num_linear_cells;r++)
33  b->ht[i][r] = 0;
34  }
35 
36  b->theta = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
37  b->sint = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
38  b->cost = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
39  for(int i=0; i<b->num_angular_cells; i++) {
40  b->theta[i] = (2 * M_PI * i) / b->num_angular_cells;
41  b->sint[i] = sin(b->theta[i]);
42  b->cost[i] = cos(b->theta[i]);
43  }
44 
45  b->hs_cross_corr = (double*) calloc((size_t)b->num_angular_cells, sizeof(double));
46 
47  b->max_num_results = (int) p->num_angular_hypotheses * pow( (float) p->linear_xc_max_npeaks, (float) p->xc_ndirections);
48 
49  b->num_valid_results = 0;
50  b->results = (double**) calloc((size_t)b->max_num_results, sizeof(double*));
51  for(int i=0;i<b->max_num_results; i++)
52  b->results[i] = (double*) calloc(3, sizeof(double));
53 
54  b->results_quality = (double*) calloc((size_t)b->max_num_results, sizeof(double));
55 
56  double zero[3] = {0,0,0};
57  hsm_compute_ht_base(b, zero);
58 
59  return b;
60 }
61 
63 
64  free(b->hs);
65  for(int i=0; i<b->num_angular_cells; i++)
66  free(b->ht[i]);
67  free(b->ht);
68 
69  free(b->theta);
70  free(b->sint);
71  free(b->cost);
72 
73  free(b->hs_cross_corr);
74  for(int i=0;i<b->max_num_results; i++)
75  free(b->results[i]);
76  free(b->results);
77 
78  free(b->results_quality);
79  free(b);
80 }
81 
82 void hsm_compute_ht_base(hsm_buffer b, const double base_pose[3]) {
83  b->disp[0] = base_pose[0];
84  b->disp[1] = base_pose[1];
85  b->disp[2] = base_pose[2];
86  b->disp_th_cos = cos(base_pose[2]);
87  b->disp_th_sin = sin(base_pose[2]);
88 }
89 
90 void hsm_compute_ht_point(hsm_buffer b, double x0, double y0, double weight) {
91 
92  double x1 = x0 * b->disp_th_cos - y0 * b->disp_th_sin + b->disp[0];
93  double y1 = x0 * b->disp_th_sin + y0 * b->disp_th_cos + b->disp[1];
94 
95  for(int i=0; i<b->num_angular_cells; i++) {
96  double rho = x1 * b->cost[i] + y1 * b->sint[i];
97  int rho_index;
98  double alpha;
99  if(!hsm_rho2index(b, rho, &rho_index, &alpha)) {
100  continue;
101  }
102 
103  b->ht[i][rho_index] += (1-fabs(alpha)) * weight;
104 
105  if( (alpha > 0) && (rho_index < b->num_linear_cells - 1))
106  b->ht[i][rho_index+1] += (fabs(alpha)) * weight;
107 
108  if( (alpha < 0) && (rho_index > 0))
109  b->ht[i][rho_index-1] += (fabs(alpha)) * weight;
110  }
111 }
112 
113 double mdax(double a, double b) {
114  return a>b?a:b;
115 }
116 
119 int hsm_rho2index(hsm_buffer b, double rho, int *rho_index, double *alpha) {
120  *rho_index = 0; *alpha = NAN;
121  if ( (rho <= b->rho_min) || (rho >= b->rho_max) )
122  return 0;
123 
124  /* x belongs to [0, n) */
125  double x = b->num_linear_cells * (rho-b->rho_min) / (b->rho_max-b->rho_min);
126 
127  if(x==b->num_linear_cells) x*=0.99999;
128 
129  *rho_index = (int) floor( x );
130  *alpha = (*rho_index+0.5)-x;
131 
132  assert(fabs(*alpha) <= 0.5001);
133  assert(*rho_index >= 0);
134  assert(*rho_index < b->num_linear_cells);
135 
136  return 1;
137 }
138 
139 
141  for(int t=0; t<b->num_angular_cells; t++) {
142  b->hs[t] = 0;
143  for(int r=0;r<b->num_linear_cells;r++)
144  b->hs[t] = max(b->hs[t], b->ht[t][r]);
145  }
146 }
147 
149  for(int t=0; t<b->num_angular_cells; t++) {
150  b->hs[t] = 0;
151  for(int r=0;r<b->num_linear_cells;r++)
152  b->hs[t] += b->ht[t][r] * b->ht[t][r];
153  }
154 }
155 
157  sm_log_push("hsm_match");
158  /* Let's measure the time */
159  clock_t hsm_match_start = clock();
160 
161  assert(b1->num_angular_cells == b2->num_angular_cells);
162  assert(p->max_translation > 0);
163  assert(b1->linear_cell_size > 0);
164 
165  b1->num_valid_results = 0;
166 
167  /* Compute cross-correlation of spectra */
169 
170  /* Find peaks in cross-correlation */
171  int peaks[p->num_angular_hypotheses], npeaks;
173 
174  sm_debug("Found %d peaks (max %d) in cross correlation.\n", npeaks, p->num_angular_hypotheses);
175 
176  if(npeaks == 0) {
177  sm_error("Cross correlation of spectra has 0 peaks.\n");
178  sm_log_pop();
179  return;
180  }
181 
182  sm_log_push("loop on theta hypotheses");
183  /* lag e' quanto 2 si sposta a destra rispetto a 1 */
184  for(int np=0;np<npeaks;np++) {
185  int lag = peaks[np];
186  double theta_hypothesis = lag * (2*M_PI/b1->num_angular_cells);
187 
188  sm_debug("Theta hyp#%d: lag %d, angle %fdeg\n", np, lag, rad2deg(theta_hypothesis));
189 
190  /* Superimpose the two spectra */
191  double mult[b1->num_angular_cells];
192  for(int r=0;r<b1->num_angular_cells;r++)
193  mult[r] = b1->hs[r] * b2->hs[pos_mod(r-lag, b1->num_angular_cells)];
194 
195  /* Find directions where both are intense */
196  int directions[p->xc_ndirections], ndirections;
198 
199  if(ndirections<2) {
200  sm_error("Too few directions.\n");
201  }
202 
203  #define MAX_NPEAKS 1024
204  assert(p->linear_xc_max_npeaks<MAX_NPEAKS);
205 
206  struct {
207  /* Direction of cross correlation */
208  double angle;
209  int nhypotheses;
210  struct {
211  double delta;
212  double value;
213  // } hypotheses[p->linear_xc_max_npeaks];
214  } hypotheses[MAX_NPEAKS];
215  } dirs[ndirections];
216 
217 
218  sm_debug("Using %d (max %d) correlations directions.\n", ndirections, p->xc_ndirections);
219 
220  int max_lag = (int) ceil(p->max_translation / b1->linear_cell_size);
221  int min_lag = -max_lag;
222  sm_debug("Max lag: %d cells (max t: %f, cell size: %f)\n",
223  max_lag, p->max_translation, b1->linear_cell_size);
224 
225  sm_log_push("loop on xc direction");
226  /* For each correlation direction */
227  for(int cd=0;cd<ndirections;cd++) {
228 
229  dirs[cd].angle = theta_hypothesis + (directions[cd]) * (2*M_PI/b1->num_angular_cells);
230 
231  printf(" cd %d angle = %d deg\n", cd, (int) rad2deg(dirs[cd].angle));
232 
233  /* Do correlation */
234  int lags [2*max_lag + 1];
235  double xcorr [2*max_lag + 1];
236 
237  int i1 = pos_mod(directions[cd] , b1->num_angular_cells);
238  int i2 = pos_mod(directions[cd] + lag , b1->num_angular_cells);
239  double *f1 = b1->ht[i1];
240  double *f2 = b2->ht[i2];
241 
243  b2->num_linear_cells,f2,
244  b1->num_linear_cells,f1,
245  xcorr, lags, min_lag, max_lag);
246 
247  /* Find peaks of cross-correlation */
248  int linear_peaks[p->linear_xc_max_npeaks], linear_npeaks;
249 
251  2*max_lag + 1, xcorr, p->linear_xc_peaks_min_distance/b1->linear_cell_size,
252  p->linear_xc_max_npeaks, linear_peaks, &linear_npeaks);
253 
254  sm_debug("theta hyp #%d: Found %d (max %d) peaks for correlation.\n",
255  cd, linear_npeaks, p->linear_xc_max_npeaks);
256 
257  dirs[cd].nhypotheses = linear_npeaks;
258  sm_log_push("Considering each peak of linear xc");
259  for(int lp=0;lp<linear_npeaks;lp++) {
260  int linear_xc_lag = lags[linear_peaks[lp]];
261  double value = xcorr[linear_peaks[lp]];
262  double linear_xc_lag_m = linear_xc_lag * b1->linear_cell_size;
263  sm_debug("lag: %d delta: %f value: %f \n", linear_xc_lag, linear_xc_lag_m, value);
264  dirs[cd].hypotheses[lp].delta = linear_xc_lag_m;
265  dirs[cd].hypotheses[lp].value = value;
266  }
267  sm_log_pop();
268 
269  if(p->debug_true_x_valid) {
270  double true_delta = cos(dirs[cd].angle) * p->debug_true_x[0] +
271  sin(dirs[cd].angle) * p->debug_true_x[1];
272  sm_debug("true_x delta = %f \n", true_delta );
273  }
274 
275  } /* xc direction */
276  sm_log_pop();
277 
278  sm_debug("Now doing all combinations. How many are there?\n");
279  int possible_choices[ndirections];
280  int num_combinations = 1;
281  for(int cd=0;cd<ndirections;cd++) {
282  possible_choices[cd] = dirs[cd].nhypotheses;
283  num_combinations *= dirs[cd].nhypotheses;
284  }
285  sm_debug("Total: %d combinations\n", num_combinations);
286  sm_log_push("For each combination..");
287  for(int comb=0;comb<num_combinations;comb++) {
288  int choices[ndirections];
289  hsm_generate_combinations(ndirections, possible_choices, comb, choices);
290 
291  /* Linear least squares */
292  double M[2][2]={{0,0},{0,0}}; double Z[2]={0,0};
293  /* heuristic quality value */
294  double sum_values = 0;
295  for(int cd=0;cd<ndirections;cd++) {
296  double angle = dirs[cd].angle;
297  double c = cos(angle), s = sin(angle);
298  double w = dirs[cd].hypotheses[choices[cd]].value;
299  double y = dirs[cd].hypotheses[choices[cd]].delta;
300 
301  M[0][0] += c * c * w;
302  M[1][0] += c * s * w;
303  M[0][1] += c * s * w;
304  M[1][1] += s * s * w;
305  Z[0] += w * c * y;
306  Z[1] += w * s * y;
307 
308  sum_values += w;
309  }
310 
311  double det = M[0][0]*M[1][1]-M[0][1]*M[1][0];
312  double Minv[2][2];
313  Minv[0][0] = M[1][1] * (1/det);
314  Minv[1][1] = M[0][0] * (1/det);
315  Minv[0][1] = -M[0][1] * (1/det);
316  Minv[1][0] = -M[1][0] * (1/det);
317 
318  double t[2] = {
319  Minv[0][0]*Z[0] + Minv[0][1]*Z[1],
320  Minv[1][0]*Z[0] + Minv[1][1]*Z[1]};
321 
322  /* copy result in results slot */
323 
324  int k = b1->num_valid_results;
325  b1->results[k][0] = t[0];
326  b1->results[k][1] = t[1];
327  b1->results[k][2] = theta_hypothesis;
328  b1->results_quality[k] = sum_values;
329  b1->num_valid_results++;
330  }
331  sm_log_pop();
332 
333  } /* theta hypothesis */
334  sm_log_pop();
335 
336 /* for(int i=0;i<b1->num_valid_results;i++) {
337  printf("#%d %.0fdeg %.1fm %.1fm quality %f \n",i,
338  rad2deg(b1->results[i][2]),
339  b1->results[i][0],
340  b1->results[i][1],
341  b1->results_quality[i]);
342  }*/
343 
344 
345  /* Sorting based on values */
346  int indexes[b1->num_valid_results];
347  for(int i=0;i<b1->num_valid_results;i++)
348  indexes[i] = i;
349 
350  qsort_descending(indexes, (size_t) b1->num_valid_results, b1->results_quality);
351 
352  /* copy in the correct order*/
353  double*results_tmp[b1->num_valid_results];
354  double results_quality_tmp[b1->num_valid_results];
355  for(int i=0;i<b1->num_valid_results;i++) {
356  results_tmp[i] = b1->results[i];
357  results_quality_tmp[i] = b1->results_quality[i];
358  }
359 
360  for(int i=0;i<b1->num_valid_results;i++) {
361  b1->results[i] = results_tmp[indexes[i]];
362  b1->results_quality[i] = results_quality_tmp[indexes[i]];
363  }
364 
365  for(int i=0;i<b1->num_valid_results;i++) {
366  char near[256]="";
367  double *x = b1->results[i];
368  if(p->debug_true_x_valid) {
369  double err_th = rad2deg(fabs(angleDiff(p->debug_true_x[2],x[2])));
370  double err_m = hypot(p->debug_true_x[0]-x[0],
371  p->debug_true_x[1]-x[1]);
372  const char * ast = (i == 0) && (err_th > 2) ? " ***** " : "";
373  sprintf(near, "th err %4d err_m %5f %s",(int)err_th ,err_m,ast);
374  }
375  if(i<10)
376  printf("after #%d %3.1fm %.1fm %3.0fdeg quality %5.0f \t%s\n",i,
377  x[0],
378  x[1], rad2deg(x[2]), b1->results_quality[i], near);
379  }
380 
381 
382  /* How long did it take? */
383  clock_t hsm_match_stop = clock();
384  int ticks = hsm_match_stop-hsm_match_start;
385  double ctime = ((double)ticks) / CLOCKS_PER_SEC;
386  sm_debug("Time: %f sec (%d ticks)\n", ctime, ticks);
387 
388  sm_log_pop();
389 }
390 
391 
392 void hsm_generate_combinations(int nslots, const int possible_choices[],
393  int i, int i_choice[])
394 {
395  for(int slot=0;slot<nslots;slot++) {
396  i_choice[slot] = i % possible_choices[slot];
397  i = (i - i % possible_choices[slot]) / possible_choices[slot];
398  }
399 }
400 
401 void hsm_find_peaks_circ(int n, const double*f, double min_angle_deg, int unidir, int max_peaks,
402  int*peaks, int* npeaks)
403 {
404  sm_log_push("hsm_find_peaks_circ");
405 
406  assert(max_peaks>0);
407 
408  /* Find all local maxima for the function */
409  int maxima[n], nmaxima;
410  hsm_find_local_maxima_circ(n, f, maxima, &nmaxima);
411 
412  sm_debug("Found %d of %d are local maxima.\n", nmaxima, n);
413 
414  /* Sort based on value */
415  qsort_descending(maxima, (size_t) nmaxima, f);
416 
417  *npeaks = 0;
418 
419  sm_log_push("For each maximum");
420  /* Only retain a subset of these */
421  for(int m=0;m<nmaxima;m++) {
422  /* Here's a candidate maximum */
423  int candidate = maxima[m];
424  double candidate_angle = candidate * (2*M_PI/n);
425  /* Check that is not too close to the already accepted maxima */
426  int acceptable = 1;
427  for(int a=0;a<*npeaks;a++) {
428  int other = peaks[a];
429  double other_angle = other * (2*M_PI/n);
430 
431  if(hsm_is_angle_between_smaller_than_deg(candidate_angle,other_angle,min_angle_deg)) {
432  acceptable = 0; break;
433  }
434 
435  /* If unidir, check also +M_PI */
436  if(unidir)
437  if(hsm_is_angle_between_smaller_than_deg(candidate_angle+M_PI,other_angle,min_angle_deg)) {
438  acceptable = 0; break;
439  }
440 
441  }
442 
443  sm_debug("%saccepting candidate %d; lag = %d value = %f\n",
444  acceptable?"":"not ", m, maxima[m], f[maxima[m]]);
445 
446  if(acceptable) {
447  peaks[*npeaks] = candidate;
448  (*npeaks) ++;
449  }
450 
451  if(*npeaks>=max_peaks) break;
452  }
453  sm_log_pop();
454 
455  sm_debug("found %d (max %d) maxima.\n", *npeaks, max_peaks);
456  sm_log_pop();
457 }
458 
459 
460 void hsm_find_peaks_linear(int n, const double*f, double min_dist, int max_peaks,
461  int*peaks, int* npeaks)
462 {
463  sm_log_push("hsm_find_peaks_linear");
464 
465  assert(max_peaks>0);
466 
467  /* Find all local maxima for the function */
468  int maxima[n], nmaxima;
469  hsm_find_local_maxima_linear(n,f,maxima,&nmaxima);
470 
471  sm_debug("Found %d of %d are local maxima.\n", nmaxima, n);
472 
473  /* Sort based on value */
474  qsort_descending(maxima, (size_t) nmaxima, f);
475 
476  *npeaks = 0;
477  sm_log_push("for each maximum");
478  /* Only retain a subset of these */
479  for(int m=0;m<nmaxima;m++) {
480  /* Here's a candidate maximum */
481  int candidate = maxima[m];
482  /* Check that is not too close to the already accepted maxima */
483  int acceptable = 1;
484  for(int a=0;a<*npeaks;a++) {
485  int other = peaks[a];
486 
487  if(abs(other-candidate) < min_dist) {
488  acceptable = 0; break;
489  }
490  }
491 
492  sm_debug("%s accepting candidate %d; lag = %d value = %f\n",
493  acceptable?"":"not", m, maxima[m], f[maxima[m]]);
494 
495  if(acceptable) {
496  peaks[*npeaks] = candidate;
497  (*npeaks) ++;
498  }
499 
500  if(*npeaks >= max_peaks) break;
501  }
502  sm_log_pop("");
503  sm_debug("Found %d (max %d) maxima.\n", *npeaks, max_peaks);
504 
505  sm_log_pop();
506 }
507 
508 
509 int hsm_is_angle_between_smaller_than_deg(double angle1, double angle2, double threshold_deg) {
510  double dot = cos(angle1)*cos(angle2) + sin(angle1)*sin(angle2);
511  return (dot > cos(threshold_deg * M_PI/180));
512 }
513 
514 void hsm_find_local_maxima_circ(int n, const double*f, int*maxima, int*nmaxima) {
515  *nmaxima = 0;
516  for(int i=0;i<n;i++) {
517  double val = f[i];
518  double left = f[ pos_mod(i-1,n) ];
519  double right = f[ pos_mod(i+1,n) ];
520  if( (val>0) && (val>left) && (val>right))
521  maxima[(*nmaxima)++] = i;
522  }
523 }
524 
525 
526 void hsm_find_local_maxima_linear(int n, const double*f, int*maxima, int*nmaxima) {
527  *nmaxima = 0;
528  for(int i=1;i<n-1;i++) {
529  double val = f[i];
530  double left = f[i-1];
531  double right = f[i+1];
532  if( (val>0) && (val>left) && (val>right))
533  maxima[(*nmaxima)++] = i;
534  }
535 }
536 
537 
538 
539 void hsm_circular_cross_corr_stupid(int n, const double *a, const double *b, double*res) {
540  /* Two copies of f1 */
541  double aa[2*n];
542  for(int i=0;i<2*n;i++) aa[i] = a[i%n];
543  for(int lag=0;lag<n;lag++) {
544  res[lag] = 0;
545  for(int j=0;j<n;j++)
546  res[lag] += b[j] * aa[j+lag];
547  }
548 }
549 
550 
551 void hsm_linear_cross_corr_stupid(int na, const double *a, int nb, const double *b, double*res, int*lags, int min_lag, int max_lag) {
552  assert(a);
553  assert(b);
554  assert(res);
555  assert(lags);
556 
557  for(int l=min_lag;l<=max_lag;l++) {
558  lags[l-min_lag] = l;
559 
560  double r = 0;
561  for(int j=0; (j<nb) && (j+l<na);j++) {
562  // j + l >= 0
563  if(j+l>=0)
564  r += b[j] * a[j+l];
565  }
566 
567  res[l-min_lag] = r;
568 
569  }
570 }
571 
572 
573 const double *qsort_descending_values = 0;
574 
575 int compare_descending(const void *index_pt1, const void *index_pt2) {
576  int i1 = *( (const int*) index_pt1);
577  int i2 = *( (const int*) index_pt2);
578  const double * f = qsort_descending_values;
579  return f[i1] < f[i2] ? +1 : f[i1] == f[i2] ? 0 : -1;
580 }
581 
582 void qsort_descending(int *indexes, size_t nmemb, const double*values)
583 {
584  qsort_descending_values = values;
585  qsort(indexes, nmemb, sizeof(int), compare_descending);
586 }
587 
588 
589 
591 int pos_mod(int a, int b) {
592  return ((a%b)+b)%b;
593 }
594 
595 
596 
void sm_log_push(const char *cname)
Definition: logging.c:118
int hsm_is_angle_between_smaller_than_deg(double angle1, double angle2, double threshold_deg)
Definition: hsm.c:509
void hsm_buffer_free(hsm_buffer b)
Definition: hsm.c:62
void hsm_generate_combinations(int nslots, const int possible_choices[], int i, int i_choice[])
Definition: hsm.c:392
#define MAX_NPEAKS
#define NAN
Definition: math_utils.h:11
void hsm_circular_cross_corr_stupid(int n, const double *a, const double *b, double *res)
Definition: hsm.c:539
int hsm_rho2index(hsm_buffer b, double rho, int *rho_index, double *alpha)
Definition: hsm.c:119
double ** results
Definition: hsm.h:76
void hsm_compute_ht_base(hsm_buffer b, const double base_pose[3])
Definition: hsm.c:82
double angleDiff(double a, double b)
Definition: math_utils.c:128
#define max(a, b)
Definition: bits.h:20
Definition: egsl.h:12
void hsm_find_peaks_circ(int n, const double *f, double min_angle_deg, int unidir, int max_peaks, int *peaks, int *npeaks)
Definition: hsm.c:401
int num_angular_hypotheses
Definition: hsm.h:16
void hsm_compute_ht_point(hsm_buffer b, double x0, double y0, double weight)
Definition: hsm.c:90
double * cost
Definition: hsm.h:86
void hsm_compute_spectrum_norm(hsm_buffer b)
Definition: hsm.c:148
void qsort_descending(int *indexes, size_t nmemb, const double *values)
Definition: hsm.c:582
double * results_quality
Definition: hsm.h:79
int compare_descending(const void *index_pt1, const void *index_pt2)
Definition: hsm.c:575
double mdax(double a, double b)
Definition: hsm.c:113
void hsm_compute_spectrum(hsm_buffer b)
Definition: hsm.c:140
void hsm_find_local_maxima_linear(int n, const double *f, int *maxima, int *nmaxima)
Definition: hsm.c:526
double angular_cell_size_deg
Definition: hsm.h:13
hsm_buffer hsm_buffer_alloc(struct hsm_params *p)
Definition: hsm.c:10
int num_valid_results
Definition: hsm.h:73
double rho_max
Definition: hsm.h:59
double debug_true_x[3]
Definition: hsm.h:42
#define M_PI
Definition: math_utils.h:7
const double * qsort_descending_values
Definition: hsm.c:573
double * sint
Definition: hsm.h:86
double linear_xc_peaks_min_distance
Definition: hsm.h:33
double * hs_cross_corr
Definition: hsm.h:89
#define m(v1, v2)
Definition: egsl_macros.h:13
double disp_th_sin
Definition: hsm.h:93
int num_angular_cells
Definition: hsm.h:50
int pos_mod(int a, int b)
Definition: hsm.c:591
int linear_xc_max_npeaks
Definition: hsm.h:30
double disp_th_cos
Definition: hsm.h:93
double disp[3]
Definition: hsm.h:92
void hsm_match(struct hsm_params *p, hsm_buffer b1, hsm_buffer b2)
Definition: hsm.c:156
struct @0 p
#define M(matrix, rows, col)
Definition: gpc.c:25
double xc_directions_min_distance_deg
Definition: hsm.h:26
int debug_true_x_valid
Definition: hsm.h:40
double linear_cell_size
Definition: hsm.h:56
double linear_cell_size
Definition: hsm.h:11
void hsm_find_peaks_linear(int n, const double *f, double min_dist, int max_peaks, int *peaks, int *npeaks)
Definition: hsm.c:460
void sm_log_pop()
Definition: logging.c:130
int max_num_results
Definition: hsm.h:70
double rho_min
Definition: hsm.h:59
struct hsm_buffer_struct * hsm_buffer
Definition: hsm.h:96
Definition: hsm.h:7
double max_norm
Definition: hsm.h:9
int num_linear_cells
Definition: hsm.h:53
int xc_ndirections
Definition: hsm.h:23
double max_translation
Definition: hsm.h:37
double ** ht
Definition: hsm.h:62
void sm_debug(const char *msg,...)
Definition: logging.c:88
double * hs
Definition: hsm.h:65
void hsm_find_local_maxima_circ(int n, const double *f, int *maxima, int *nmaxima)
Definition: hsm.c:514
void sm_error(const char *msg,...)
Definition: logging.c:49
double angular_hyp_min_distance_deg
Definition: hsm.h:19
void hsm_linear_cross_corr_stupid(int na, const double *a, int nb, const double *b, double *res, int *lags, int min_lag, int max_lag)
Definition: hsm.c:551
double rad2deg(double rad)
Definition: math_utils.c:79
double * theta
Definition: hsm.h:83


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23