1 // This is core/vpgl/algo/vpgl_rational_adjust_multipt.h
2 #ifndef vpgl_rational_adjust_multipt_h_
3 #define vpgl_rational_adjust_multipt_h_
4 //:
5 // \file
6 // \brief Adjust image offsets to register a set of rational cameras using multiple correspondence points
7 // \author Ozge C. Ozcanli
8 // \date Nov 17, 2011
9 //
10 // \verbatim
11 //   Modifications
12 //    Yi Dong  Jun-2015  added new function to optimize the Lev-Marq refinement with given initial 3-d point, height range and search diameter
13 // \endverbatim
14 
15 #include <vector>
16 #ifdef _MSC_VER
17 #  include <vcl_msvc_warnings.h>
18 #endif
19 #include <vnl/vnl_vector.h>
20 #include <vnl/vnl_least_squares_function.h>
21 #include <vpgl/vpgl_rational_camera.h>
22 #include <vgl/vgl_vector_2d.h>
23 #include <vgl/vgl_point_2d.h>
24 #include <vgl/vgl_point_3d.h>
25 
26 
27 //:
28 // This algorithm finds a set of minimum translations that registers the input set of images using multiple correspondences
29 // e.g. multiple 3D points projecting to a set of 2D correspondences in each image
30 // After registration, the images have geographically corresponding rational
31 // cameras. That is, a visible 3-d point will project into its corresponding
32 // image location in all the images.
33 
34 class vpgl_cam_trans_search_lsqr : public vnl_least_squares_function
35 {
36  public:
37   //: Constructor
38   vpgl_cam_trans_search_lsqr(std::vector<vpgl_rational_camera<double> > const& cams,
39                              std::vector<float>  cam_weights,
40                              std::vector< std::vector<vgl_point_2d<double> > > const& image_pts,  // for each 3D corr, an array of 2D corrs for each camera
41                              std::vector< vgl_point_3d<double> >  initial_pts);
42   //: Destructor
43   ~vpgl_cam_trans_search_lsqr() override = default;
44 
45   //: The main function.
46   //  Given the parameter vector x, compute the vector of residuals fx.
47   //  fx has been sized appropriately before the call.
48   void f(vnl_vector<double> const& translation,   // size is 2*cams.size()
49                  vnl_vector<double>& projection_errors) override;  // size is cams.size()*image_pts.size() --> compute a residual for each 3D corr point in each image
50 
51   void get_finals(std::vector<vgl_point_3d<double> >& finals);
52 
53  protected:
54   vpgl_cam_trans_search_lsqr();//not valid
55   std::vector<vgl_point_3d<double> > initial_pts_;
56   std::vector<vpgl_rational_camera<double> > cameras_; //cameras
57   std::vector<float> cam_weights_; // should sum up to 1
58   std::vector<std::vector<vgl_point_2d<double> > > corrs_;
59   std::vector<vgl_point_3d<double> > finals_;
60 };
61 
62 class vpgl_rational_adjust_multiple_pts
63 {
64  public:
65   ~vpgl_rational_adjust_multiple_pts() = default;
66 
67   //: exhaustively searches the parameter space to find the best parameter setting
68   static bool adjust(std::vector<vpgl_rational_camera<double> > const& cams,
69                      std::vector<float> const& cam_weights,
70                      std::vector<std::vector< vgl_point_2d<double> > > const& corrs,  // a vector of correspondences for each cam
71                      double radius, int n,       // divide radius into n intervals to generate camera translation space
72                      std::vector<vgl_vector_2d<double> >& cam_translations,          // output translations for each cam
73                      std::vector<vgl_point_3d<double> >& intersections);             // output 3d locations for each correspondence
74 
75   //: run Lev-Marq optimization to search the param space to find the best parameter setting
76   static bool adjust_lev_marq(std::vector<vpgl_rational_camera<double> > const& cams,
77                               std::vector<float> const& cam_weights,
78                               std::vector<std::vector< vgl_point_2d<double> > > const& corrs, // a vector of correspondences for each cam
79                               std::vector<vgl_vector_2d<double> >& cam_translations, // output translations for each cam
80                               std::vector<vgl_point_3d<double> >& intersections);    // output 3d locations for each correspondence
81 
82   //: run Lev-Marq optimization to search the param space to find the best parameter setting, with a initial guess and relative diameter given for back-projection
83   static bool adjust_lev_marq(std::vector<vpgl_rational_camera<double> > const& cams,          // cameras that will be corrected
84                               std::vector<float> const& cam_weights,                           // camera weight parameters
85                               std::vector<std::vector<vgl_point_2d<double> > > const& corrs,    // a vector of correspondences for each cam
86                               vgl_point_3d<double> const& initial_pt,                         // initial 3-d point for back-projection
87                               double const& zmin,                                             // minimum allowed height of the 3-d intersection point
88                               double const& zmax,                                             // maximum allowed height of the 3-d intersection point
89                               std::vector<vgl_vector_2d<double> >& cam_translations,           // output translations for each camera
90                               std::vector<vgl_point_3d<double> >& intersections,               // output 3-d locations for each correspondence
91                               double const relative_diameter = 1.0);                          // relative diameter used in back-projection
92 
93  protected:
94   vpgl_rational_adjust_multiple_pts();
95 };
96 
97 
98 #endif // vpgl_rational_adjust_multipt_h_
99