contrib/gel/mrc/vpgl/algo/vpgl_backproject.cxx
Go to the documentation of this file.
00001 #include "vpgl_backproject.h"
00002 //:
00003 // \file
00004 #include <vpgl/algo/vpgl_invmap_cost_function.h>
00005 #include <vgl/vgl_point_2d.h>
00006 #include <vgl/vgl_point_3d.h>
00007 #include <vgl/vgl_plane_3d.h>
00008 #include <vnl/algo/vnl_amoeba.h>
00009 
00010 //: Backproject an image point onto a plane, start with initial_guess
00011 bool vpgl_backproject::bproj_plane(const vpgl_camera<double>* cam,
00012                                    vnl_double_2 const& image_point,
00013                                    vnl_double_4 const& plane,
00014                                    vnl_double_3 const& initial_guess,
00015                                    vnl_double_3& world_point)
00016 {
00017   vpgl_invmap_cost_function cf(image_point, plane, cam);
00018   vnl_double_2 x1(0.0, 0.0);
00019 
00020   cf.set_params(initial_guess, x1);
00021   vnl_amoeba amoeba(cf);
00022   amoeba.set_max_iterations(1000);
00023   vnl_vector<double> x(&x1[0], 2);
00024   amoeba.minimize(x); x1 = x;
00025   cf.point_3d(x1, world_point);
00026   double u=0, v=0, X=world_point[0], Y=world_point[1], Z=world_point[2];
00027   cam->project(X, Y, Z, u, v);
00028    vnl_double_2 final_proj;
00029    final_proj[0]=u; final_proj[1]=v;
00030   double err = (final_proj-image_point).magnitude();
00031   // was: double err = vcl_sqrt(cf.f(x));
00032   if (err>.05) // greater than a 20th of a pixel
00033     return false;
00034   return true;
00035 }
00036 
00037   // vgl interface
00038 
00039 //: Backproject an image point onto a plane, start with initial_guess
00040 bool vpgl_backproject::bproj_plane(const vpgl_camera<double>*  cam,
00041                                    vgl_point_2d<double> const& image_point,
00042                                    vgl_plane_3d<double> const& plane,
00043                                    vgl_point_3d<double> const& initial_guess,
00044                                    vgl_point_3d<double>& world_point)
00045 {
00046   //simply convert to vnl interface
00047   vnl_double_2 ipt;
00048   vnl_double_3 ig, wp;
00049   vnl_double_4 pl;
00050   ipt[0]=image_point.x(); ipt[1]=image_point.y();
00051   pl[0]=plane.a(); pl[1]=plane.b(); pl[2]=plane.c(); pl[3]=plane.d();
00052   ig[0]=initial_guess.x();  ig[1]=initial_guess.y();  ig[2]=initial_guess.z();
00053   bool success = vpgl_backproject::bproj_plane(cam, ipt, pl, ig, wp);
00054   world_point.set(wp[0], wp[1], wp[2]);
00055   return success;
00056 }
00057 
00058 
00059 //: Backproject an image point onto a world plane
00060 bool vpgl_backproject::bproj_plane(vpgl_rational_camera<double> const& rcam,
00061                                    vnl_double_2 const& image_point,
00062                                    vnl_double_4 const& plane,
00063                                    vnl_double_3 const& initial_guess,
00064                                    vnl_double_3& world_point)
00065 {
00066   const vpgl_camera<double>*  cam = static_cast<const vpgl_camera<double>* >(&rcam);
00067   return bproj_plane(cam, image_point, plane, initial_guess, world_point);
00068 }
00069 
00070 //: Backproject an image point onto a world plane
00071 bool vpgl_backproject::bproj_plane(vpgl_rational_camera<double> const& rcam,
00072                                    vgl_point_2d<double> const& image_point,
00073                                    vgl_plane_3d<double> const& plane,
00074                                    vgl_point_3d<double> const& initial_guess,
00075                                    vgl_point_3d<double>& world_point)
00076 {
00077   const vpgl_camera<double>* const cam = static_cast<const vpgl_camera<double>* >(&rcam);
00078   return bproj_plane(cam, image_point, plane, initial_guess, world_point);
00079 }
00080 //Only the direction of the vector is important so it can be 
00081 //normalized to a unit vector. Two rays can be constructed, one through
00082 //point and one through a point formed by adding the vector to the point
00083 bool 
00084 vpgl_backproject::bproj_point_vector(vpgl_proj_camera<double> const& cam,
00085                                vgl_point_2d<double> const& point,
00086                                vgl_vector_2d<double> const& vect,
00087                                vgl_plane_3d<double>& plane)
00088 {
00089   vgl_homg_point_2d<double> hp(point);
00090   //get a second point
00091   vgl_vector_2d<double> vu = vect/vect.length();
00092   vgl_point_2d<double> point_plus_vect = point + vu;
00093   vgl_homg_point_2d<double> hp1(point_plus_vect);
00094   vgl_homg_line_2d<double> hline(hp, hp1);
00095   vgl_homg_plane_3d<double> hpl = cam.backproject(hline);
00096   plane = vgl_plane_3d<double>(hpl);
00097   //might add checks for ideal plane later
00098   return true;
00099 }
00100