33 #include "bias_config.h"
34 #include "Geometry/EpipoleEstimation.hh"
35 #include "Base/Math/Random.hh"
36 #include "Base/Geometry/KMatrix.hh"
37 #include "Base/Geometry/RMatrixBase.hh"
38 #include "Geometry/FMatrix.hh"
39 #include "Geometry/PMatrix.hh"
40 #include "Base/Debug/TimeMeasure.hh"
45 #define EPIPOLE_FACTOR 15.0
57 vector<BIAS::HomgPoint2D> match1, match2;
59 void CreateMatches2(vector<HomgPoint2D>& match1, vector<HomgPoint2D>& match2,
60 unsigned int match_count,
unsigned int width,
61 unsigned int height,
double spatial_noise_sigma,
69 K[0][0]=K[1][1]=840.0;
70 K[0][2]=(width-1.0)/2.0;
71 K[1][2]=(height-1.0)/2.0;
73 R2.
SetXYZ(r_ang, 0.0, 0.0);
74 C1.
Set(0.0, 0.0, 0.0);
77 C2.
Set(0.3, 0.0, 0.3);
87 true_epipole = P2 * C1;
90 vector<vector<HomgPoint2D> > i_matches, n_matches;
91 vector<HomgPoint3D> p3d;
93 CreateMatches(pvec, match_count, width, height, spatial_noise_sigma,
94 i_matches, n_matches, p3d, 2.0, -30.0, 30.0, -30.0, 30.0,
97 match1.resize(match_count);
98 match2.resize(match_count);
99 for (
unsigned i=0; i<match_count; i++){
100 match1[i]=n_matches[i][0];
101 match2[i]=n_matches[i][1];
107 void CreateMatches(vector<BIAS::HomgPoint2D>& match1,
108 vector<BIAS::HomgPoint2D>& match2,
110 unsigned int width,
unsigned int height,
111 double maxdisparity,
double mindisparity,
112 double spatial_noise_sigma)
116 double dist, p1epipoledist;
122 for (
unsigned int i=0; i<match_count; i++){
128 p1epipoledist=sqrt((epipole[0]-p1[0])*(epipole[0]-p1[0])+
129 (epipole[1]-p1[1])*(epipole[1]-p1[1]));
131 while (dist>=p1epipoledist);
133 p2[0]=p1[0]+(epipole[0]-p1[0])*dist/p1epipoledist
135 p2[1]=p1[1]+(epipole[1]-p1[1])*dist/p1epipoledist
140 }
while (p2[0]<0.0 || p2[0]>(
double)(width-1) ||
141 p2[1]<0.0 || p2[1]>(
double)(height-1));
143 match1.push_back(p1);
144 match2.push_back(p2);
149 void AddErr(
double& mean_ep_dist,
double& mean_ang,
double& mean_el_dist)
151 mean_ep_dist += estimated_epipole.
Distance(true_epipole);
154 vector<HomgPoint2D>::iterator it1, it2;
156 double ma=0.0, md=0.0;
159 for (it1=match1.begin(), it2=match2.begin();
160 it1!=match1.end() && it2!=match2.end(); it1++, it2++, c++){
161 l1.
Set(true_epipole, *it2);
163 l2.
Set(estimated_epipole, *it2);
165 ma+=fabs(atan2(l1[1], l1[0])-atan2(l2[1], l2[0]));
166 md+=(*it1).ScalarProduct(E*(*it2));
168 mean_ang=ma/(double)c;
169 mean_el_dist=md/(double)c;
172 int main(
int argc,
char *argv[])
174 ofstream os(
"errcp3.txt");
175 ofstream os2(
"errls3.txt");
177 double spatial_noise_sigma=0.0;
178 double max_disparity=50.0;
179 double mindisparity=2.0;
180 unsigned int match_count=80;
181 unsigned int width=640, height=480;
183 double mean_ep_dist_ls, mean_ep_dist_cp, mean_ang_ls, mean_ang_cp;
184 double mean_el_dist_ls, mean_el_dist_cp;
185 EpipoleEstimation ee;
189 center.
Set(width/2, height/2);
191 if (argc>=2) match_count=atoi(argv[1]);
192 if (argc>=3) spatial_noise_sigma=atof(argv[2]);
195 K[0][0]=K[1][1]=840.0;
196 K[0][2]=double(width)/2.0;
197 K[1][2]=double(height)/2.0;
204 (EPIPOLE_FACTOR+1.0)*(
double)width);
206 EPIPOLE_FACTOR+1.0*(
double)height);
208 CreateMatches2(match1, match2, match_count, width, height,
209 spatial_noise_sigma, 0.0);
211 os <<
"# EpipoleEstimationCrossProduct\n"
212 <<
"# true epipole: "<<true_epipole[0]<<
" "<<true_epipole[1]
213 <<
" "<<true_epipole[2]<<endl
214 <<
"# "<<match_count<<
" matches"
215 <<
"\n# max disparity: "<<max_disparity
216 <<
"\n# min disparity: "<<mindisparity<<endl;
217 os2 <<
"# EpipoleEstimationCrossProduct\n"
218 <<
"# true epipole: "<<true_epipole[0]<<
" "<<true_epipole[1]
219 <<
" "<<true_epipole[2]<<endl
220 <<
"# "<<match_count<<
" matches"
221 <<
"\n# max disparity: "<<max_disparity
222 <<
"\n# min disparity: "<<mindisparity<<endl;
226 for (spatial_noise_sigma=0.0; spatial_noise_sigma<1.05;
227 spatial_noise_sigma+=0.1){
228 os <<endl<<endl<<
"# spatial noise: "<<spatial_noise_sigma
229 <<
"\n# spat-nois\trot-err(DEG)\trot-err(RAD)\tabs-dist-err"
230 <<
"\tabs-angle-err\tabs-el-dist-err\n";
231 os2 <<endl<<endl<<
"# spatial noise: "<<spatial_noise_sigma
232 <<
"\n# spat-nois\trot-err(DEG)\trot-err(RAD)\tabs-dist-err"
233 <<
"\tabs-angle-err\tabs-el-dist-err\n";
234 for (err_r=1e-3; err_r<=0.5; err_r*=2.0){
235 mean_ep_dist_ls = mean_ep_dist_cp = mean_ang_ls = mean_ang_cp =
236 mean_el_dist_ls = mean_el_dist_cp = 0.0;
237 for (
int c=0; c<count; c++){
238 CreateMatches2(match1, match2, match_count, width, height,
239 spatial_noise_sigma, err_r);
241 if (ee.CrossProductLeastSquaresSVD(match1,match2,
242 estimated_epipole)!=0){
243 BIASERR(
"error estimating epipole");
246 AddErr(mean_ep_dist_cp, mean_ang_cp, mean_el_dist_cp);
248 if (ee.MatchLengthWeightedLeastSquares(match1, match2,
249 estimated_epipole)!=0){
250 BIASERR(
"error estimating epipole");
253 AddErr(mean_ep_dist_ls, mean_ang_ls, mean_el_dist_ls);
258 mean_ep_dist_ls /= count;
259 mean_ep_dist_cp /= count;
260 mean_ang_ls /= count;
261 mean_ang_cp /= count;
262 mean_el_dist_ls /= count;
263 mean_el_dist_cp /= count;
265 os2 <<setw(6)<<spatial_noise_sigma<<
"\t"<< setw(6) << err_r/2/M_PI*360
266 << setw(12) << err_r <<
"\t" << setw(12)
267 <<mean_ep_dist_ls <<
"\t" << setw(12)
268 <<mean_ang_ls<<
"\t"<<mean_el_dist_ls<<endl;
270 os <<setw(6)<<spatial_noise_sigma<<
"\t"<< setw(6) << err_r/2/M_PI*360
271 << setw(12) <<err_r <<
"\t" << setw(12)
272 <<mean_ep_dist_cp <<
"\t" << setw(12)
273 <<mean_ang_cp<<
"\t"<<mean_el_dist_cp<<endl;
276 cout <<setw(12)<<spatial_noise_sigma<<setw(12)<<err_r<<
"\t"<<setw(12)
278 <<
"\t"<<setw(12)<<mean_ang_ls<<
"\t"<<mean_el_dist_ls<<endl;
279 cout <<setw(12)<<spatial_noise_sigma<<setw(12)<<err_r<<
"\t"<<setw(12)
281 <<
"\t"<<setw(12)<<mean_ang_cp<<
"\t"<<mean_el_dist_cp<<endl;
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
HOMGPOINT2D_TYPE Distance(const HomgPoint2D &point) const
void Set(const HOMGPOINT3D_TYPE &x, const HOMGPOINT3D_TYPE &y, const HOMGPOINT3D_TYPE &z)
set elementwise with given 3 euclidean scalar values.
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
void Set(const HomgPoint2D &p1, const HomgPoint2D &p2)
constructing a line through two points
a line l = (a b c)^T is a form of the implicit straight line equation 0 = a*x + b*y + c if homogenize...
void Homogenize()
aequivalent to homogenize for points the gradient triangle is normed to hypothenuse length of 1 ...
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Implements a 3D rotation matrix.
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
describes a projective 3D -> 2D mapping in homogenous coordinates
void SetAsCrossProductMatrix(const Vector3< T > &vec)
Sets matrix from vector as cross product matrix of this vector.
KMatrix Invert() const
returns analyticaly inverted matrix
void Set(const HOMGPOINT2D_TYPE &x, const HOMGPOINT2D_TYPE &y)
set elementwise with given 2 euclidean scalar values.
class for producing random numbers from different distributions
class TimeMeasure contains functions for timing real time and cpu time.
void Compose(const Matrix3x3< double > &K, const Matrix3x3< double > &R, const Vector3< double > &C)
composes this from K, R and C using P = [ K R' | -K R' C ] with R' = transpose(R) ...
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...