icp_outliers.c
Go to the documentation of this file.
1 #include <math.h>
2 
3 #include "icp.h"
4 
5 void quicksort(double *array, int begin, int end);
6 double hoare_selection(double *data, int start, int end, int k);
7 
9 void visibilityTest(LDP laser_ref, const gsl_vector*u) {
10 
11  double theta_from_u[laser_ref->nrays];
12 
13  int j;
14  for(j=0;j<laser_ref->nrays;j++) {
15  if(!ld_valid_ray(laser_ref,j)) continue;
16  theta_from_u[j] =
17  atan2(gvg(u,1)-laser_ref->points[j].p[1],
18  gvg(u,0)-laser_ref->points[j].p[0]);
19  }
20 
21  sm_debug("\tvisibility: Found outliers: ");
22  int invalid = 0;
23  for(j=1;j<laser_ref->nrays;j++) {
24  if(!ld_valid_ray(laser_ref,j)||!ld_valid_ray(laser_ref,j-1)) continue;
25  if(theta_from_u[j]<theta_from_u[j-1]) {
26  laser_ref->valid[j] = 0;
27  invalid ++;
28  sm_debug("%d ",j);
29  }
30  }
31  sm_debug("\n");
32 }
33 
34 
43  double threshold = 3; /* TODO: add as configurable */
44 
45  LDP laser_ref = params->laser_ref;
46  LDP laser_sens = params->laser_sens;
47 
48  double dist2_i[laser_sens->nrays];
49  double dist2_j[laser_ref->nrays];
50  int j; for(j=0;j<laser_ref->nrays;j++)
51  dist2_j[j]= 1000000;
52 
53  int i;
54  for(i=0;i<laser_sens->nrays;i++) {
55  if(!ld_valid_corr(laser_sens, i)) continue;
56  int j1 = laser_sens->corr[i].j1;
57  dist2_i[i] = laser_sens->corr[i].dist2_j1;
58  dist2_j[j1] = GSL_MIN(dist2_j[j1], dist2_i[i]);
59  }
60 
61  int nkilled = 0;
62  for(i=0;i<laser_sens->nrays;i++) {
63  if(!ld_valid_corr(laser_sens, i)) continue;
64  int j1 = laser_sens->corr[i].j1;
65  if(dist2_i[i] > (threshold*threshold)*dist2_j[j1]) {
66  laser_sens->corr[i].valid=0;
67  nkilled ++;
68  }
69  }
70  sm_debug("\tkill_outliers_double: killed %d correspondences\n",nkilled);
71 }
72 
83 void kill_outliers_trim(struct sm_params*params, double*total_error) {
84 
85  if(JJ) jj_context_enter("kill_outliers_trim");
86 
87  LDP laser_ref = params->laser_ref;
88  LDP laser_sens = params->laser_sens;
89 
90  /* dist2, indexed by k, contains the error for the k-th correspondence */
91  int k = 0;
92  double dist2[laser_sens->nrays];
93 
94  int i;
95  double dist[laser_sens->nrays];
96  /* for each point in laser_sens */
97  for(i=0;i<laser_sens->nrays;i++) {
98  /* which has a valid correspondence */
99  if(!ld_valid_corr(laser_sens, i)) { dist[i]=NAN; continue; }
100  double *p_i_w = laser_sens->points_w[i].p;
101 
102  int j1 = laser_sens->corr[i].j1;
103  int j2 = laser_sens->corr[i].j2;
104  /* Compute the distance to the corresponding segment */
105  dist[i]= dist_to_segment_d(
106  laser_ref->points[j1].p, laser_ref->points[j2].p, p_i_w);
107  dist2[k] = dist[i];
108  k++;
109  }
110 
111 
112  if(JJ) jj_add_int("num_valid_before", k);
113  if(JJ) jj_add_double_array("dist_points", dist2, laser_sens->nrays);
114  if(JJ) jj_add_double_array("dist_corr_unsorted", dist2, k);
115 
116 #if 0
117  double dist2_copy[k]; for(i=0;i<k;i++) dist2_copy[i] = dist2[i];
118 #endif
119 
120  /* two errors limits are defined: */
121  /* In any case, we don't want more than outliers_maxPerc% */
122  int order = (int)floor(k*(params->outliers_maxPerc));
123  order = GSL_MAX(0, GSL_MIN(order, k-1));
124 
125  /* The dists for the correspondence are sorted
126  in ascending order */
127  quicksort(dist2, 0, k-1);
128  double error_limit1 = dist2[order];
129  if(JJ) jj_add_double_array("dist_corr_sorted", dist2, k);
130 
131  /* Then we take a order statics (o*K) */
132  /* And we say that the error must be less than alpha*dist(o*K) */
133  int order2 = (int)floor(k*params->outliers_adaptive_order);
134  order2 = GSL_MAX(0, GSL_MIN(order2, k-1));
135  double error_limit2 = params->outliers_adaptive_mult*dist2[order2];
136 
137  double error_limit = GSL_MIN(error_limit1, error_limit2);
138 
139 #if 0
140  double error_limit1_ho = hoare_selection(dist2_copy, 0, k-1, order);
141  double error_limit2_ho = error_limit2;
142  if((error_limit1_ho != error_limit1) || (error_limit2_ho != error_limit2)) {
143  printf("%f == %f %f == %f\n",
144  error_limit1_ho, error_limit1, error_limit2_ho, error_limit2);
145  }
146 #endif
147 
148  if(JJ) jj_add_double_array("dist_corr_sorted", dist2, k);
149  if(JJ) jj_add_double("error_limit_max_perc", error_limit1);
150  if(JJ) jj_add_double("error_limit_adaptive", error_limit2);
151  if(JJ) jj_add_double("error_limit", error_limit);
152 
153  sm_debug("\ticp_outliers: maxPerc %f error_limit: fix %f adaptive %f \n",
154  params->outliers_maxPerc,error_limit1,error_limit2);
155 
156  *total_error = 0;
157  int nvalid = 0;
158  for(i=0;i<laser_sens->nrays;i++) {
159  if(!ld_valid_corr(laser_sens, i)) continue;
160  if(dist[i] > error_limit) {
161  laser_sens->corr[i].valid = 0;
162  laser_sens->corr[i].j1 = -1;
163  laser_sens->corr[i].j2 = -1;
164  } else {
165  nvalid++;
166  *total_error += dist[i];
167  }
168  }
169 
170  sm_debug("\ticp_outliers: valid %d/%d (limit: %f) mean error = %f \n",nvalid,k,error_limit,
171  *total_error/nvalid);
172 
173  if(JJ) jj_add_int("num_valid_after", nvalid);
174  if(JJ) jj_add_double("total_error", *total_error);
175  if(JJ) jj_add_double("mean_error", *total_error / nvalid);
176 
177  if(JJ) jj_context_exit();
178 }
179 
180 
181 void swap_double(double*a,double*b) {
182  double t = *a; *a = *b; *b=t;
183 }
184 
186 void quicksort(double *array, int begin, int end) {
187  if (end > begin) {
188  double pivot = array[begin];
189  int l = begin + 1;
190  int r = end+1;
191  while(l < r) {
192  if (array[l] < pivot) {
193  l++;
194  } else {
195  r--;
196  swap_double(array+l, array+r);
197  }
198  }
199  l--;
200  swap_double(array+begin, array+l);
201  if(l>begin)
202  quicksort(array, begin, l);
203  if(end>r)
204  quicksort(array, r, end);
205  }
206 }
207 
208 #if 0
209 double hoare_selection(double *data, int start, int end, int k)
210 {
211  int pivotIndex, i, j;
212  float pivotValue, tmp;
213 
214  while(start < end) {
215  //select a random pivot
216  pivotIndex = start + (end-start)/2;
217  pivotValue = data[pivotIndex];
218  //sort the array into two sub arrays around the pivot value
219  i = start;
220  j = end;
221  while(i <= j) {
222  while(data[i] < pivotValue)
223  i++;
224  while(data[j] > pivotValue)
225  j--;
226  if(i<=j) {
227  tmp = data[i];
228  data[i] = data[j];
229  data[j] = tmp;
230  i++;
231  j--;
232  }
233  }
234  //continue search in left sub array
235  if(j < k)
236  start = i;
237  if(k < i) //continue search in right sub array
238  end = j;
239  }
240  return(data[k]);
241 }
242 
243 #endif
double dist2_j1
Definition: laser_data.h:71
int *restrict valid
Definition: laser_data.h:23
void jj_add_int(const char *name, int v)
Definition: json_journal.c:86
point2d *restrict points
Definition: laser_data.h:44
#define NAN
Definition: math_utils.h:11
#define gvg
Definition: math_utils_gsl.h:9
INLINE int ld_valid_corr(LDP ld, int i)
double hoare_selection(double *data, int start, int end, int k)
INLINE int ld_valid_ray(LDP ld, int i)
#define JJ
Definition: json_journal.h:21
void visibilityTest(LDP laser_ref, const gsl_vector *u)
Definition: icp_outliers.c:9
double outliers_adaptive_mult
Definition: algos.h:66
double outliers_maxPerc
Definition: algos.h:53
void swap_double(double *a, double *b)
Definition: icp_outliers.c:181
void kill_outliers_double(struct sm_params *params)
Definition: icp_outliers.c:42
void jj_context_exit()
Definition: json_journal.c:56
void kill_outliers_trim(struct sm_params *params, double *total_error)
Definition: icp_outliers.c:83
LDP laser_ref
Definition: algos.h:14
point2d *restrict points_w
Definition: laser_data.h:47
LDP laser_sens
Definition: algos.h:16
double dist_to_segment_d(const double a[2], const double b[2], const double x[2])
Definition: math_utils.c:181
void jj_add_double(const char *name, double v)
Definition: json_journal.c:91
struct correspondence *restrict corr
Definition: laser_data.h:36
void quicksort(double *array, int begin, int end)
Definition: icp_outliers.c:186
void jj_add_double_array(const char *name, double *v, int n)
Definition: json_journal.c:96
void sm_debug(const char *msg,...)
Definition: logging.c:88
double outliers_adaptive_order
Definition: algos.h:65
double p[2]
Definition: laser_data.h:12
void jj_context_enter(const char *context_name)
Definition: json_journal.c:36


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