Ransac.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ALVAR, A Library for Virtual and Augmented Reality.
3  *
4  * Copyright 2007-2012 VTT Technical Research Centre of Finland
5  *
6  * Contact: VTT Augmented Reality Team <alvar.info@vtt.fi>
7  * <http://www.vtt.fi/multimedia/alvar.html>
8  *
9  * ALVAR is free software; you can redistribute it and/or modify it under the
10  * terms of the GNU Lesser General Public License as published by the Free
11  * Software Foundation; either version 2.1 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
17  * for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with ALVAR; if not, see
21  * <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
22  */
23 
24 #include "Ransac.h"
25 #include <memory.h>
26 #include <math.h>
27 
28 #ifdef TRACE
29  #include <stdio.h>
30 #endif
31 
32 namespace alvar {
33 
34 RansacImpl::RansacImpl(int min_params, int max_params,
35  int sizeof_param, int sizeof_model) {
36  this->min_params = min_params;
37  this->max_params = max_params;
38  this->sizeof_param = sizeof_param;
39  this->sizeof_model = sizeof_model;
40  indices = NULL;
41 
42  samples = new void*[max_params];
43  if (!samples) {
44 #ifdef TRACE
45  printf("Cound not allocate memory for %d sample pointers.",
46  max_params);
47 #endif
48  }
49 
50  hypothesis = new char[sizeof_model];
51  if (!hypothesis) {
52 #ifdef TRACE
53  printf("Cound not allocate %d bytes of memory for model parameters.",
54  sizeof_model);
55 #endif
56  }
57 }
58 
60  if (samples) delete[] samples;
61  if (hypothesis) delete[] (char *)hypothesis;
62  if (indices) delete[] indices;
63 }
64 
65 int RansacImpl::_estimate(void* params, int param_c,
66  int support_limit, int max_rounds,
67  void* model) {
68  if (param_c < min_params) return 0;
69 
70  int max_support = 0;
71 
72  // Randomly search for the best model.
73  for (int i = 0;
74  i < max_rounds && max_support < support_limit;
75  i++) {
76  // 1. pick a random sample of min_params.
77  int sample_c;
78  for (sample_c = 0; sample_c < min_params; sample_c++) {
79  int r = rand() % (param_c-sample_c);
80  void* s = (char*)params + r*sizeof_param;
81  for (int j = 0; j < sample_c; j++)
82  if (s >= samples[j]) s = (char*)s + sizeof_param;
83  samples[sample_c] = s;
84  }
85 
86  // 2. create a model from the sampled parameters.
87  _doEstimate(samples, sample_c, hypothesis);
88 
89  // 3. count the support for the model.
90  int hypo_support = 0;
91  for (int j = 0; j < param_c; j++) {
92  if (_doSupports((char*)params + j*sizeof_param, hypothesis)) {
93  hypo_support++;
94  }
95  }
96 #ifdef TRACE
97  printf("Hypothesis got %d support\n", hypo_support);
98 #endif
99  if (hypo_support > max_support) {
100  max_support = hypo_support;
101  memcpy(model, hypothesis, sizeof_model);
102  }
103  }
104 
105  return max_support;
106 }
107 
108 int RansacImpl::_refine(void* params, int param_c,
109  int support_limit, int max_rounds,
110  void* model, char *inlier_mask) {
111  if (param_c < min_params) return 0;
112 
113  int max_support = 0;
114 
115  // Iteratively make the model estimation better.
116  for (int i = 0;
117  i < max_rounds && max_support < support_limit;
118  i++) {
119  int sample_c = 0;
120  // 1. Find all parameters that support the current model.
121  for (int j = 0; j < param_c && sample_c < max_params; j++) {
122  if (_doSupports((char*)params + j*sizeof_param, model)) {
123  samples[sample_c++] = (char*)params + j*sizeof_param;
124  if (inlier_mask) inlier_mask[j] = 1;
125  } else {
126  if (inlier_mask) inlier_mask[j] = 0;
127  }
128  }
129 #ifdef TRACE
130  printf("Found %d supporting parameters\n", sample_c);
131 #endif
132  if (sample_c > max_support) {
133  // 2. create a model from all supporting parameters.
134  _doEstimate(samples, sample_c, model);
135  max_support = sample_c;
136 
137  } else {
138  // until there are no new supporting parameters.
139  break;
140  }
141  }
142 
143  return max_support;
144 }
145 
149  this->min_params = min_params;
150  this->max_params = max_params;
151  this->sizeof_param = -1;
152  this->sizeof_model = sizeof_model;
153  samples = NULL;
154  indices = new int[max_params];
155  hypothesis = new char[sizeof_model];
156  if (!hypothesis) {
157 #ifdef TRACE
158  printf("Cound not allocate %d bytes of memory for model parameters.",
159  sizeof_model);
160 #endif
161  }
162 }
163 
164 int RansacImpl::_estimate(int param_c,
165  int support_limit, int max_rounds,
166  void* model) {
167  if (param_c < min_params) return 0;
168 
169  int max_support = 0;
170 
171  // Randomly search for the best model.
172  for (int i = 0;
173  i < max_rounds && max_support < support_limit;
174  i++) {
175  // 1. pick a random sample of min_params.
176  int sample_c;
177  for (sample_c = 0; sample_c < min_params; sample_c++) {
178  int r = rand() % (param_c-sample_c);
179  for (int j = 0; j < sample_c; j++)
180  if (r >= indices[j]) r++;
181  indices[sample_c] = r;
182  }
183 
184  // 2. create a model from the sampled parameters.
185  _doEstimate(indices, sample_c, hypothesis);
186 
187  // 3. count the support for the model.
188  int hypo_support = 0;
189  for (int j = 0; j < param_c; j++) {
190  if (_doSupports(j, hypothesis)) {
191  hypo_support++;
192  }
193  }
194 #ifdef TRACE
195  printf("Hypothesis got %d support\n", hypo_support);
196 #endif
197  if (hypo_support > max_support) {
198  max_support = hypo_support;
199  memcpy(model, hypothesis, sizeof_model);
200  }
201  }
202 
203  return max_support;
204 }
205 
206 int RansacImpl::_refine(int param_c,
207  int support_limit, int max_rounds,
208  void* model, char *inlier_mask) {
209  if (param_c < min_params) return 0;
210 
211  int max_support = 0;
212 
213  // Iteratively make the model estimation better.
214  for (int i = 0;
215  i < max_rounds && max_support < support_limit;
216  i++) {
217  int sample_c = 0;
218  // 1. Find all parameters that support the current model.
219  for (int j = 0; j < param_c && sample_c < max_params; j++) {
220  if (_doSupports(j, model)) {
221  indices[sample_c++] = j;
222  if (inlier_mask) inlier_mask[j] = 1;
223  } else {
224  if (inlier_mask) inlier_mask[j] = 0;
225  }
226  }
227 #ifdef TRACE
228  printf("Found %d supporting parameters\n", sample_c);
229 #endif
230  if (sample_c < min_params) break; // indicates too few points.
231  if (sample_c > max_support) {
232  // 2. create a model from all supporting parameters.
233  _doEstimate(indices, sample_c, model);
234  max_support = sample_c;
235 
236  } else {
237  // until there are no new supporting parameters.
238  break;
239  }
240  }
241 
242  return max_support;
243 }
244 
247 int RansacImpl::estimateRequiredRounds(float success_propability,
248  float inlier_percentage) {
249  return (int)
250  (log(1-success_propability) / log(1-pow(inlier_percentage,3)));
251 }
252 
253 } // namespace alvar
Main ALVAR namespace.
Definition: Alvar.h:174
RansacImpl(int min_params, int max_params, int sizeof_param, int sizeof_model)
Definition: Ransac.cpp:34
int _refine(void *params, int param_c, int support_limit, int max_rounds, void *model, char *inlier_mask=NULL)
Definition: Ransac.cpp:108
int _estimate(void *params, int param_c, int support_limit, int max_rounds, void *model)
Definition: Ransac.cpp:65
XmlRpcServer s
int sizeof_model
Definition: Ransac.h:49
This file implements a generic RANSAC algorithm.
virtual void _doEstimate(void **params, int param_c, void *model)
Definition: Ransac.h:63
int sizeof_param
Definition: Ransac.h:48
void ** samples
Definition: Ransac.h:44
virtual ~RansacImpl()
Definition: Ransac.cpp:59
void * hypothesis
Definition: Ransac.h:45
virtual bool _doSupports(void *param, void *model)
Definition: Ransac.h:64
r
int * indices
Definition: Ransac.h:64
int estimateRequiredRounds(float success_propability, float inlier_percentage)
How many rounds are needed for the Ransac to work.
Definition: Ransac.cpp:247


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Mon Jun 10 2019 12:47:04