38 #include "hugin_config.h"
94 template<
class Estimator,
class S,
class T>
95 static std::vector<const T*>
compute(S & parameters,
96 std::vector<int> & inliers,
97 const Estimator & paramEstimator ,
98 const std::vector<T> &
data,
99 double desiredProbabilityForNoOutliers,
100 double maximalOutlierPercentage);
125 template<
class Estimator,
class S,
class T>
126 static std::vector<const T*>
compute(S ¶meters,
127 const Estimator & paramEstimator ,
128 const std::vector<T> &data);
135 static unsigned int choose(
unsigned int n,
unsigned int m);
137 template<
class Estimator,
class T>
139 const std::vector<T> &data,
141 short *bestVotes,
short *curVotes,
142 int &numVotesForBest,
int startIndex,
143 int n,
int k,
int arrIndex,
int *arr);
146 template<
class Estimator,
class T,
class S>
147 static void estimate(
const Estimator & paramEstimator,
const std::vector<T> &data,
149 short *bestVotes,
short *curVotes,
150 int &numVotesForBest,
int *arr);
163 if(arr1[i] < arr2[i])
174 template<
class Estimator,
class S,
class T>
176 std::vector<int> & inliers,
177 const Estimator & paramEstimator,
178 const std::vector<T> &
data,
179 double desiredProbabilityForNoOutliers,
180 double maximalOutlierPercentage)
182 unsigned int numDataObjects = (int) data.size();
183 unsigned int numForEstimate = paramEstimator.numForEstimate();
186 if(numDataObjects < numForEstimate || maximalOutlierPercentage>=1.0)
187 return std::vector<const T*>();
189 std::vector<const T *> exactEstimateData;
190 std::vector<const T *> leastSquaresEstimateData;
191 S exactEstimateParameters;
192 int i, j, k, l, numVotesForBest, numVotesForCur, maxIndex, numTries;
193 short *bestVotes =
new short[numDataObjects];
194 short *curVotes =
new short[numDataObjects];
195 short *notChosen =
new short[numDataObjects];
197 std::set<int *, SubSetIndexComparator > chosenSubSets(subSetIndexComparator);
198 int *curSubSetIndexes;
200 double numerator =
log(1.0-desiredProbabilityForNoOutliers);
201 double denominator =
log(1-
pow((
double)(1.0-maximalOutlierPercentage), (
double)(numForEstimate)));
202 int allTries =
choose(numDataObjects,numForEstimate);
210 maxIndex = numDataObjects - 1;
211 std::mt19937 rng(static_cast<unsigned int>(std::time(0)));
212 std::uniform_int_distribution<> distribIndex(0, maxIndex);
213 auto randIndex=std::bind(distribIndex, rng);
216 numTries = (int)(numerator/denominator + 0.5);
219 numTries = numTries<allTries ? numTries : allTries;
221 for(i=0; i<numTries; i++) {
223 memset(notChosen,
'1',numDataObjects*
sizeof(
short));
224 curSubSetIndexes =
new int[numForEstimate];
226 exactEstimateData.clear();
228 maxIndex = numDataObjects-1;
229 for(l=0; l<(int)numForEstimate; l++) {
231 unsigned int selectedIndex = randIndex();
233 for(j=-1,k=0; k<(int)numDataObjects && j<(
int)selectedIndex; k++) {
238 exactEstimateData.push_back(&(data[k]));
244 for(l=0, j=0; j<(int)numDataObjects; j++) {
246 curSubSetIndexes[l] = j+1;
252 std::pair< std::set<int *, SubSetIndexComparator >::iterator,
bool > res = chosenSubSets.insert(curSubSetIndexes);
254 if(res.second ==
true) {
256 if (!paramEstimator.estimate(exactEstimateData,exactEstimateParameters))
262 memset(curVotes,
'\0',numDataObjects*
sizeof(
short));
263 for(j=0; j<(int)numDataObjects; j++) {
264 if(paramEstimator.agree(exactEstimateParameters, data[j])) {
271 std::cerr <<
"RANSAC iter " << i <<
": inliers: " << numVotesForCur <<
" parameters:";
272 for (
int jj=0; jj < exactEstimateParameters.size(); jj++)
273 std::cerr <<
" " << exactEstimateParameters[jj];
274 std::cerr << std::endl;
277 if(numVotesForCur > numVotesForBest) {
278 numVotesForBest = numVotesForCur;
279 memcpy(bestVotes,curVotes, numDataObjects*
sizeof(
short));
280 parameters = exactEstimateParameters;
295 delete [] curSubSetIndexes;
301 std::set<int *, SubSetIndexComparator >::iterator it = chosenSubSets.begin();
302 std::set<int *, SubSetIndexComparator >::iterator chosenSubSetsEnd = chosenSubSets.end();
303 while(it!=chosenSubSetsEnd) {
307 chosenSubSets.clear();
310 if(numVotesForBest > 0) {
311 for(j=0; j<(int)numDataObjects; j++) {
313 leastSquaresEstimateData.push_back(&(data[j]));
314 inliers.push_back(j);
317 paramEstimator.leastSquaresEstimate(leastSquaresEstimateData,parameters);
323 return leastSquaresEstimateData;
326 template<
class Estimator,
class S,
class T>
328 const Estimator & paramEstimator,
329 const std::vector<T> &
data)
331 unsigned int numForEstimate = paramEstimator.numForEstimate();
332 std::vector<T *> leastSquaresEstimateData;
333 int numDataObjects = data.size();
334 int numVotesForBest = 0;
335 int *arr =
new int[numForEstimate];
336 short *curVotes =
new short[numDataObjects];
337 short *bestVotes =
new short[numDataObjects];
342 if(numDataObjects < numForEstimate)
346 bestVotes, curVotes, numVotesForBest, 0, data.size(), numForEstimate, 0, arr);
349 if(numVotesForBest > 0) {
350 for(
int j=0; j<numDataObjects; j++) {
352 leastSquaresEstimateData.push_back(&(data[j]));
354 paramEstimator.leastSquaresEstimate(leastSquaresEstimateData,parameters);
361 return leastSquaresEstimateData;
364 template<
class Estimator,
class T>
366 int numForEstimate,
short *bestVotes,
short *curVotes,
367 int &numVotesForBest,
int startIndex,
int n,
int k,
368 int arrIndex,
int *arr)
372 estimate(paramEstimator, data, numForEstimate, bestVotes, curVotes, numVotesForBest, arr);
378 for(
int i=startIndex; i<=endIndex; i++) {
380 computeAllChoices(paramEstimator, data, numForEstimate, bestVotes, curVotes, numVotesForBest,
381 i+1, n, k-1, arrIndex+1, arr);
386 template<
class Estimator,
class T,
class S>
388 int numForEstimate,
short *bestVotes,
short *curVotes,
389 int &numVotesForBest,
int *arr)
391 std::vector<T *> exactEstimateData;
392 std::vector<S> exactEstimateParameters;
397 numDataObjects = data.size();
398 memset(curVotes,
'\0',numDataObjects*
sizeof(
short));
401 for(j=0; j<numForEstimate; j++)
402 exactEstimateData.push_back(&(data[arr[j]]));
403 paramEstimator.estimate(exactEstimateData,exactEstimateParameters);
405 if(exactEstimateParameters.empty())
408 for(j=0; j<numDataObjects; j++) {
409 if(paramEstimator.agree(exactEstimateParameters, data[j])) {
414 if(numVotesForCur > numVotesForBest) {
415 numVotesForBest = numVotesForCur;
416 memcpy(bestVotes,curVotes, numDataObjects*
sizeof(
short));
422 unsigned int denominatorEnd, numeratorStart, numerator,denominator;
424 numeratorStart = n-m+1;
428 numeratorStart = m+1;
429 denominatorEnd = n-m;
433 for(i=numeratorStart, numerator=1; i<=n; i++)
435 for(i=1, denominator=1; i<=denominatorEnd; i++)
437 return numerator/denominator;
static std::vector< const T * > compute(S ¶meters, std::vector< int > &inliers, const Estimator ¶mEstimator, const std::vector< T > &data, double desiredProbabilityForNoOutliers, double maximalOutlierPercentage)
Estimate the model parameters using the RanSac framework.
SubSetIndexComparator(int arrayLength)
float pow(float a, double b)
static void estimate(const Estimator ¶mEstimator, const std::vector< T > &data, int numForEstimate, short *bestVotes, short *curVotes, int &numVotesForBest, int *arr)
bool operator()(const int *arr1, const int *arr2) const
static void computeAllChoices(const Estimator ¶mEstimator, const std::vector< T > &data, int numForEstimate, short *bestVotes, short *curVotes, int &numVotesForBest, int startIndex, int n, int k, int arrIndex, int *arr)
vigra::RGBValue< T, RIDX, GIDX, BIDX > log(vigra::RGBValue< T, RIDX, GIDX, BIDX > const &v)
component-wise logarithm
static unsigned int choose(unsigned int n, unsigned int m)
Compute n choose m [ n!/(m!*(n-m)!)].
This class implements the Random Sample Consensus (RanSac) framework, a framework for robust paramete...
options wxIntPtr wxIntPtr sortData std::vector< PanoInfo > * data