2
* Copyright (C) 2007-2008 Anael Orlinski
4
* This file is part of Panomatic.
6
* Panomatic is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* Panomatic is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Panomatic; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include "RansacFiltering.h"
22
#include "Homography.h"
24
#include <boost/foreach.hpp>
28
static int genint(int x)
30
return (int)((double)rand()*x/(double)RAND_MAX);
36
// distance between estimate and real point in pixels.
38
double Ransac::calcError(Homography *aH, PointMatch &aM)
41
aH->transformPoint(aM._img1_x, aM._img1_y, x1p, y1p);
43
double d1 = aM._img2_x - x1p;
44
double d2 = aM._img2_y - y1p;
50
void Ransac::filter(PointMatchVector_t& ioMatches, PointMatchVector_t& ioRemovedMatches)
52
int aRemainingIterations = _nIter;
53
const double aErrorDistSq = _distanceThres * _distanceThres;
55
Homography aCurrentModel;
57
unsigned int aMaxInliers = 0;
58
PointMatchVector_t aBestInliers;
59
PointMatchVector_t aBestOutliers;
61
// normalization !!!!!!
62
aCurrentModel.initMatchesNormalization(ioMatches);
65
//std::cout << "gravity " << _v1x << " " << _v1y << " " << _v2x << " " << _v2y << endl;
67
for(; aRemainingIterations > 0; aRemainingIterations--)
69
//cout << "RANSAC -- iter " << aRemainingIterations << endl;
71
// random select 4 matches to fit the model
72
// from the input set as maybe_inliers
73
PointMatchVector_t aMatches(ioMatches);
74
PointMatchVector_t aInliers, aOutliers;
76
//std::cout << aMatches.size() << " matches size" << endl;
78
for(int i=0; i<5; i++)
80
int n = genint((int)aMatches.size()-1);
81
aInliers.push_back(aMatches.at(n));
82
aMatches.erase(aMatches.begin()+n);
85
//std::cout << aMatches.size() << " estimate" << endl;
87
if (!aCurrentModel.estimate(aInliers))
93
// for every point remaining in aMatches, add them to aInliers if they fit the model well.
94
BOOST_FOREACH(PointMatchPtr aMatchesIter2, aMatches)
96
if (calcError(&aCurrentModel, *aMatchesIter2) < aErrorDistSq)
98
aInliers.push_back(aMatchesIter2);
102
aOutliers.push_back(aMatchesIter2);
106
if (aInliers.size() > aMaxInliers)
108
//cout << "good found -----------------" << aRemainingIterations << endl;
109
//cout << aCurrentModel << endl;
110
for (int i=0; i<3;++i)
111
for(int j=0; j<3;++j)
112
_bestModel._H[i][j] = aCurrentModel._H[i][j];
114
_bestModel._v1x = aCurrentModel._v1x;
115
_bestModel._v2x = aCurrentModel._v2x;
116
_bestModel._v1y = aCurrentModel._v1y;
117
_bestModel._v2y = aCurrentModel._v2y;
120
//*ioBestModel = *aCurrentModel;
121
aMaxInliers = (unsigned int)aInliers.size();
122
aBestInliers = aInliers;
123
aBestOutliers = aOutliers;
124
//cout << "Inliers : " << aInliers.size() << " Outliers : " << aOutliers.size() << endl;
128
// if there are 0 outliers then we are done.
129
if (aOutliers.empty())
132
//cout << "Inliers : " << aInliers.size() << " Outliers : " << aOutliers.size() << endl;
133
//cout << "end iter" << endl;
136
ioMatches = aBestInliers;
137
ioRemovedMatches = aBestOutliers;
142
void Ransac::transform(double iX, double iY, double &oX, double &oY)
144
_bestModel.transformPoint(iX, iY, oX, oY);