Go to the documentation of this file.00001 #include "vpgl_ray_intersect.h"
00002
00003
00004 #include <vnl/algo/vnl_levenberg_marquardt.h>
00005 #include <vnl/vnl_numeric_traits.h>
00006 #include <vnl/vnl_vector.h>
00007 #include <vnl/vnl_double_3.h>
00008 #include <vcl_iostream.h>
00009 #include <vpgl/vpgl_camera.h>
00010
00011
00012 vpgl_ray_intersect_lsqr::
00013 vpgl_ray_intersect_lsqr(vcl_vector<vpgl_camera<double>* > const& cams,
00014 vcl_vector<vgl_point_2d<double> > const& image_pts,
00015 unsigned num_residuals) :
00016 vnl_least_squares_function(3, num_residuals,
00017 vnl_least_squares_function::no_gradient ),
00018 f_cameras_(cams),
00019 f_image_pts_(image_pts)
00020 {}
00021
00022
00023
00024
00025
00026
00027 void vpgl_ray_intersect_lsqr::f(vnl_vector<double> const& intersection_point,
00028 vnl_vector<double>& image_errors)
00029 {
00030
00031 unsigned dim = image_errors.size()/2;
00032
00033
00034 double huge = vnl_numeric_traits<double>::maxval;
00035 for (unsigned i=0; i<image_errors.size(); i++)
00036 image_errors.put(i, huge);
00037
00038
00039 double intersection_point_x = intersection_point[0];
00040 double intersection_point_y = intersection_point[1];
00041 double intersection_point_z = intersection_point[2];
00042 #ifdef RAY_INT_DEBUG
00043 vcl_cout << "Error Vector (" << intersection_point_x << ", "
00044 << intersection_point_y << ", " << intersection_point_z << ") = ";
00045 #endif
00046
00047 for (unsigned image_no = 0; image_no < dim; image_no++)
00048 {
00049
00050 vpgl_camera<double>* cam = f_cameras_[image_no];
00051 double image_u = f_image_pts_[image_no].x(),
00052 image_v = f_image_pts_[image_no].y();
00053
00054 double cur_image_u, cur_image_v;
00055 cam->project(intersection_point_x, intersection_point_y,
00056 intersection_point_z, cur_image_u, cur_image_v);
00057
00058 image_errors.put(2*image_no,
00059 (cur_image_u - image_u));
00060 image_errors.put(2*image_no+1,
00061 (cur_image_v - image_v));
00062 #ifdef RAY_INT_DEBUG
00063 vcl_cout << " x_err = " << cur_image_u << '-' << image_u << '='
00064 << image_errors[2*image_no]
00065 << " y_err = " << cur_image_v << '-' << image_v << '='
00066 << image_errors[2*image_no+1];
00067 #endif
00068
00069
00070 #ifdef RAY_INT_DEBUG
00071 vcl_cout << '\n';
00072 #endif
00073 }
00074 }
00075
00076
00077 vpgl_ray_intersect::vpgl_ray_intersect(unsigned dim): dim_(dim)
00078 {}
00079
00080
00081
00082
00083 bool vpgl_ray_intersect::
00084 intersect(vcl_vector<vpgl_camera<double>* > const& cams,
00085 vcl_vector<vgl_point_2d<double> > const& image_pts,
00086 vgl_point_3d<double> const& initial_intersection,
00087 vgl_point_3d<double>& intersection)
00088 {
00089
00090 if (dim_ < 2)
00091 {
00092 vcl_cerr << "The dimension is too small. There must be at least 2 images"
00093 << '\n';
00094 return false;
00095 }
00096
00097
00098 if (cams.size() != dim_)
00099 {
00100 vcl_cerr << "Please provide correct number of cameras" << '\n';
00101 return false;
00102 }
00103
00104
00105 if (image_pts.size() != dim_)
00106 {
00107 vcl_cerr << "Please provide correct number of image points" << '\n';
00108 return false;
00109 }
00110
00111
00112 f_cameras_ = cams;
00113 f_image_pts_ = image_pts;
00114
00115
00116 vpgl_ray_intersect_lsqr lqf(cams, image_pts, 2*dim_);
00117 vnl_levenberg_marquardt levmarq(lqf);
00118 #ifdef RAY_INT_DEBUG
00119 vcl_cout << "Created LevenbergMarquardt minimizer ... setting tolerances\n";
00120 levmarq.set_verbose(true);
00121 #endif
00122
00123
00124 levmarq.set_x_tolerance(1e-10);
00125
00126
00127 levmarq.set_epsilon_function(1.0);
00128
00129
00130
00131 levmarq.set_f_tolerance(1e-10);
00132
00133
00134 levmarq.set_max_function_evals(10000);
00135 vnl_double_3 intersection_pt;
00136 intersection_pt[0]=initial_intersection.x();
00137 intersection_pt[1]=initial_intersection.y();
00138 intersection_pt[2]=initial_intersection.z();
00139
00140 #ifdef RAY_INT_DEBUG
00141 vcl_cout << "Initialized the intersection point " << intersection_pt
00142 << " ... minimizing\n";
00143 #endif
00144
00145
00146 levmarq.minimize(intersection_pt);
00147
00148
00149 #ifdef RAY_INT_DEBUG
00150 vcl_cout << "Min error of " << levmarq.get_end_error() << " at "
00151 << '(' << intersection_pt[0] << ", " << intersection_pt[1]
00152 << ", " << intersection_pt[2] << ")\n"
00153 << "Iterations: " << levmarq.get_num_iterations() << " "
00154 << "Evaluations: " << levmarq.get_num_evaluations() << '\n';
00155 levmarq.diagnose_outcome();
00156 #endif
00157
00158 intersection.set(intersection_pt[0],
00159 intersection_pt[1],
00160 intersection_pt[2]);
00161
00162 return true;
00163 }