Go to the documentation of this file.00001
00002 #include "vpgl_triangulate_points.h"
00003
00004
00005
00006 #include <vcl_cmath.h>
00007 #include <vcl_cstdlib.h>
00008 #include <vcl_cassert.h>
00009
00010 #include <vgl/vgl_vector_3d.h>
00011
00012 #include <vnl/vnl_matrix_fixed.h>
00013 #include <vnl/vnl_matrix.h>
00014 #include <vnl/vnl_vector.h>
00015 #include <vnl/vnl_double_3.h>
00016 #include <vnl/vnl_double_3x3.h>
00017 #include <vnl/algo/vnl_svd.h>
00018
00019
00020 double vpgl_triangulate_points::triangulate(
00021 const vcl_vector<vgl_point_2d<double> > &points,
00022 const vcl_vector<vpgl_perspective_camera<double> > &cameras,
00023 vgl_point_3d<double> &point_3d)
00024 {
00025 const int num_vars = 3;
00026 const int num_eqs = 2 * points.size();
00027
00028
00029 vnl_matrix<double> A(num_eqs, num_vars, 0.0);
00030 vnl_vector<double> b(num_eqs, 0.0);
00031
00032 for (unsigned int i = 0; i < points.size(); ++i) {
00033 const vgl_vector_3d<double> &trans =
00034 cameras[i].get_translation();
00035
00036 const vnl_double_3x3 &rot =
00037 cameras[i].get_rotation().as_matrix();
00038
00039 const vgl_point_2d<double> pt =
00040 cameras[i].get_calibration().map_to_focal_plane(points[i]);
00041
00042
00043 A.put(2 * i, 0, rot.get(0, 0) - pt.x() * rot.get(2, 0) );
00044 A.put(2 * i, 1, rot.get(0, 1) - pt.x() * rot.get(2, 1) );
00045 A.put(2 * i, 2, rot.get(0, 2) - pt.x() * rot.get(2, 2) );
00046
00047
00048 A.put(2*i+1, 0, rot.get(1, 0) - pt.y() * rot.get(2, 0) );
00049 A.put(2*i+1, 1, rot.get(1, 1) - pt.y() * rot.get(2, 1) );
00050 A.put(2*i+1, 2, rot.get(1, 2) - pt.y() * rot.get(2, 2) );
00051
00052
00053 b[2*i + 0] = trans.z() * pt.x() - trans.x();
00054 b[2*i + 1] = trans.z() * pt.y() - trans.y();
00055 }
00056
00057
00058 vnl_svd<double> svd(A);
00059 vnl_double_3 x = svd.solve(b);
00060
00061 point_3d.set(x.begin());
00062
00063
00064 double error = 0.0;
00065 for (unsigned int i = 0; i < points.size(); ++i) {
00066
00067 vnl_double_3 pp = cameras[i].get_rotation().as_matrix() * x;
00068
00069 pp[0] += cameras[i].get_translation().x();
00070 pp[1] += cameras[i].get_translation().y();
00071 pp[2] += cameras[i].get_translation().z();
00072
00073 double dx = pp[0] / pp[2] - points[i].x();
00074 double dy = pp[1] / pp[2] - points[i].y();
00075 error += dx * dx + dy * dy;
00076 }
00077
00078 return vcl_sqrt(error / points.size());
00079 }