1 // This is core/vpgl/algo/vpgl_camera_convert.h
2 #ifndef vpgl_camera_convert_h_
3 #define vpgl_camera_convert_h_
4 //:
5 // \file
6 // \brief Several routines for converting camera types
7 // \author J.L. Mundy
8 // \date July 18, 2005
9 //
10 // Should template this class.
11 
12 #include <vector>
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include <vgl/vgl_fwd.h>
17 #include <vnl/vnl_fwd.h>
18 #include <vpgl/vpgl_calibration_matrix.h>
19 #include <vpgl/vpgl_perspective_camera.h>
20 #include <vpgl/vpgl_proj_camera.h>
21 #include <vpgl/vpgl_affine_camera.h>
22 #include <vpgl/vpgl_rational_camera.h>
23 #include <vpgl/vpgl_local_rational_camera.h>
24 #include <vpgl/vpgl_generic_camera.h>
25 #include <vgl/algo/vgl_h_matrix_3d.h>
26 
27 #include <vil/vil_config.h>
28 #if HAS_GEOTIFF
29 #include <vpgl/file_formats/vpgl_geo_camera.h>
30 #endif
31 
32 //: Basic least squares solution for a general projective camera given corresponding world and image points.
33 class vpgl_proj_camera_convert
34 {
35  public:
36   //:Find a projective camera that best approximates the rational camera at the world center (lon (deg), lat (deg), elev (meters) )
37   static  bool convert(vpgl_rational_camera<double> const& rat_cam,
38                        vgl_point_3d<double> const& world_center,
39                        vpgl_proj_camera<double>& camera);
40 
41   //:An auxiliary matrix that transforms (normalizes) world points prior to projection by a projective camera.  (lon, lat, elevation)->[-1, 1].
42   static vgl_h_matrix_3d<double>
43     norm_trans(vpgl_rational_camera<double> const& rat_cam);
44 
45  private:
46   //:default constructor (is private)
47   vpgl_proj_camera_convert() = delete;
48 };
49 
50 
51 //:Various methods for computing a perspective camera
52 class vpgl_perspective_camera_convert
53 {
54  public:
55 
56   //: Convert from a rational camera
57   // Put the resulting camera into camera, return true if successful.
58   // The approximation volume defines the region of space (lon (deg), lat (deg), elev (meters))
59   //  where the perspective approximation is valid. Norm trans is a pre-multiplication
60   // of the perspective camera to account for scaling the lon, lat and elevation
61   // to the range [-1, 1]
62   static bool convert( vpgl_rational_camera<double> const& rat_cam,
63                        vgl_box_3d<double> const& approximation_volume,
64                        vpgl_perspective_camera<double>& camera,
65                        vgl_h_matrix_3d<double>& norm_trans);
66 
67   //: Convert from rational camera using a local Euclidean coordinate system.
68   static bool convert_local( vpgl_rational_camera<double> const& rat_cam,
69                              vgl_box_3d<double> const& approximation_volume,
70                              vpgl_perspective_camera<double>& camera,
71                              vgl_h_matrix_3d<double>& norm_trans);
72 
73  private:
74   vpgl_perspective_camera_convert() = delete;
75 };
76 
77 //:Various methods for converting to a generic camera
78 class vpgl_generic_camera_convert
79 {
80  public:
81 
82   //: Convert a local rational camera to a generic camera
83   static bool convert( vpgl_local_rational_camera<double> const& rat_cam,
84                        int ni, int nj,
85                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
86 
87   //: Convert a local rational camera to a generic camera, using user-specified z bounds
88   //  Note that the z values are relative to the local coordinate system
89   static bool convert( vpgl_local_rational_camera<double> const& rat_cam,
90                        int ni, int nj,
91                        vpgl_generic_camera<double> & gen_cam,
92                        double local_z_min, double local_z_max, unsigned level = 0);
93   static bool convert_bruteforce( vpgl_local_rational_camera<double> const& rat_cam,
94                                  int gni, int gnj, vpgl_generic_camera<double> & gen_cam,
95                                  double local_z_min, double local_z_max, unsigned level);
96   //: Convert a proj_camera to a generic camera
97   static bool convert( vpgl_proj_camera<double> const& prj_cam,
98                        int ni, int nj,
99                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
100 
101   //: Convert a perspective_camera to a generic camera
102   static bool convert( vpgl_perspective_camera<double> const& per_cam,
103                        int ni, int nj,
104                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
105 #if 0
106   {
107     vpgl_perspective_camera<double> nc_cam(per_cam);
108     vpgl_proj_camera<double>* prj_cam_ptr =
109       dynamic_cast<vpgl_proj_camera<double>*>(&nc_cam);
110     if (!prj_cam_ptr) return false;
111     return convert(*prj_cam_ptr, ni, nj, gen_cam,level);
112   }
113 #endif
114 
115   static bool convert_with_margin( vpgl_perspective_camera<double> const& per_cam,
116                                    int ni, int nj,
117                                    vpgl_generic_camera<double> & gen_cam, int margin, unsigned level = 0);
118 
119   //: Convert an affine_camera to a generic camera
120   static bool convert( vpgl_affine_camera<double> const& aff_cam,
121                        int ni, int nj, vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
122 
123   //::convert an abstract camera to generic camera
124   static bool convert( vpgl_camera_double_sptr const& camera, int ni, int nj,
125                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
126 
127 #if HAS_GEOTIFF
128   //: Convert a geocam (transformtaion matrix read from a geotiff header + an lvcs) to a generic camera
129   static bool convert( vpgl_geo_camera& geocam, int ni, int nj, double height,
130                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
131 
132   //: Convert a geocam (transformtaion matrix read from a geotiff header + an lvcs) to a generic camera using the specified ray direction (not necessarily nadir rays)
133   //  basically creates a camera with parallel rays but the rays can be in any direction
134   static bool convert( vpgl_geo_camera& geocam, int ni, int nj, double height, vgl_vector_3d<double>& dir,
135                        vpgl_generic_camera<double> & gen_cam, unsigned level = 0);
136 #endif
137 
138   // === utility methods ===
139  private:
140   //: interpolate rays to fill next higher resolution pyramid layer
141   static bool
142     upsample_rays(std::vector<vgl_ray_3d<double> > const& ray_nbrs,
143                   vgl_ray_3d<double> const& ray,
144                   std::vector<vgl_ray_3d<double> >& interp_rays);
145   //: interpolate a span of rays base on a linear interpolation. n_grid is the step distance from r1. r0 and r1 are one unit apart.
146   static vgl_ray_3d<double> interp_pair(vgl_ray_3d<double> const& r0,
147                                         vgl_ray_3d<double> const& r1,
148                                         double n_grid);
149   static bool pyramid_est(vpgl_local_rational_camera<double> const& rat_cam,
150                                               int ni, int nj,int offseti, int offsetj,
151                                                double local_z_min, double local_z_max,
152                                               int n_levels,std::vector<int> nr, std::vector<int> nc,
153                                               std::vector<unsigned int> scl,std::vector<vbl_array_2d<vgl_ray_3d<double> > > & ray_pyr );
154 
155   vpgl_generic_camera_convert() = delete;
156 };
157 
158 //:methods for computing to an affine camera
159 class vpgl_affine_camera_convert
160 {
161  public:
162 
163   //: Convert from rational camera using a local Euclidean coordinate system.
164   static bool convert( vpgl_local_rational_camera<double> const& camera_in,
165                        vgl_box_3d<double> const& region_of_interest,
166                        vpgl_affine_camera<double>& camera_out,
167                        unsigned int num_points=10000);
168 
169  private:
170   vpgl_affine_camera_convert() = delete;
171 };
172 
173 #endif // vpgl_camera_convert_h_
174